NaN loss when training regression network Ask Question

NaN loss when training regression network Ask Question

I have a data matrix in "one-hot encoding" (all ones and zeros) with 260,000 rows and 35 columns. I am using Keras to train a simple neural network to predict a continuous variable. The code to make the network is the following:

model = Sequential()
model.add(Dense(1024, input_shape=(n_train,)))
model.add(Activation('relu'))
model.add(Dropout(0.1))

model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.1))

model.add(Dense(256))
model.add(Activation('relu'))
model.add(Dropout(0.1))
model.add(Dense(1))

sgd = SGD(lr=0.01, nesterov=True);
#rms = RMSprop()
#model.compile(loss='categorical_crossentropy', optimizer=rms, metrics=['accuracy'])
model.compile(loss='mean_absolute_error', optimizer=sgd)
model.fit(X_train, Y_train, batch_size=32, nb_epoch=3, verbose=1, validation_data=(X_test,Y_test), callbacks=[EarlyStopping(monitor='val_loss', patience=4)] )

However, during the training process, I see the loss decrease nicely, but during the middle of the second epoch, it goes to nan:

Train on 260000 samples, validate on 64905 samples
Epoch 1/3
260000/260000 [==============================] - 254s - loss: 16.2775 - val_loss:
 13.4925
Epoch 2/3
 88448/260000 [=========>....................] - ETA: 161s - loss: nan

I tried using RMSProp instead of SGD, I tried tanh instead of relu, I tried with and without dropout, all to no avail. I tried with a smaller model, i.e. with only one hidden layer, and same issue (it becomes nan at a different point). However, it does work with less features, i.e. if there are only 5 columns, and gives quite good predictions. It seems to be there is some kind of overflow, but I can't imagine why--the loss is not unreasonably large at all.

Python バージョン 2.7.11、Linux マシンで実行、CPU のみ。最新バージョンの Theano でテストしましたが、Nans も発生したため、Theano 0.8.2 に移行してみましたが、同じ問題が発生しました。最新バージョンの Keras でも同じ問題が発生し、バージョン 0.3.2 でも同じ問題が発生します。

ベストアンサー1

ニューラルネットワークによる回帰は、出力が無制限であるため、動作させるのが難しく、特に爆発勾配問題(おそらくこれがナンの原因です)。

歴史的に、爆発的な勾配に対する重要な解決策の 1 つは学習率を下げることでしたが、Adam のようなパラメータごとの適応学習率アルゴリズムの登場により、良好なパフォーマンスを得るために学習率を設定する必要がなくなりました。ニューラル ネットワークの熱狂的なファンで、学習スケジュールを調整する方法を知っているのでなければ、SGD をモメンタムとともに使用する理由はほとんどありません。

以下に、試すことができる可能性のある事項をいくつか示します。

  1. 出力を正規化する分位正規化またはZスコアリング厳密に言うと、データセット全体ではなく、トレーニング データに対してこの変換を計算します。たとえば、分位正​​規化では、例がトレーニング セットの 60 パーセンタイルにある場合、値は 0.6 になります。(分位正規化された値を 0.5 下げて、0 パーセンタイルが -0.5、100 パーセンタイルが +0.5 になるようにすることもできます)。

  2. ドロップアウト率を上げるか、重みに L1 および L2 ペナルティを追加して、正則化を追加します。L1 正則化は特徴選択に類似しており、特徴の数を 5 に減らすとパフォーマンスが向上するとおっしゃっているので、L1 でも同様の結果が得られる可能性があります。

  3. それでも問題が解決しない場合は、ネットワークのサイズを縮小します。これはパフォーマンスに悪影響を与える可能性があるため、常に最善のアイデアとは限りませんが、入力機能 (35) に対して第 1 層のニューロンの数が多い (1024) ため、役立つ可能性があります。

  4. バッチ サイズを 32 から 128 に増やします。128 は標準的な値であり、最適化の安定性が向上する可能性があります。

おすすめ記事