Keras前回(2016/11/9)はMNISTの数字認識を多層パーセプトロンで解いたが、今回は畳み込みニューラルネットを使って解いてみた。このタスクもKerasの例題に含まれている。ソースコードを見れば大体何をやっているかつかめそうだけどポイントを少しまとめておく。Learning」の7章が非常にわかりやすいのでおすすめ。畳み込みニューラルネットでは、入力する画像の形状を保つために画像集合を4次元テンソル(4次元配列)、すなわち画像のサンプル数、画像のチャネル数(白黒画像なら1、RGBのカラー画像なら3など)、画像の縦幅、画像の横幅で入力するのが一般的。久々にKerasを動かしたら動かなくなっていてはまった。image_dim_orderingは、~/.keras/keras.jsonでth(Theano)またはtf(TensorFlow)のどちらかを指定できる。実際は、バックエンドとは無関係に指定でき、バックエンドにTensorFlowを使ってthを指定してもよいし、バックエンドにTheanoを使ってtfを指定してもよい。デフォルトではtfのようだ。チャネル数)の並び順になる。image_dim_orderingがtfの場合、X_train[sample][row][col][channel]で画像の画素値にアクセスできる。両方に対応する場合は、下のようなコードを書く必要がある。keras.jsonの設定はkeras.backendモジュールのimage_dim_ordering()で取得できる。1)MNISTの入力数は白黒画像なのでチャネル数は1である。畳み込み層が2つで、プーリング層が1つ、そのあとに多層パーセプトロンが続くシンプルな構成の畳み込みニューラルネットである。model畳み込みニューラルネットでは、これまでの全結合層(Dense)以外に畳み込み層(Convolution2D)とプーリング層(MaxPooling2D)が出てくる。畳み込み層やプーリング層も「層」なのでmodelにadd()で追加できる。最後に多層パーセプトロンに入力するときはデータをフラット化する必要がある。4次元配列を1次元配列に変換するにはFlatten()という層を追加するだけでOK。ユニット数などは自動的に計算してくれる。モデルを図示してみると下のようになる。image_dim_orderingの設定を見るようにしてほしいところ。Convolution2Dのborder_modeをvalidにすると出力画像は入力画像より小さくなる(2015/6/26)。sameにすると自動的にパディングして出力画像が入力画像と同じサイズになるよう調整される。出力画像のサイズは計算式があるが、Kerasでは自動的に計算してくれている。畳み込みニューラルネットのパラメータ数はフィルタのパラメータ数になる。32を足すのは各フィルタにあるスカラーのバイアス項。残りは前回の多層パーセプトロンとまったく同じなので省略。実行すると7エポックほどで収束し、精度は99%近く出る。最後に学習したフィルタを可視化してみた。1つ目の畳み込み層の重みのみ。フィルタは32なので手抜きで固定している。plt.show()Wの次元もimage_dim_orderingによって変わるようだ。thだと(フィルタ数、チャネル数、行数、列数)となるのだが、tfだと(行数、列数、チャネル数、フィルタ数)と逆になる。これは内部のアルゴリズムの実装による違いなのだろうか?混乱するなあ。個人的にはバックエンドがTensorFlowでもthに統一した方が扱いやすいと思ったが、デフォルトはtfなんだよなあ。学習前と学習後の重みを比較すると学習前ではモザイクがランダムなのに対し、学習後の方が白と黒が組織化されて何らかの特徴をとらえていることがわかる。実際は、まったく重みが変わらないフィルタもあるようだが・・・EarlyStoppingを使うと数エポックで学習が終了してしまい、更新されないフィルタが多くなっていた。図は50エポックくらい学習させた重み。次回は、定番のCIFAR-10のデータセットで畳み込みニューラルネットを試してみたい。(2017/1/8)のつづき。»プロフィールid:aidiary人工知能とその関連分野に興味があります。)はてなブログをはじめよう!aidiaryさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。