損失関数がNaNになる問題
TensorFlowでDeep Learningを実行している途中で、損失関数がNaNになる問題が発生した。
Epoch: 10, Train Loss: 85.6908, Train Accuracy: 0.996, Test Error: 90.7068, Test Accuracy: 0.985238 Epoch: 20, Train Loss: 42.9642, Train Accuracy: 0.998286, Test Error: 121.561, Test Accuracy: 0.98619 Epoch: 30, Train Loss: 0.945895, Train Accuracy: 1.0, Test Error: 102.041, Test Accuracy: 0.990476 Epoch: 40, Train Loss: nan, Train Accuracy: 0.101429, Test Error: nan, Test Accuracy: 0.1 Epoch: 50, Train Loss: nan, Train Accuracy: 0.0941429, Test Error: nan, Test Accuracy: 0.1 Epoch: 60, Train Loss: nan, Train Accuracy: 0.0968571, Test Error: nan, Test Accuracy: 0.1 Epoch: 70, Train Loss: nan, Train Accuracy: 0.0881429, Test Error: nan, Test Accuracy: 0.1 Epoch: 80, Train Loss: nan, Train Accuracy: 0.0931429, Test Error: nan, Test Accuracy: 0.1 Epoch: 90, Train Loss: nan, Train Accuracy: 0.0997143, Test Error: nan, Test Accuracy: 0.1 Epoch: 100, Train Loss: nan, Train Accuracy: 0.0997143, Test Error: nan, Test Accuracy: 0.1
原因は、損失関数に指定している交差エントロピーのtf.log(Y)
にあった。
cross_entropy = -tf.reduce_sum(Y_*tf.log(Y))
tf.log(Y)
はln(x)(自然対数のlog)であり、xが0になるとき-∞になるため、NaNとなっていた。
ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装では、4章の「ニューラルネットワークの学習」で、 極少の数値を加算することで、この問題に対処する方法を提示している。
def cross_entropy_error(y, t): delta = 1e-7 return -np.sum(t * np.log(y + delta))
しかし、TensorFlowを利用したいので、上記の問題を解決しているsoftmax_cross_entropy_with_logits()
を用いて、
cross_entropy
を書き換える。
#cross_entropy = -tf.reduce_sum(Y_*tf.log(Y))
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(Y, Y_))
これにより、NaNになる問題が解決できた。
しかし、学習が進み、cross_entropy
が低くなるに連れて、Y
は1に近づき、tf.log(Y)
は0に近づくため、
cross_entropy
がNaNになる確率は低くなるはずなのだが、NaNになる点は謎のままである。
Epoch: 10, Train Error: 1.46717, Train Accuracy: 0.995, Test Error: 1.47448, Test Accuracy: 0.987619 Epoch: 20, Train Error: 1.46428, Train Accuracy: 0.997286, Test Error: 1.47456, Test Accuracy: 0.985714 Epoch: 30, Train Error: 1.46262, Train Accuracy: 0.998715, Test Error: 1.47142, Test Accuracy: 0.990476 Epoch: 40, Train Error: 1.46272, Train Accuracy: 0.998429, Test Error: 1.47249, Test Accuracy: 0.989047 Epoch: 50, Train Error: 1.46235, Train Accuracy: 0.998857, Test Error: 1.47399, Test Accuracy: 0.987619 Epoch: 60, Train Error: 1.46462, Train Accuracy: 0.996715, Test Error: 1.47435, Test Accuracy: 0.987619 Epoch: 70, Train Error: 1.46261, Train Accuracy: 0.998572, Test Error: 1.47196, Test Accuracy: 0.989524 Epoch: 80, Train Error: 1.46215, Train Accuracy: 0.999, Test Error: 1.47119, Test Accuracy: 0.99 Epoch: 90, Train Error: 1.46547, Train Accuracy: 0.995715, Test Error: 1.4784, Test Accuracy: 0.982857 Epoch: 100, Train Error: 1.46201, Train Accuracy: 0.999143, Test Error: 1.47057, Test Accuracy: 0.990476
参考文献
- Why does my TensorFlow Convnet (attempted) training result in NaN gradients?
- ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装
ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装
- 作者: 斎藤康毅
- 出版社/メーカー: オライリージャパン
- 発売日: 2016/09/24
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (14件) を見る