tf.train.MomentumOptimizerでNaNの問題を解決する



Solve Nan Problem With Tf



テンソルフローに使用されているAdamOptimizerは、他の人の論文を再現し、論文のパラメーターに勢いがあることを確認したいので、tf.train.MomentumOptimizerオプティマイザーを使用する必要があります。手順。損失がNaNであることを示しています。学習率と勢いを調整しようとしても無駄です。後で、githubで確認したところ、誰かが次のように変更するよう提案していることがわかりました。 (参照リンク https://github.com/tensorlayer/openpose-plus/issues/50 )。

opt = tf.train.MomentumOptimizer(lr_v, 0.9) train_op = opt.minimize(total_loss, global_step=global_step)

上記のコードをに変更します



tvars = tf.layers.get_variables_with_name('model', True, True) grads, _ = tf.clip_by_global_norm(tf.gradients(total_loss, tvars), 100) optimizer = tf.train.MomentumOptimizer(lr_v, 0.9) train_op = optimizer.apply_gradients(zip(grads, tvars), global_step=global_step)

コードの最初の行は、トレーニング可能な変数を取得することです。これをtf.trainable_variables()に置き換えました。このようにして、通常どおりトレーニングできます。

理由を分析すると、運動量の運動量が大きすぎて勾配爆発を引き起こすことができないため、勾配を制限する必要があります。 Tf.clip_by_global_norm(tf.gradients(loss、tvars)、100)は、勾配を制約し、勾配値を100未満に制限する関数です。これにより、勾配の爆発による大きな損失は発生しません。



tf.clip_by_global_normのドキュメントを見ると、グローバル勾配を計算する必要があるため、テキストで言及されている関数に長い時間がかかることがわかりました。 tf.clip_by_norm関数は、各勾配値を制限するため、時間がかかりません。いくつかの資料を調べた後、次のようにコードを変更できます:(参照リンク https://blog.csdn.net/linuxwindowsios/article/details/67635867 )。

optimizer = tf.train.MomentumOptimizer(learning_rate, 0.9) grads = optimizer.compute_gradients(loss) for i, (g, v) in enumerate(grads): if g is not None: grads[i] = (tf.clip_by_norm(g, 100), v) # clip gradients train_op = optimizer.apply_gradients(grads, global_step=global_step)