使用三元组损失连体神经网络模型评估 (model.evaluate) - tensorflow

Evaluating (model.evaluate) with a triplet loss Siamese neural network model - tensorflow

我训练了一个使用三元组损失的连体神经网络。这很痛苦,但我想我设法做到了。但是,我很难理解如何使用这个模型进行评估。

SNN:

def triplet_loss(y_true, y_pred):
    margin = K.constant(1)
    return K.mean(K.maximum(K.constant(0), K.square(y_pred[:,0]) - 0.5*(K.square(y_pred[:,1])+K.square(y_pred[:,2])) + margin))

def euclidean_distance(vects):
    x, y = vects
    return K.sqrt(K.maximum(K.sum(K.square(x - y), axis=1, keepdims=True), K.epsilon()))
anchor_input = Input((max_len, ), name='anchor_input')
positive_input = Input((max_len, ), name='positive_input')
negative_input = Input((max_len, ), name='negative_input')

Shared_DNN = create_base_network(embedding_dim = EMBEDDING_DIM, max_len=MAX_LEN, embed_matrix=embed_matrix)

encoded_anchor = Shared_DNN(anchor_input)
encoded_positive = Shared_DNN(positive_input)
encoded_negative = Shared_DNN(negative_input)

positive_dist = Lambda(euclidean_distance, name='pos_dist')([encoded_anchor, encoded_positive])
negative_dist = Lambda(euclidean_distance, name='neg_dist')([encoded_anchor, encoded_negative])
tertiary_dist = Lambda(euclidean_distance, name='ter_dist')([encoded_positive, encoded_negative])

stacked_dists = Lambda(lambda vects: K.stack(vects, axis=1), name='stacked_dists')([positive_dist, negative_dist, tertiary_dist])

model = Model([anchor_input, positive_input, negative_input], stacked_dists, name='triple_siamese')

model.compile(loss=triplet_loss, optimizer=adam_optim, metrics=[accuracy])
history = model.fit([Anchor,Positive,Negative],y=Y_dummy,validation_data=([Anchor_test,Positive_test,Negative_test],Y_dummy2), batch_size=128, epochs=25)

我了解一旦使用三元组训练模型,评估实际上不应该要求使用三元组。但是,我该如何欺骗这种重塑?

因为这是一个 SNN,我想将两个输入输入 model.evaluate,以及一个表示两个输入是否相似的分类变量 (1 = similar, 0 = not similar)

所以基本上,我想要 model.evaluate(input1, input2, y_label)。但是我不确定如何使用我训练的模型来获得它。如上所示,我训练了三个输入:model.fit([Anchor,Positive,Negative],y=Y_dummy ... ) .

我知道我应该保存训练模型的权重,但我不知道将权重加载到哪个模型。

非常感谢您的帮助!

编辑: 我知道以下预测方法,但我不是在寻找预测,我希望使用 model.evaluate 因为我想获得模型的 loss/accuracy 的一些最终度量。此外,这种方法只将锚点输入模型(而我对文本相似性感兴趣,所以想输入 2 个输入)

eval_model = Model(inputs=anchor_input, outputs=encoded_anchor)
eval_model.load_weights('weights.hdf5')

考虑到 eval_model 被训练来生成嵌入,我认为使用 cosine similarity.

来评估两个嵌入之间的相似性应该很好

根据TF文档,余弦相似度是一个介于-1和1之间的数,当它是一个更接近-1的负数时,表示相似度更大。当它是接近1的正数时,表示相异性较大。

我们可以简单地计算所有待处理样本的正输入和负输入之间的余弦相似度。当余弦相似度 < 0 时,我们可以说两个输入相似 (1 = similar, 0 = not similar)。最后,可以计算二进制精度作为最终指标。

我们可以使用 TF 进行所有计算,而无需使用 model.evaluate

eval_model = Model(inputs=anchor_input, outputs=encoded_anchor)
eval_model.load_weights('weights.hdf5')

cos_sim = tf.keras.losses.cosine_similarity(
    eval_model(X1), eval_model(X2)
).numpy().reshape(-1,1)

accuracy = tf.reduce_mean(tf.keras.metrics.binary_accuracy(Y, -cos_sim, threshold=0))

Another approach在于计算anchor和positive图像之间的余弦相似度,并将其与anchor和negative图像之间的相似度进行比较。

eval_model = Model(inputs=anchor_input, outputs=encoded_anchor)
eval_model.load_weights('weights.hdf5')

positive_similarity = tf.keras.losses.cosine_similarity(
    eval_model(X_anchor), eval_model(X_positive)
).numpy().mean()

negative_similarity = tf.keras.losses.cosine_similarity(
    eval_model(X_anchor), eval_model(X_negative)
).numpy().mean()

我们应该期望锚点和正图像之间的相似度大于锚点和负图像之间的相似度。