美文网首页
AdamOptimizer Loss Null

AdamOptimizer Loss Null

作者: LanWong | 来源:发表于2019-08-27 15:28 被阅读0次

    之前一直用的的tensorflow的AdamOptimizer,由于想要复现下别人的论文,看到论文中的参数有momentum,因此需要用tf.train.MomentumOptimizer优化器,本来可以正常训练的代码再开始训练两步后就显示loss为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()来实现。这样一来就可以正常训练了。

    分析下原因吧,应该是momentum冲量过大导致梯度爆炸,因此需要对梯度进行约束。tf.clip_by_global_norm(tf.gradients(loss, tvars), 100) 就是约束梯度的函数,限制梯度值小于100。如此就不会因为梯度爆炸导致loss很大了。

    查看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)

    相关文章

      网友评论

          本文标题:AdamOptimizer Loss Null

          本文链接:https://www.haomeiwen.com/subject/naueectx.html