使用自定义训练循环进行训练期间,NaN损失以及NaN输出

时间:2020-06-16 12:39:08

标签: python tensorflow machine-learning keras deep-learning

我正在尝试训练一个网络,该网络将3个预训练模型(VGG NET)的最后卷积层的输出作为输入。

现在,我要解决的问题是多标签分类问题。

def grads_ds(model_ds, ds_inputs,y_true,cw):
    with tf.GradientTape() as ds_tape:
        y_pred = model_ds(ds_inputs)
        #print(y_pred)
        logits_1 = -1*y_true*K.log(y_pred)*cw[:,0]
        logits_0 = -1*(1-y_true)*K.log(1-y_pred)*cw[:,1]
        loss = logits_1 + logits_0
        loss_value_ds = K.sum(loss)

    #print(loss_value_ds)

    ds_grads = ds_tape.gradient(loss_value_ds,model_ds.trainable_variables,unconnected_gradients=tf.UnconnectedGradients.NONE)
    return loss_value_ds, ds_grads

这是计算梯度的代码,就像我正在使用自定义训练循环一样。

我将此问题表示为3个二进制分类问题(3个类),因此我尝试为每个问题计算二进制交叉熵。我还对输出应用了sigmoid激活。

此外,班级不平衡,因此,我也使用了班级权重。

班级权重示例:

[[0.61883899 2.60368664]
 [2.71634615 0.61279826]
 [1.4231738  0.77080491]]

训练开始时,梯度值在1e-1至1e-8的量级之间变化,反之亦然。经过约20次迭代后,梯度值突然变为nan

我能想到的是手动计算损失函数时出现的一个问题,这是由我自己引起的,这是因为张量流中没有任何加权二进制交叉熵函数。

另一件事是,预训练的图层被冻结并且没有进行微调。仅对与预训练模型的输出连接的密集层进行训练。

输出的形状为41472,形状为2048的FC层连接到该形状,然后是另一个形状为3的致密层(用于输出)。

我正在使用的优化程序是Adam(lr=1e-5)

每批包含16张图像。可训练参数的总数约为8500万。

获得nan损失和nan输出值的原因是什么?

0 个答案:

没有答案