深層学習を勉強する機運が高まったので「PythonとKerasによるディープラーニング」を読んでいる。第5章ではまずMNIST数字分類にCNNを使うのだが、サンプルコードを写経したプログラムがうまくいかないので困っている。誰か教えてください。
こちらがそのノートブック。MNISTデータ読み込みなどが終わった後、前半ではサンプルコード通りのネットワークを持つ分類器を使っている。
Layer (type) Output Shape Param # ================================================================= conv2d_1 (Conv2D) (None, 26, 26, 32) 320 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 13, 13, 32) 0 _________________________________________________________________ conv2d_2 (Conv2D) (None, 11, 11, 64) 18496 _________________________________________________________________ max_pooling2d_2 (MaxPooling2 (None, 5, 5, 64) 0 _________________________________________________________________ conv2d_3 (Conv2D) (None, 3, 3, 64) 36928 _________________________________________________________________ flatten_1 (Flatten) (None, 576) 0 _________________________________________________________________ dense_1 (Dense) (None, 64) 36928 _________________________________________________________________ dense_2 (Dense) (None, 10) 650 ================================================================= Total params: 93,322 Trainable params: 93,322 Non-trainable params: 0
その結果がこれである。
Epoch 1/5 60000/60000 [==============================] - 97s 2ms/step - loss: 14.0193 - acc: 0.1115 Epoch 2/5 60000/60000 [==============================] - 88s 1ms/step - loss: 14.4351 - acc: 0.1044 Epoch 3/5 60000/60000 [==============================] - 86s 1ms/step - loss: 14.4351 - acc: 0.1044 Epoch 4/5 60000/60000 [==============================] - 91s 2ms/step - loss: 14.4351 - acc: 0.1044 Epoch 5/5 60000/60000 [==============================] - 88s 1ms/step - loss: 14.4351 - acc: 0.1044
テストデータでの正答率も0.1028と何も学んでいない。どこかでコードミスっているか?と思い、サンプルコードをgit cloneしてそのまま実行してもやはり同じようになった。
次に上のモデルのConv2D_3が妙に気になったので消してみたのが後半。
Layer (type) Output Shape Param # ================================================================= conv2d_4 (Conv2D) (None, 26, 26, 32) 320 _________________________________________________________________ max_pooling2d_3 (MaxPooling2 (None, 13, 13, 32) 0 _________________________________________________________________ conv2d_5 (Conv2D) (None, 11, 11, 64) 18496 _________________________________________________________________ max_pooling2d_4 (MaxPooling2 (None, 5, 5, 64) 0 _________________________________________________________________ flatten_2 (Flatten) (None, 1600) 0 _________________________________________________________________ dense_3 (Dense) (None, 64) 102464 _________________________________________________________________ dense_4 (Dense) (None, 10) 650 ================================================================= Total params: 121,930 Trainable params: 121,930 Non-trainable params: 0
その結果がこれである。
Epoch 1/5 60000/60000 [==============================] - 85s 1ms/step - loss: 0.1748 - acc: 0.9473 Epoch 2/5 60000/60000 [==============================] - 87s 1ms/step - loss: 0.0534 - acc: 0.9835 Epoch 3/5 60000/60000 [==============================] - 85s 1ms/step - loss: 0.0391 - acc: 0.9881 Epoch 4/5 60000/60000 [==============================] - 84s 1ms/step - loss: 0.0309 - acc: 0.9911 Epoch 5/5 60000/60000 [==============================] - 84s 1ms/step - loss: 0.0259 - acc: 0.9922
テストデータでの正答率も0.9899と高い。この結果からはこのConv2D_3が悪かったんかなぁという推測を生む以上の何かは得られなかった。
その次に、イヌとネコの分類器を作るパートでも同様にサンプルコード通りに試してみた。そのノートブックがこちら。
モデルのサマリはこんな感じ。
Layer (type) Output Shape Param # ================================================================= conv2d_1 (Conv2D) (None, 148, 148, 32) 896 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 74, 74, 32) 0 _________________________________________________________________ conv2d_2 (Conv2D) (None, 72, 72, 64) 18496 _________________________________________________________________ max_pooling2d_2 (MaxPooling2 (None, 36, 36, 64) 0 _________________________________________________________________ conv2d_3 (Conv2D) (None, 34, 34, 128) 73856 _________________________________________________________________ max_pooling2d_3 (MaxPooling2 (None, 17, 17, 128) 0 _________________________________________________________________ conv2d_4 (Conv2D) (None, 15, 15, 128) 147584 _________________________________________________________________ max_pooling2d_4 (MaxPooling2 (None, 7, 7, 128) 0 _________________________________________________________________ flatten_1 (Flatten) (None, 6272) 0 _________________________________________________________________ dense_1 (Dense) (None, 512) 3211776 _________________________________________________________________ dense_2 (Dense) (None, 1) 513 ================================================================= Total params: 3,453,121 Trainable params: 3,453,121 Non-trainable params: 0
実行結果はこんな感じ。
Epoch 1/30 100/100 [==============================] - 199s 2s/step - loss: 3.9247 - acc: 0.4875 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 2/30 100/100 [==============================] - 190s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 3/30 100/100 [==============================] - 197s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 4/30 100/100 [==============================] - 193s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 5/30 100/100 [==============================] - 191s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 6/30 100/100 [==============================] - 192s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 7/30 100/100 [==============================] - 191s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 8/30 100/100 [==============================] - 192s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 9/30 100/100 [==============================] - 192s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 10/30 100/100 [==============================] - 192s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 11/30 100/100 [==============================] - 191s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 12/30 100/100 [==============================] - 192s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 13/30 100/100 [==============================] - 194s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 14/30 100/100 [==============================] - 192s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 15/30 100/100 [==============================] - 191s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 16/30 100/100 [==============================] - 195s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 17/30 100/100 [==============================] - 193s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 18/30 100/100 [==============================] - 192s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 19/30 100/100 [==============================] - 192s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 20/30 100/100 [==============================] - 192s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 21/30 100/100 [==============================] - 192s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 22/30 100/100 [==============================] - 195s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 23/30 100/100 [==============================] - 192s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 24/30 100/100 [==============================] - 193s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 25/30 100/100 [==============================] - 193s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 26/30 100/100 [==============================] - 192s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 27/30 100/100 [==============================] - 193s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 28/30 100/100 [==============================] - 192s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 29/30 100/100 [==============================] - 192s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000 Epoch 30/30 100/100 [==============================] - 193s 2s/step - loss: 7.9712 - acc: 0.5000 - val_loss: 7.9712 - val_acc: 0.5000
2つの分類で正答率0.5なのでやはりダメダメである。何故サンプルコード通りでうまくいかないのかが全くわからない。それとlossが全く動いていないのが気になる。この手の「同じ値を出力し続ける」ようなことって、記憶が曖昧だがメモリ足りない時とかに起きるようなことがあった気がするなぁなんて思いながら結果を眺めていた。
おそらくMNISTでConv2D_3が入るとうまくいかない理由と、イヌネコ分類器がうまくいかない理由は一緒なんだろうという気がしている。ただその原因が全く分からない。ググっても同じような人は見当たらない。どこかでタイポしているのだろうか。なんなのか。今日はずっとこれの原因を探していたがもう限界である。
(追記)
ノートブック
やはりオーバーフローの類が原因として濃厚だったためバッチサイズを10にしたところ、たまに学習がうまくいくようになった。ただやはりうまく学習するモデルとそうでないモデルの違いがよくわからず模索した跡が、ノートブックのmodel1~3の部分。
そんな時に、学習と関係ないコマンドを追加しただけなのにうまく学習が進んでいたモデルがうまく学習しなかったところでハッと気づいた。そこで上のmodel2を10回繰り返したのが、ノートブック後半部。
結果としてうまくいったりうまくいかなかったりするものとが出てきたので、なるほどなと。こういうこともあるのだな。
しかし、「局所解にハマってlossがなかなか下がらない」ならともかく、「lossがドカンと上がってしまう」というのは、一体何が起きているのか直感的によくわからないですね。やっぱり詳しい人教えてください。
0 件のコメント:
コメントを投稿