zim*_*rmc 12 python deep-learning tensorflow
我正在使用Adam解算器训练网络并遇到问题,优化在某些时候点击'nan',但是到目前为止,损失似乎很好地减少了.它只发生在一些特定的配置上,经过几千次迭代.例如,批量大小为5的网络将出现问题,而批量大小为1的网络则有效.所以我开始调试我的代码:
1)我想到的第一件事就是在网络命中'nan'时检查输入,但它们看起来合理(正确标记的地面实况和输入具有可靠的值范围)
2)搜索时我发现了tf.verify_tensor_all_finite(..),我把它全部放在我的代码上看,哪个张量首先成为'nan'.我可以将问题缩小到以下几行:
kernel = tf.verify_tensor_all_finite(kernel, 'kernel')
in_tensor = tf.verify_tensor_all_finite(in_tensor, 'in_tensor')
tmp_result = tf.nn.conv2d_transpose(value=in_tensor, filter=kernel, output_shape=output_shape,
strides=strides, padding='SAME')
tmp_result = tf.verify_tensor_all_finite(tmp_result, 'convres')
Run Code Online (Sandbox Code Playgroud)
抛出错误,其中包含:
InvalidArgumentError (see above for traceback): convres : Tensor had NaN values
[[Node: upconv_logits5_fs/VerifyFinite_2/CheckNumerics = CheckNumerics[T=DT_FLOAT, _class=["loc:@upconv_logits5_fs/conv2d_transpose"], message="convres", _device="/job:localhost/replica:0/task:0/gpu:0"](upconv_logits5_fs/conv2d_transpose)]]
[[Node: Adam/update/_2794 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/cpu:0", send_device="/job:localhost/replica:0/task:0/gpu:0", send_device_incarnation=1, tensor_name="edge_154_Adam/update", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/cpu:0"]()]]
Run Code Online (Sandbox Code Playgroud)
现在我不确定这里发生了什么.
我想,在前进过程中一切都进展顺利,因为标量丢失没有触发错误,内核和输入仍然是有效数字.似乎有些Adam更新节点修改了我upconv_logits5_fs对nan 的值.这个转置的卷积操作是我网络的最后一个,因此是第一个要更新的网络.
我正在处理tf.nn.softmax_cross_entropy_with_logits()亏损并将tf.verify_tensor_all_finite()其全部输入和输出,但它们不会触发错误.我能得出的唯一结论是,亚当解算器可能存在数值问题.
非常感激您的帮忙.
编辑:
我能够通过将求解器epsilon参数从1e-8增加到1e-4 来解决我的问题.似乎我的一些参数倾向于具有非常小的零方差tf.sqrt(0.0 + epsilon),并且导致数值问题.
小智 19
我多次遇到同样的问题.这个问题背后的原因是使用softmax和crossentropy.因此,当您计算渐变并以零或inf潜水时,您将获得正在传播的nan,抛出所有参数.
很少有人建议避免这个问题
解决方案:
在我的情况下,学习率解决了这个问题,但我仍在努力优化它
Feras 的答案中没有包含一个额外的步骤,并且花费了我一天的调试时间。
提高变量的精度。我有一个网络,其中很多变量被定义为 float16。除了 Adam 和 Adadelta 之外,网络对于所有优化器都运行良好。经过几个小时的调试后,我切换到tf.float64并且它工作了。
| 归档时间: |
|
| 查看次数: |
6032 次 |
| 最近记录: |