为什么使用Keras(Python)时,深度学习模型的完全丢失会突然变成NaN?

为什么使用Keras(Python)时,深度学习模型的完全丢失会突然变成NaN?,python,tensorflow,keras,deep-learning,Python,Tensorflow,Keras,Deep Learning,我有一个Keras(TF2.0后端)模型,它使用多个损失值进行反向传播。随着培训的初始化,模型似乎逐渐学习(清楚地表明损失随着时间的推移而减少) 然而,在某个随机时期,总损失突然变为NaN。在接下来的时间里,我个人的一些损失也变成了0.000。这种行为是不确定的。有时,该模型运行了整个100个时代而没有成为NaN 当单个损失是有限的数字时,总损失怎么会变成NaN? 所以我的问题更多的是概念性的,而不是编程。为什么会发生这种情况?最明显的候选者是定制的损失函数,但是,正如我提到的,单个损失还没有变

我有一个Keras(TF2.0后端)模型,它使用多个损失值进行反向传播。随着培训的初始化,模型似乎逐渐学习(清楚地表明损失随着时间的推移而减少)

然而,在某个随机时期,总损失突然变为NaN。在接下来的时间里,我个人的一些损失也变成了0.000。这种行为是不确定的。有时,该模型运行了整个100个时代而没有成为NaN

当单个损失是有限的数字时,总损失怎么会变成NaN?

所以我的问题更多的是概念性的,而不是编程。为什么会发生这种情况?最明显的候选者是定制的损失函数,但是,正如我提到的,单个损失还没有变成NaN(参见下面的示例)

在这里,我展示了一个训练周期中随机选取的4个时期的损失:

--------------------------------------------------
STARTING EPOCH: 0
        loss:7.612e-01, 
   xout_loss:7.606e-01, 
 yout_0_loss:0.000e+00,  yout_1_loss:1.673e-04,  yout_2_loss:4.342e-04,  yout_3_loss:3.220e-05,
...
--------------------------------------------------
STARTING EPOCH: 10
        loss:3.355e-02, 
   xout_loss:3.349e-02, 
 yout_0_loss:0.000e+00,  yout_1_loss:0.000e+00,  yout_2_loss:6.202e-05,  yout_3_loss:0.000e+00,
...
--------------------------------------------------
STARTING EPOCH: 20
        loss:3.294e-02, 
   xout_loss:3.289e-02, 
 yout_0_loss:0.000e+00,  yout_1_loss:0.000e+00,  yout_2_loss:5.094e-05,  yout_3_loss:0.000e+00,
...
--------------------------------------------------
STARTING EPOCH: 47
        loss:   nan, 
   xout_loss:3.501e-03, 
 yout_0_loss:0.000e+00,  yout_1_loss:0.000e+00,  yout_2_loss:5.997e-05,  yout_3_loss:0.000e+00,
...
--------------------------------------------------
STARTING EPOCH: 48
        loss:   nan, 
   xout_loss:3.240e-02, 
 yout_0_loss:0.000e+00,  yout_1_loss:0.000e+00,  yout_2_loss:0.000e+00,  yout_3_loss:0.000e+00,
请注意,我已经查阅了一些关于损失转为NaN的问题,但在所有这些情况下,OP有一个单一的损失成为NaN,并且必须解决其损失函数。这里的情况不同。例如

更新:损失函数定义

对于yout_xxx:

def corr_loss(y_true, y_pred):
    y_true = tf.squeeze(y_true)
    y_pred = tf.squeeze(y_pred)

    xm = y_true - tf.reduce_mean(y_true, axis=1, keepdims=True)
    ym = y_pred - tf.reduce_mean(y_pred, axis=1, keepdims=True)

    c_num = tf.reduce_sum(tf.multiply(xm, ym), axis=1)
    c_den = tf.math.sqrt(tf.multiply(tf.reduce_sum(tf.math.square(xm), axis=1), tf.reduce_sum(tf.math.square(ym), axis=1)))

    r = c_num / (c_den+tf.keras.backend.epsilon())
    loss = 1 - tf.math.square(r)
    return loss
对于xout_损失:

tf.keras.losses.mean_squared_error(y_true, y_pred)

不应该为零的东西达到了零?然后你得到了一些
log
,或者除法,或者其他不能取全零的东西?你能指定如何实现每个损失函数吗?但是正如我上面提到的,总损失不就是单个损失的总和吗?在这种情况下,当这些损失是有限的,那么总损失将如何变成NaN。个人损失只是皮尔逊相关性(xout是mse)。让我更新一下。正如daniel所说,我遇到了这样的情况,当我的模型试图最小化log prob时,我的损失变成了NaN,当prob=0(log 0=-inf)时,它最终达到了-inf(NaN)。最有可能是爆炸性的梯度。由于深层神经网络中复杂的训练机制,即使没有“bug”,也可能发生这种情况。此外,您的丢失具有“危险”的操作,如除法和平方根(这些操作可能具有不正确的渐变)。您可能希望减少层的数量或引入规范化方法,如批量规范化。