我正在使用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),并且导致数值问题.
当人们尝试用CNN解决语义分割的任务时,他们通常在训练期间使用softmax-crossentropy损失(参见完全转换 - 长).但是,当谈到比较不同方法的表现时,报告了诸如交叉结合的措施.
我的问题是为什么人们不直接训练他们想要优化的措施?在训练期间对我进行一些衡量训练似乎很奇怪,但评估基准的另一个衡量标准.
我可以看到IOU在训练样本时存在问题,其中类不存在(union = 0且intersection = 0 =>除零归零).但是,当我可以确保我的基础事实的每个样本都包含所有类别时,还有另一个不使用此度量的原因吗?
machine-learning computer-vision image-segmentation deep-learning
我一直在使用tf.gradients()函数并遇到了我意想不到的行为。也就是说,它似乎无法计算切片变量的梯度。我举了一个例子,希望能说明我的意思:
import tensorflow as tf
a = tf.Variable([1.0])
b = tf.Variable([1.0])
c = tf.concat(0, [a, b])
print(c) # >Tensor("concat:0", shape=(2,), dtype=float32)
grad_full = tf.gradients(c, c)
grad_slice1 = tf.gradients(c, a)
grad_slice2 = tf.gradients(c, c[:, ]) # --> Here the gradient is None
grad_slice3 = tf.gradients(c, c[0, ]) # --> Here the gradient is None
print(grad_full) # >[<tf.Tensor 'gradients/Fill:0' shape=(2,) dtype=float32>]
print(grad_slice1) # >[<tf.Tensor 'gradients_1/concat_grad/Slice:0' shape=(1,) dtype=float32>]
print(grad_slice2) # >[None]
print(grad_slice3) # >[None]
sess = tf.Session()
sess.run(tf.initialize_all_variables())
grad_full_v, grad_slice_v = …Run Code Online (Sandbox Code Playgroud)