一、前沿
最近搞cvr 转化时延建模的事情,升级了一下模型结构,并写了一个巨复杂的损失函数,但是调试好多时间,总是在训练过程中偶尔报下面的错误:
错误的原因是 计算auc的过程中偶尔出现 InvalidArgumentError (see above for traceback): assertion failed: [predictions must be in [0, 1]],也就是predictions中出现了[0,1] 区间之外的值。
注:predictions经过了sigmoid
labels_auc = model.auc(tasks_outputs, train_click_labels)
_, auc = tf.metrics.auc(task_labels[..., i], predictions[..., i])
self._traceback = tf_stack.extract_stack()
InvalidArgumentError (see above for traceback): assertion failed: [predictions must be in [0, 1]] [Condition x <= y did not hold element-wise:x (strided_slice_5:0) = ] [nan nan nan...] [y (auc/Cast_1/x:0) = ] [1]nvalidArgumentError (see above for traceback): assertion failed: [predictions must be in [0, 1]]
二、问题分析
使用TensorFlow、kersa 中实现不同的神经网络,出现Nan值的情况,一般来说有两种情况:
在loss中计算后得到了Nan值 在更新网络权 的时候出现了Nan值
三、在loss中得到Nan值
检查代码中是否存在 取对数运算,因为对数的真数部分不能为0。有0在取对数会报错,即使那个数经过了sigmoid处理也不行。tf.nn.sigmoid函数,在输出的参数非常大,或者非常小的情况下,会给出边界值1或者0。
所以我们要给对数运算的真数部分限定一个范围,否则会出现数值下溢的问题,可以使用tf.clip_by_value(input,min_value,max_value)函数来限定真数的下限。
tf.log(cvr)
改为下面
tf.log(tf.clip_by_value(cvr, 1e-10, 0.9999))
四、在更新网络权 的时候出现Nan值
在训练的过程中出现 预测值 为nan,可能数据有问题。要是训练过程中偶尔出现,你就需要 确保大致知道每一层的输出的一个范围,这样才能彻底的解决Nan值的出现,这个太难了。
在训练的过程中出现损失函数值为nan,这种情况一般是由于学习率太大,需要减小学习率;或者是在训练一段时间后出现nan,这种情况可能是由于梯度爆炸导致的,可以对梯度进行裁剪,将梯度的最大值限定在某个常数。
“无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。”