在几个像元后损失为nan



我试图预测由两个角度(theta和phi)给出的方向。我定义了一个损失函数,它是预测方向和真实方向之间的角距离,但我在几个epoch后继续得到nan值。

鉴于输出激活是线性的,我的定制的损失是:

import tensorflow as tf
import numpy as np
import tensorflow.keras.backend as K
def square_angular_distance(y_true, y_pred):
the_pred = K.abs(y_pred[:, 0])
phi_pred = (y_pred[:, 1])%(2*np.pi)
the_true = y_true[:, 0]
phi_true = y_true[:, 1]
cos_phi_pred = K.cos(phi_pred)
cos_phi_true = K.cos(phi_true)
sin_phi_pred = K.sin(phi_pred)
sin_phi_true = K.sin(phi_true)
cos_the_pred = K.cos(the_pred)
cos_the_true = K.cos(the_true)
sin_the_pred = K.sin(the_pred)
sin_the_true = K.sin(the_true)
v_true = K.stack((sin_the_true*cos_phi_true, sin_the_true*sin_phi_true, cos_the_true), axis=1)
v_pred = K.stack((sin_the_pred*cos_phi_pred, sin_the_pred*sin_phi_pred, cos_the_pred), axis=1)
v_dot = K.batch_dot(v_true, v_pred)
angle_dist = tf.math.acos(K.clip(v_dot, -1., 1.))*180./np.pi
return K.mean(K.square(angle_dist), axis=-1)

其中y_pred[:, 0]和y_pred[:, 1]分别是酉向量的角和角(y_true相同)

我尝试使用正则化器来剪辑梯度,学习率,并且我还检查了数据是否没有Nan/Inf值。

我还尝试使用输出层的自定义激活函数来剪辑输出值,但它没有解决问题。

有什么建议我做错了吗?

@ATony的评论解决了这个问题。

缩短tf.math.acos的输入域可以防止损失为Nan。

K.clip(v_dot, -.999, .999)

最新更新