我想学习一种结合VGG和巴黎6k图片的嵌入方式。Adrian Ung三胞胎损失. 问题是经过少量的迭代后,在第一个epoch,损失变成了nan,然后准确率和验证准确率增长到了1.我已经尝试过降低学习率,增加批处理量(只有16个beacuse内存),改变优化器(Adam和RMSprop),检查我的数据集上是否有None值。
我已经尝试过降低学习率,增加批处理量(由于内存的原因,只增加到16个),改变优化器(Adam和RMSprop),检查我的数据集上是否有None值,将数据格式从 "float32 "改为 "float64",给它们增加一点偏置,并简化模型。
这是我的代码。
base_model = VGG16(include_top = False, input_shape = (512, 384, 3))
input_images = base_model.input
input_labels = Input(shape=(1,), name='input_label')
embeddings = Flatten()(base_model.output)
labels_plus_embeddings = concatenate([input_labels, embeddings])
model = Model(inputs=[input_images, input_labels], outputs=labels_plus_embeddings)
batch_size = 16
epochs = 2
embedding_size = 64
opt = Adam(lr=0.0001)
model.compile(loss=tl.triplet_loss_adapted_from_tf, optimizer=opt, metrics=['accuracy'])
label_list = np.vstack(label_list)
x_train = image_list[:2500]
x_val = image_list[2500:]
y_train = label_list[:2500]
y_val = label_list[2500:]
dummy_gt_train = np.zeros((len(x_train), embedding_size + 1))
dummy_gt_val = np.zeros((len(x_val), embedding_size + 1))
H = model.fit(
x=[x_train,y_train],
y=dummy_gt_train,
batch_size=batch_size,
epochs=epochs,
validation_data=([x_val, y_val], dummy_gt_val),callbacks=callbacks_list)
图像是3366个,数值在[0,1]范围内缩放。网络采取虚值,因为它试图从图像中学习嵌入的方式,同一类的图像应该有小的距离,而不同类的图像应该有高的距离,比真实类是训练的一部分。
我注意到我之前做了一个不正确的类划分(并保留了应该丢弃的图像),我并没有出现nan损失的问题。
我应该尝试做什么?
先谢谢你,对不起我的英语。
在某些情况下,随机的NaN损失可能是由你的数据引起的,因为如果你的批次中没有正对,你会得到一个NaN损失。
你可以在Adrian Ung的笔记本中看到(或者在 tensorflow附加组件 三重损失;这是相同的代码)。
semi_hard_triplet_loss_distance = math_ops.truediv(
math_ops.reduce_sum(
math_ops.maximum(
math_ops.multiply(loss_mat, mask_positives), 0.0)),
num_positives,
name='triplet_semihard_loss')
有一个正对数的除法(num_positives
),这可能导致NaN。
我建议你尝试检查你的数据管道,以确保你的每个批次中至少有一个正对。(例如,你可以改编一些代码在 triplet_loss_adapted_from_tf
以获得 num_positives
的,并检查它是否大于0)。)
试试增加你的批次大小。我也遇到过这种情况。正如前面的回答中提到的,网络无法找到任何num_positive。我有250个类,最初得到的是nan损失。我把它增加到128256,然后就没有问题了。
我看到Paris6k有15个班或12个班。增加你的批处理量32,如果GPU内存发生问题,你可以用参数较少的模型试试。你可以用Efficient B0模型开始工作。它有5.3M,而VGG16有138M参数。