我目前正在使用三元组损失训练相似性学习神经网络。我采用了半硬负挖掘来训练网络来学习特征。训练后的模型具有较高的准确率(或召回率 = 88%),但平均准确率较低。
规格:
- 三元组损失中使用的保证金=1.6。
- 嵌入使用 L2 范数进行归一化
- 具有最小平方距离的图像对被识别为匹配
- 分数被否定并按降序排序(最小的距离代表更高的置信度)
- PR(precision-recall)曲线是在分数按置信度降序排序后为每个预测绘制的曲线(首先绘制高置信度分数,然后是低置信度)
置信度(或分数)= - (两个图像对嵌入之间的平方距离)
问题:
- PR 曲线呈下降趋势,直到召回率 = 0.05 最高置信度得分非常糟糕
- 这在召回 0.05 后会有所改善
问题:如何调查并尝试提高最高置信度分数的精度。任何想法,指针?
我试过的:
- 测试错误;代码看起来不错,准确率(高召回率)准确
- 验证准确性测试(随机可视化的三元组对)
- 降低了 ALPHA =0.2(默认为triplet loss paper),但它产生低召回率(准确度)和较低的平均精度
def triplet_loss(x, alpha=ALPHA):
# Triplet Loss function.
anchor, positive, negative = x
# distance between the anchor and the positive
pos_dist = K.sum(K.square(anchor - positive), axis=1)
# distance between the anchor and the negative
neg_dist = K.sum(K.square(anchor - negative), axis=1)
# compute loss
basic_loss = pos_dist - neg_dist + alpha
loss = K.maximum(basic_loss, 0.0)
return loss
def identity_loss(y_true, y_pred):
return K.mean(y_pred)
def my_norm(ip):
return K.l2_normalize(ip, axis=-1)
def embedding_model():
# used for the embedding model.
base_cnn = keras.applications.ResNet50(weights="imagenet", input_shape=IM_SIZE + (3,), include_top=False)
flatten = keras.layers.Flatten()(base_cnn.output)
drop1 = keras.layers.Dropout(rate=0.25)(flatten)
dense1 = keras.layers.Dense(256, activation="relu")(drop1)
dense1 = keras.layers.BatchNormalization()(dense1)
output = keras.layers.Dense(256)(dense1)
output = Lambda(my_norm)(output)
trainable = False
for layer in base_cnn.layers:
if layer.name == "conv5_block1_out":
trainable = True
layer.trainable = trainable
mdl = Model(inputs=base_cnn.input, outputs=output, name="Embedding")
return mdl
def complete_model(base_model, alpha=0.2):
# Create the complete model with three
# embedding models and minimize the loss
# between their output embeddings
input_1 = Input((imsize, imsize, 3))
input_2 = Input((imsize, imsize, 3))
input_3 = Input((imsize, imsize, 3))
A = base_model(input_1)
P = base_model(input_2)
N = base_model(input_3)
loss = Lambda(triplet_loss)([A, P, N])
model = Model(inputs=[input_1, input_2, input_3], outputs=loss)
model.compile(loss=identity_loss, optimizer=Adam(LR))
return model
def get_model_name():
return "resnet50Reg0.8"
def preprocess(x):
return keras.applications.resnet50.preprocess_input(x)