我正在尝试训练一个网络,该网络将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
输出值的原因是什么?