我一直在寻找深度学习中三元组嵌入的简单实现。我想使用Keras,因为这是我稍微熟悉的(尽管仍然非常缺乏经验)。
以下是其中一个灵感作品的参考:paper on embedded triplets
我已经找到了一个很好的例子,开始使用mnist数据集,据我所知,它工作得很好。实现3个嵌入层的合并时会出现问题。
def build_model(input_shape):
base_input = Input(input_shape)
x = Conv2D(32, (3, 3), activation='relu')(base_input)
x = MaxPooling2D((2, 2))(x)
x = Conv2D(64, (3, 3), activation='relu')(x)
x = MaxPooling2D((2, 2))(x)
x = Dropout(0.25)(x)
x = Flatten()(x)
x = Dense(2, activation='linear')(x)
embedding_model = Model(base_input, x, name='embedding')
anchor_input = Input(input_shape, name='anchor_input')
positive_input = Input(input_shape, name='positive_input')
negative_input = Input(input_shape, name='negative_input')
anchor_embedding = embedding_model(anchor_input)
positive_embedding = embedding_model(positive_input)
negative_embedding = embedding_model(negative_input)
inputs = [anchor_input, positive_input, negative_input]
outputs = [anchor_embedding, positive_embedding, negative_embedding]
triplet_model = Model(inputs, outputs)
triplet_model.add_loss(K.mean(triplet_loss(outputs)))
triplet_model.compile(loss=None, optimizer='adam') # <-- CRITICAL LINE
return embedding_model, triplet_model
通过当前实施,损失是通过model.add_loss
添加的,我还没有找到这样的例子。 真正的问题是,我无法加载已保存的模型。行
triplet_model.save('triplet.h5')
model = load_model('triplet.h5')
返回:
ValueError: The model cannot be compiled because it has no loss to optimize.
在“损失”中添加参数&#39;当我尝试编译模型时,参数引发了另一个错误。 我想问一下如何绕过这个问题,或者是否有更好的方法来创建嵌入模型的模型(可能没有空的损失函数)。
以下是triplet_loss函数供参考:
def triplet_loss(inputs, dist='sqeuclidean', margin='maxplus'):
anchor, positive, negative = inputs
positive_distance = K.square(anchor - positive)
negative_distance = K.square(anchor - negative)
if dist == 'euclidean':
positive_distance = K.sqrt(K.sum(positive_distance, axis=-1, keepdims=True))
negative_distance = K.sqrt(K.sum(negative_distance, axis=-1, keepdims=True))
elif dist == 'sqeuclidean':
positive_distance = K.mean(positive_distance, axis=-1, keepdims=True)
negative_distance = K.mean(negative_distance, axis=-1, keepdims=True)
loss = positive_distance - negative_distance
if margin == 'maxplus':
loss = K.maximum(0.0, 1 + loss)
elif margin == 'softplus':
loss = K.log(1 + K.exp(loss))
return K.mean(loss)
以下是完整的脚本:link
答案 0 :(得分:2)
这里的问题是您离开triplet_model.compile(loss=None)
,但keras
不知道如何在load_model()
中正确处理它。我知道你必须这样做,但你可以用不同的方式加载模型来解决当前的问题。
简而言之,不要通过load_model()
加载整个模型,而只是加载load_weights()
的权重。
例如,您可以
# save only weights
triplet_model.save_weights('tmp.h5')
# load saved weights
new_embedding_model, new_triplet_model = build_model(input_shape)
new_triplet_model.load_weights('tmp.h5') # load only weights