機械学習

初心者のための畳み込みニューラルネットワーク(MNISTデータセット + Kerasを使ってCNNを構築)

  • このエントリーをはてなブックマークに追加

深層学習入門と書かれた本を購入したはいいけど…見たこともない形のグラフや、なんかやたら威嚇をしてるように見える数式が…。そもそもシグモイドって一体どこの国ですか。と感じたことはありませんか?

ご安心ください!本チュートリアルでは、機械学習を全く触ったことの無い初心者の方を対象として、「畳み込みネットワーク(CNN)」の超基本的な仕組みを、PythonとJupyter Notebookを使って一緒に紐解いていきましょう。畳み込みネットワークを理解するため、本チュートリアルではMNIST(エムニスト)という手書き数字のデータセットを使っていきます。

コンピューティングの時間を合わせて、30分〜2時間程度で完了できるチュートリアルとなっています。是非、機械学習の最初の一歩として挑戦をしてみて下さい!

畳み込みニューラルネットワークを学ぶ前に…

初めて機械学習に挑戦するのであれば、CNNの前に初歩的な手法から学ぶのがオススメです。環境構築が不要、オンラインで実行が可能な機械学習入門チュートリアルを公開中!機械学習の世界へ飛び込んでみませんか?

コンピュータービジョンとは?

Teslaやトヨタによって開発された自動運転技術や、スマートフォン上の顔認識ソフトウェア、画像認識アプリケーションに至るまで、様々な会社や組織においてコンピュータービジョンは活躍しています。企業の競合優位性や収益に対して、機械学習を活用したコンピュータービジョンが大きな影響を与えていることに疑いの余地はありません。

ソース:Tesla

米テックメディアのtechopediaによれば、コンピュータービジョンとは「人間が行うのと同じ方法でコンピューターが画像を見たり、識別したり、処理することを可能にするコンピューターサイエンスの分野(注:意訳)」と定義をしています。

下の図の通り、コンピューターと人間では画像を見るのに大きな違いがあります。単純に言えば、左の写真のように人間の目には「犬」と認識できるこの写真ですが、コンピューターにとっては28行28列のピクセルを表した行列としか認識ができません。

コンピューターは画像をピクセルの値で認識をしますが、このピクセル値を、畳み込みニューラルネットワークのような深層学習のモデルでパターン認識と特徴量抽出をすることで、人間のように画像を認識することが可能になる訳です。

ソース:https://adeshpande3.github.io/assets/Corgi3.png

コンピュータービジョンを活用した一つの事例として、画像分類問題があります。人間にとっては、一目で犬か猫か解りますが、コンピューターにとってはピセクルの値として認識されますので、分類をするという単純なことでさえ難しいことでした。

このような画像の分類問題ですが、CNN(畳み込みニューラルネットワーク)で画像が犬か猫かの確率を出力するモデルを構築することにより、比較的容易に分類をすることが可能です。

画像の分類で面白い一つの事例として、「Not Hot Dog 」(ホットドッグを見分けるアプリ)というアンドロイドのアプリがあります。このアプリはアメリカで大人気のテック系スタートアップドラマ「Sillicon Valley」の中で出てくるジョークのアプリですが、実際にGoogle Playでダウロードをすることも可能です。

ドラマ内ではジョークとして紹介されたこのアプリですが、機械学習で行える画像分類アプリーケーションの実用性を示す良い例だと思います。

