Keras 如何在resnet50中应用三重态损失函数进行深度排序

Keras 如何在resnet50中应用三重态损失函数进行深度排序,keras,deep-learning,Keras,Deep Learning,我尝试创建图像嵌入,以便使用三重损失函数进行深度排序。我们的想法是,我们可以采用预训练的CNN(例如resnet50或vgg16),移除FC层,并添加L2归一化函数来检索单位向量,然后通过距离度量(例如余弦相似性)进行比较。据我所知,经过预训练的CNN预测出的向量不是最优的,而是一个良好的开端。通过添加三重丢失函数,我们可以重新训练网络,使相似的图片彼此“接近”,而不同的图片在特征空间中“远离”。受此启发,我尝试设置以下代码,但出现了一个错误ValueError:conv1\u pad这个名称在

我尝试创建图像嵌入,以便使用三重损失函数进行深度排序。我们的想法是,我们可以采用预训练的CNN(例如resnet50或vgg16),移除FC层,并添加L2归一化函数来检索单位向量,然后通过距离度量(例如余弦相似性)进行比较。据我所知,经过预训练的CNN预测出的向量不是最优的,而是一个良好的开端。通过添加三重丢失函数,我们可以重新训练网络,使相似的图片彼此“接近”,而不同的图片在特征空间中“远离”。受此启发,我尝试设置以下代码,但出现了一个错误
ValueError:conv1\u pad这个名称在模型中使用了3次。所有图层名称都应该是唯一的。

# Anchor, Positive and Negative are numpy arrays of size (200, 256, 256, 3), same for the test images

pic_size=256
def shared_dnn(inp):
    base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(3, pic_size, pic_size), 
                          input_tensor=inp)
    x = base_model.output
    x = Flatten()(x)
    x = Lambda(lambda x: K.l2_normalize(x,axis=1))(x)
    for layer in base_model.layers[15:]:
        layer.trainable = False
    return x

anchor_input = Input((3, pic_size,pic_size ), name='anchor_input')
positive_input = Input((3, pic_size,pic_size ), name='positive_input')
negative_input = Input((3, pic_size,pic_size ), name='negative_input')

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

merged_vector = concatenate([encoded_anchor, encoded_positive, encoded_negative], axis=-1, name='merged_layer')

model = Model(inputs=[anchor_input,positive_input, negative_input], outputs=merged_vector)

#ValueError: The name "conv1_pad" is used 3 times in the model. All layer names should be unique.
model.compile(loss=triplet_loss, optimizer=adam_optim)

model.fit([Anchor,Positive,Negative],
          y=Y_dummy,
          validation_data=([Anchor_test,Positive_test,Negative_test],Y_dummy2), batch_size=512, epochs=500)


我是keras的新手,我不太确定如何解决这个问题。上面链接中的作者从头开始创建了自己的CNN,但我想在resnet(或vgg16)的基础上构建它。如何配置ResNet50以使用三重丢失函数(在上面的链接中,您还可以找到三重丢失函数的源代码)。

在您的ResNet50定义中,您已经编写了

base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(3, pic_size, pic_size), input_tensor=inp)
删除输入张量参数。更改输入形状=输入。 如果您使用的是您提到的TF后端,那么输入应该是(256,256,3),那么您的输入应该是(pic_大小,pic_大小,3)

模型图如下所示:
在您的ResNet50定义中,您已经编写了

base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(3, pic_size, pic_size), input_tensor=inp)
删除输入张量参数。更改输入形状=输入。 如果您使用的是您提到的TF后端,那么输入应该是(256,256,3),那么您的输入应该是(pic_大小,pic_大小,3)

模型图如下所示:

谢谢您的意见。但是keras拒绝在同一个模型中实例化resnet50 3次。这是问题的根源。我需要找到一种方法告诉keras它需要共享参数。这段代码的原始作者创建了3个独立的CNN,但据我从文献中看到的,对于这类问题,应该共享同一个CNN。为什么图像的形状很重要?我可以将resnet与大小(3,大小,大小)的图像一起使用@shaft作者可能创建了3个独立的CNN,但网络是端到端训练的所有参数。您可以打印可训练参数的总数。这将表明这三个都是共享的。图像的形状是256256,用于Theano后端256256,3用于TF后端。感谢您的输入。但是keras拒绝在同一个模型中实例化resnet50 3次。这是问题的根源。我需要找到一种方法告诉keras它需要共享参数。这段代码的原始作者创建了3个独立的CNN,但据我从文献中看到的,对于这类问题,应该共享同一个CNN。为什么图像的形状很重要?我可以将resnet与大小(3,大小,大小)的图像一起使用@shaft作者可能创建了3个独立的CNN,但网络是端到端训练的所有参数。您可以打印可训练参数的总数。这将表明这三个都是共享的。图像的形状很重要3,256,256代表Theano后端256,256,3代表TF后端。你们有答案吗?我有完全相同的工作要做。使用三重丢失重新训练Resnet,以便您以后可以使用
ANN
LSH
@Deshwal比较图像的嵌入/潜在表示,还没有。我没有跟进这个问题,但仍然好奇这个问题的解决方案。你有答案吗?我有完全相同的工作要做。使用三重丢失重新训练Resnet,以便您以后可以使用
ANN
LSH
@Deshwal比较图像的嵌入/潜在表示,还没有。我没有跟进这个问题,但仍然好奇这个问题的解决方案是什么。