またコンピュータービジョンの精度を競争するコンペなども盛んに行われています。世界中のデータサイエンティストが集まるコンペサイトのKaggleでも頻繁に開催されていますし、日本ではコンビニレシートを読み取るコンピュータービジョンのコンペも開催されています。(こちら

ソース:https://i.deepanalytics.jp/i/wh0t4i5072

上記のようなレシートの読み込みなど非常に良い事例だと思いますが、コンピュータービジョンを活用することで、様々な分野や業務の改善/効率化を図ることが可能なのです。本記事では、この実用性の高いコンピュータービジョンを実際に自ら構築してみましょう!

MNISTデータセットとは?

実際のコードを書く前に、今回使うデータセット「MNIST(エムニスト)」について簡単に説明させて頂きます。MNISTとは、0から9までの70,000個の手書き数字の画像から構成されており、画像分類問題において非常に人気の高いデータセットです。(参考:機械学習で使えるデータセットまとめ

MNISTデータセットの目的は非常に単純で、この手書きの数字には正解ラベルがついており、コンピュータービジョンを使って、画像データからこの正解ラベルを導き出すことです。下の画像を見て頂くと、より分かりやすいかと思います。人間が見れば手書きの画像から数字がすぐに理解できますが、その認識をコンピューターを訓練して行います。

MNISTですが、機械学習の「Hello World」と呼ばれるくらい入門で使われるデータセットであり、最新のアルゴリズムや技術などを評価するためのベンチマークとしても利用されています。

本チュートリアルで行う画像分類ですが、これは「教師あり学習」です。教師あり学習では、学習データに正しいクラスまたはラベルが与えられています。

さらにデータセットは「訓練データ」と「テストデータ」の2つに分割して使うことが多いです。「訓練データ」とは、アルゴリズムを訓練(学習させる)ために使われるデータのことで、対してテストデータとは訓練されたモデルの検証に使用されます。

機械学習では、全てのデータセットを100%とした時に、訓練データを80%、テストデータを20%で分割して利用することが一般的です。(時に7対3など割合は変動します)

上の図を見て分かる通り、それぞれの手書き数字には、正解ラベルが与えらえています。先ほどから「訓練」と言っていますが、これは各画像の特徴量(画像のピクセル情報)を一般化して、どの特徴量がどの正解ラベルなのかをコンピューターが学びます。

その学んだ特徴量に基づいて、まだ見たことのない新しい画像(数字)の特徴量から、どの正解ラベル(どの数字)かを予測することが可能な訳です。

今回行うMNISTの手書き数字分類ですが、これは先ほども話した通り「教師あり学習」ですが、「教師なし学習」についても簡単に言及しておきます。

教師なし学習」では、正解ラベルがデータセットには与えられていません。下の図を見て頂くと分かりやすいですが、教師あり学習(Supervised Learning)はデータに「◯」と「×」と正解ラベルが与えられていますが、教師なし学習(Unsupervised Learning)では、どのデータが「◯」か「×」かは分かりませんが、データを学習することによりクラスタリング、つまり類似性でグルーピングなどをすることが可能です。

画像をピクセルの行列として表示

一般的にデータと聞くと、温度や身長、さらには売り上げなど、数値や文字を思い浮かべますよね。では画像はどのようなフォーマットで扱われるのでしょうか。初めて画像をデータとして扱う方も多いかと思いますので、簡単に画像のデータフォーマットを見ていきましょう。

画像をデータとして扱う場合、通常は「高さ x 幅 x チャンネル」の行列形式で表されます。画像には1チャンネルまたは3チャンネルがあり、3チャンネルとは「赤」「緑」「青」の各色情報を持ち合わせています。いわゆるRGBカラーです。対して、今回扱うMNISTもそうですが、1チャンネルとはグレースケールの画像を表しています。

ピクセルの値は0-255のレンジとなっています。下記の事例を見ると非常に分かりやすいと思いますが、各ピクセルごとに0-255までの値を持っており、その値に応じて白〜黒までの色を表現しているのが分かります。

ソース:こちら

対して3チャンネルの画像の場合は、このピクセルの層が赤青緑の3層存在しています。下の図は32 x 32ピクセルのカラー画像の構造を示したものですが、ご覧の通り32×32のピクセル情報の層が3つに重なり合って一つの画像を表現しているのが分かります。

ニューラルネットと畳み込みニューラルネットワーク

ここ近年、ニュースなどでも頻繁に耳にしますが、そもそもニューラルネットワークとはどのような物なのでしょうか?また本チュートリアルで扱うCNN(Convolutional Neural Network – 畳み込みニューラルネットワーク)についても簡単な概要を見ていきましょう。

ニューラルネットワークとは、一番単純な説明として、「人間の脳の構造を模したコンピューターシステム」です。一言でニューラルネットーワークと言っても、処理をする目的などに応じて、様々な種類が存在します。

下記の図は、オランダの人工知能関連企業の一つ「Asimov institute」の深層学習研究者である、Fjodor van Veen氏が作成したインフォグラフィックです。ご覧の通り、様々な種類のニューラルネトワークが描かれています。

 

このように、ニューラルネットワークの種類は多岐多様に渡り、CNN(畳み込みニューラルネットワーク)もその一つに属するわけです。

では、CNNはどのような目的に適したニューラルネットワークなのでしょうか?

要約をするとCNNは画像認識及び分類において極めて良好に機能するニューラルネットワークです。より詳しい説明は、非常に複雑な手順と層で成り立っているため、本記事では最低限の説明で留めさせていただきます。もし、より詳しく知りたい方は、こちらの論文(英語)がオススメです。

Keras(ケラス)とは?

以前に公開した仮想通貨+機械学習の記事でも使いましたが、本記事でもKeras(ケラスと読みます)を利用しています。KerasはPythonで描かれたディープラーニングラリブラリで、TensorFlow(テンソルフロー)やTheano(テアノ)の上で実行可能な高水準のニューラルネットワークAPIです。

Kerasを使ってみると解りますが、非常に簡単かつ高速にニューラルネットワークを構築することが可能で、GoogleやMicrosoftなどの大手でも利用されているライブラリです。

また機械学習系のライブラリでは非常に稀なことですが、日本語で公式ドキュメントが用意されているのも嬉しところですね。より詳しいKerasの使い方は公式ドキュメント(日本語)をご参照ください。

本チュートリアルでは、このKerasを利用してCNN(畳み込みニューラルネットワーク)のモデルを構築してMNIST(手書き数字)を分類していきます!では、次はいよいよPythonを実際に使って機械学習のモデルを構築して見ましょう!

Pythonでコーディングしてみよう

では実際にコーディングに取り掛かりましょう。下記に本チュートリアルのステップをまとめました。

  1. Keras / Anacondaで環境構築
  2. IPythonの立ち上げ&Keras設定
  3. 必要なライブラリのインポート
  4. MNISTデータセットのインポート
  5. 特徴量(x)とターゲット(y)ヘスプリット
  6. データの確認
  7. 特徴量を28行28列へ変換
  8. Matplotlibを使ってプロッティング
  9. 仮説の確認
  10. ニューラルネットワークのためのデータ前処理
  11. モデル構築
  12. ニューラルネットワークの層の構築
  13. ハイパーパラメーターなどの設定
  14. モデル訓練開始!
  15. モデルの評価確認
  16. 予測と実際の値の確認

STEP1 Keras / Anacondaで環境構築

すでにKerasや必要なライブラリの環境構築が出来ている方はこちらのステップは飛ばしてください。初めて機械学習の環境を構築される方は、お使いのパソコンに応じてPythonやその他のライブラリのインストールが必要です。

これから初めて機械学習が行える環境の構築が必要な方はAnaconda(アナコンダ)がオススメです。Anacondaはパッケージの管理ソフトウェアで、100以上の異なるパッケージが含まれているため、とても簡単かつ素早く環境の構築が可能です。(特にWindowsをお使いの方はAnacondaを使うとエラー対処が少なくて楽です)

下記のURLからWIndows、Mac共にダウロードが可能です。Pythonのバージョンですが、本チュートリアルでは3.6で構築しています。バージョンが2をお使いの方は、Python 3.xの構築をお願いします。

https://www.anaconda.com/download/

Anacondaのイントールが完了した方、またはすでにPythonの環境がある方は、続けて下記のライブラリのインストールをお願いします。Anacondaの方は「conda install 〇〇」でインストールが可能です。(個別にインストールされる方はこちらが参考になるかと思います。Anacondaをお使いの方はこちらも参考にして見てください)

  • Numpy
  • Matplotlib
  • Pandas
  • Scikit-learn
  • ipython

次にKeras及びバックエンドで使用するTheanoのインストールが必要です。詳しくは下記のKeras公式のインストールページをご覧ください。

https://keras.io/ja/#_2

各ライブラリのインストールで手が止まってしまった方は、「ライブラリ名 + インストール + OS名」などで検索して見てください。詳細の説明を多数のサイトで扱っています。またエラーが出てしまった場合は、そのエラー構文で検索すると、解決策が見つかるかもしれません。

STEP2 IPython立ち上げ&Keras設定

無事に環境構築が出来ましたでしょうか?次は早速、IPythonの立ち上げを行いましょう。Macはターミナル、Windowsはコマンドプロンプトを立ち上げてIPythonを起動しましょう

*下記コマンドを適宜のディレクトリで入力してIPythonを立ち上げます

IPythonは立ち上がりましたでしょうか?次はKerasを動かすバックエンドの設定をしていきましょう。先述しましたが、KerasはTensorFlowやTheanoなど複数のバックエンドを採用することが可能です。本記事ではTheano(テアノ)バックエンドを利用しますので、そちらの設定をしましょう。(デフォルトはTensorFlowだったと記憶しています)

Ipythonの最初のセルに下記のコードを入力して、SHIFT +ENTERで実行してください。

上記のコードを実行すると「Using Theano backend.」と出力されれば無事に設定が完了です。

STEP3 必要なライブラリのインポート

次はこのプロジェクトで使うライブラリをインポートをしましょう。本チュートリアルではKeras、Sklearn(Scikit-learn)、Pandas、Matpolotlibを使います。これらのライブラリですが、機械学習では必須と言っても過言ではありません。より詳しい使い方は、codexaで公開している入門コースをご参考ください。

> Numpyの使い方基礎コース
> Pandasの使い方基礎コース
> Matplotlibのの使い方基礎コース

STEP4 MNISTデータセットのインポート

必要なライブラリのインポートも出来ましたので、次はMNISTデータセットを読み込みましょう。MNISTですが、機械学習では非常に頻繁に使われるデータセットで、なんとScikit-learnから直接、データセットを読み込みすることが可能です。下記のコードでMNISTデータをScikit-learn経由でダウロード出来ます。

STEP5 特徴量(x)とターゲット(y)ヘ分割

データセットのダウロードが完了したら、次は説明変数(X)と目的変数(y)に切り分けてあげましょう。説明変数と目的変数ですが機械学習ではよく出てくる単語の一つです。

例えば、「身長」「体重」のデータで、その個人の「性別」を機械学習で予測する場合を考えましょう。この場合、「身長」「体重」のデータを説明変数と呼び、予測するアウトプットの「性別」を目的変数と呼びます。説明変数ですが、その他にも「特徴量」や「独立変数」などと呼ばれたりますします。

下記のコードでMNISTのデータセットを「data(説明変数)」と「target(目的変数)」に切り分けてあげましょう。

STEP6 データの確認

次に、このMNISTデータセットを確認してみましょう。ひとまずは一番基本的な部分を確認して行きます。

(70000, 784)
(70000,)

MNISTは70000個の手書き数字が格納されています。Xのサイズを確認してみると、70000行784列のNumpy配列であることが確認出来ます。前述しましたがMNISTの画像は28×28の画像ですので、各行(70000個)に28×28=784のピクセル情報が格納されている訳です。

対してyは正解ラベルになっているため、70000行に正解ラベル(0から9までの数字)が格納されている訳です。

STEP7 特徴量を28行28列へ変換

こちらのMNISTのデータですが、28×28の画像のピクセルデータが全て平らになっていますので、これを28×28に戻して表示をしてみましょう。特別に意味はありませんが、今回は適当に選んだ53238番目の画像のデータを確認してみます。

また、Pandasですが、デフォルトだと大きいサイズのデータを途中で区切ってしまうので、その設定を変更する必要があります。

こちらですが、上記のコードを実行するとnumber_matrixのデータフレームの表示結果となります。一見、ただの数字の羅列に見えますが・・よーく目をこらすと数字に見えてきませんか?これはなんの数字を表しているか分かりますか?

・・・

ただのピクセル値ですが、よく注視してみると「8」を形取っているのがわかります。さらに各ピクセル情報をみてみるとわかりますが、「8」の真ん中の方のピクセルの番号は高く(最大は255まで)、外側と内側の縁部分は番号が低いのがわかります。このように、コンピューターは画像のピクセル情報を読み込んで画像を表示させています。

STEP8 Matplotlibを使ってプロッティング

前回のステップはデータのピクセルの値をそのままPandasのデータフレームとして表示させましたが、今回はMatplotlibを使って、ピクセル情報から実際の画像を表示させて見ましょう。Matplotlibを初めて使う方は、是非こちらの無料入門コースをご参照ください

手書き数字の「8」というのが明確にわかりますね。では次のステップでは本当にこのデータが「8」を示しているのか、正解ラベル(つまりy)の値を確認して確かめましょう。

STEP9 仮説の確認

上記で表示させたデータですが、Xの53238番目のデータを適当に抽出して表示させました。先に説明した通り、MNISTには「正解ラベル」が付与されておりますので、この53238番目のデータの正解ラベルも確認してみましょう。

8.0

ご覧の通り、「8」と出力されていますね。ここまでは特に機械学習という訳ではありませんが、基本的なライブラリを使いながらデータセットの確認と、その構造について触って見ました。

次のステップからはいよいよ、ニューラルネットワークの下準備を進めていきましょう。

STEP10 ニューラルネットワークのためのデータ前処理

次のステップでは、Kerasへインプットさせるデータの事前処理を行いましょう。機械学習ではこのデータの事前処理が非常に重要となり、また奥深い分野でもあります。今回は特に難しいことは行わず、必要最低限の前処理を行いましょう。

まずは訓練データとテストデータへ切り分けを行いましょう。下の図をみると、よりイメージがつきやすいかとおもいまうs。訓練データはCNNへ訓練をさせる(学ばさせる)データです。訓練データを使って構築したモデルに、今度は訓練で全く使ったことのない(モデルに学習をさせていない)テストデータを使って構築したモデルの良し悪しを判断します。

MNISTですが70000個の画像データがありますので、訓練データとして60000個、テストデータとして10000個に切り分けてあげましょう。

(60000, 784)
(10000, 784)

次に各画像のデータを28x28x1へリサイズをしてあげましょう。現在は一つの行に784(28×28)のピクセル情報が入っていますので、こちらを28行28列の行列へ変換します。

次にKerasで扱えるようにデータタイプをfloat32へ変換をしてあげましょう。

最後に各ピクセルデータを全て「255」で割ります。この割り算をすることにより、xの値が全て0から1の間になるようになります。この処理ですが、機械学習では「Normalization(正規化)」と呼ばれる作業で、アゴリズムの計算処理をスムーズに行うための作業となります。(詳細は今回は触れません)

データの事前処理の最後として、「y」の値をバイナリクラスに変換をしてあげましょう。ちょっと言葉では解りづらいかもしれませんが、この処理はyの値を10個の数値の配列に変換します。さらに、yの値に応じて、必要な箇所の数値を「1」、それ以外は全て「0」というデータに変換をします。下の例を見てみると、より解りやすいかもしれません。

y = 5 = [0,0,0,0,1,0,0,0,0,0] y = 0 = [1,0,0,0,0,0,0,0,0,0]

array([ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.])

ご覧の通り、yの値が0-9までの値を持っているものが、1と0のみで表現される配列へ変換されています。

STEP11 モデル構築

さて、いよいよニューラルネットワークのモデルの構築を書き始めましょう。下記のコードで、KerasでSquential Model(系列モデル)を構築が可能です。本記事では詳細は踏み込みませんが、もし興味がある方はKerasの公式ドキュメント(日本語)を読んでみると良いかと思います。

STEP12 ニューラルネットワークの層の構築

ニューラルネットワークでは「レイヤー」と呼ばれる「層」がとても重要な役割を果たします。次のコードは、先ほど作成したKerasのモデルへ「レイヤー(層)」を追加していく作業です。

またコードを見ると「Dropout」と指定されていますが、こちらは訓練データのモデルを構築する際に「過学習(オーバーフィッティング)」を避けるために役に立ちます。「Softmax」と記載がありますが、これは活性化関数で出力が合計で1となる確率分布となります。

下記に今回構築するCNN(畳み込みニューラルネットワーク)の概要を書いておきますが、分からない部分があっても大丈夫です!まずは、コードを動かして見て、分からない部分があれば、徐々に補講学習をして慣れていくほうが学習が進むかと思います。下記に、補講学習としてより詳しく調べた方が良い内容を載せておきます。

補講学習項目
  • 活性化関数(activation function)の役割
  • Softmax、ReLuの違い
  • ドロップアウトの役割

STEP13 学習プロセスの設定

ニューラルネットワークでは、学習過程(プロセス)へ影響がある3つの設定項目があります。これも今の段階で深掘りしてしまうと、先に進められなくなりますので、ひとまずは訓練データをどのように学習させるかの設定と覚えておきましょう。

補講学習項目
  • 損失関数(Loss Function)とは?
  • 最適化(optimizer)とは?
  • 確率的最急降下法(sgt)とは?
  • 評価関数(metrics)の役割

STEP14 モデル訓練開始!

さて、いよいよ畳み込みニューラルネットワークの訓練開始です!今回はepoch(エポック)を10と指定しています。epochは訓練データへ何回繰り返して学習させるかの回数を指定できます。下記のコードを実行すると、いよいよ訓練データをニューラルネットワークが学習し始めます。

私の環境で15分程度かかりました。各エポック(反復計算)で、どのくらい時間を要したのか、またそのさいのAccuracy(精度)も表示してくれます。

各エポックで「acc(精度)」が上がっているのが確認できます!最初の計算では0.8561でしたが、最後の10回目では0.9739と改善しています。

STEP15 モデルの評価確認

前回のステップで訓練データ(X_train)へモデルをフィットさせました。次はテストデータ(X_test)を使って、この構築したモデルがどれくらい手書き文字を認識できるのかの評価をして見ましょう。繰り返しになりますが、このモデルはテストデータ(X_test)を見たことがありませんので、全く新しいデータでの予測と言えるわけです。

下のコードでテストデータを使って、今回構築したモデルの精度を評価してみましょう。

10000/10000 [==============================] – 6s 607us/step
[0.072555564129352573, 0.97750000000000004]

おおおお!今回Kerasで構築したモデルですが、MSNIT(手書き文字)の分類(手書きで書かれている数字を当てる)の精度が97%と出ました!これはなかなかの精度ですね!

STEP16 予測と実際の値の確認

STEP15でモデルの評価をテストデータを使って行いましたが、実際にX_test(テストデータ)をモデルに入力して、予測(predictions)を出力させて比較してみましょう。

すでに前回のステップで「精度」は確認をしていますが、このように、実際値と予測値を比較することで、構築したモデルがしっかりと予測できているか(手書き数字を判別できているか)がわかりやすいかと思います。

「results」として上記のコードでは最初の10行を表示させていますが、この値を調整してみると、予測値と実際値が異なるデータも見つけることが可能です。補講学習として、このモデルに自分で書いた手書き文字を読み込ませて、予測値を確認してみるとのも良い練習になるかと思います。

おめでとうございます!

実際にPythonとKeras+他のライブラリを活用して「畳み込みニューラルネットワーク(CNN)」を構築してみました!いかがでしたでしょうか?

本記事内では畳み込みネットーワークの構築に焦点を当てて、特にCNNの詳細の説明や、Kerasの詳しい使い方などは最小限に抑えています。記事内でも記載をしていますが「補講学習」として、より気になった部分は個別に掘り下げて学習してみてください。

またcodexaでは、機械学習入門チュートリアルを多数公開しています。次のステップとして、下記のチュートリアルも挑んでみてはいかがでしょうか?

以上となります!ご質問やご不明な点は、是非コメントで残していただけると助かります!最後までお読みいただいて、ありがとうございました。

  • このエントリーをはてなブックマークに追加

年収に大幅に差がつく前に

AIエンジニアへスキルアップをしませんか?コデクサでは、機械学習の初心者を対象に0から学べるコースを配信しています。

機械学習に必要な線形代数や統計基礎、さらに初歩的なアルゴリズムなどの無料コースを豊富に取り揃えています!

機械学習エンジニアへキャリアアップをしましょう!

0から始める機械学習

コメントを残す

*

CAPTCHA