如何在 Keras 中使用预训练的 CNN 实现孪生网络?
How to Implement Siamese Network using pretrained CNNs in Keras?
我正在使用 Keras 为 224x224x3 大小的图像开发用于人脸识别的 Siamese 网络。 Siamese Network 的架构是这样的:
对于 CNN 模型,我正在考虑使用已经在 Keras.applications 模块中预训练的 InceptionV3 模型。
#Assume all the other modules are imported correctly
from keras.applications.inception_v3 import InceptionV3
IMG_SHAPE=(224,224,3)
def return_siamese_net():
left_input=Input(IMG_SHAPE)
right_input=Input(IMG_SHAPE)
model1=InceptionV3(include_top=False, weights="imagenet", input_tensor=left_input) #Left SubConvNet
model2=InceptionV3(include_top=False, weights="imagenet", input_tensor=right_input) #Right SubConvNet
#Do Something here
distance_layer = #Do Something
prediction = Dense(1,activation='sigmoid')(distance_layer) # Outputs 1 if the images match and 0 if it does not
siamese_net = #Do Something
return siamese_net
model=return_siamese_net()
由于模型是预训练的,我遇到了错误,现在我一直在为双网络实现距离层。
我应该在两者之间添加什么才能使这个 Siamese Network 正常工作?
一个非常重要的注意事项,在你使用距离层之前,要考虑到你只有一个卷积神经网络。
共享权重实际上只指一个卷积神经网络,共享权重是因为在传递一对图像时使用相同的权重(取决于使用的损失函数)以计算特征并随后每个输入图像的嵌入。
您将只有一个神经网络,块逻辑需要如下所示:
def euclidean_distance(vectors):
(features_A, features_B) = vectors
sum_squared = K.sum(K.square(features_A - features_B), axis=1, keepdims=True)
return K.sqrt(K.maximum(sum_squared, K.epsilon()))
image_A = Input(shape=...)
image_B = Input(shape=...)
feature_extractor_model = get_feature_extractor_model(shape=...)
features_A = feature_extractor(image_A)
features_B = feature_extractor(image_B)
distance = Lambda(euclidean_distance)([features_A, features_B])
outputs = Dense(1, activation="sigmoid")(distance)
siamese_model = Model(inputs=[image_A, image_B], outputs=outputs)
当然,特征提取器模型可以是来自Keras/TensorFlow的预训练网络,输出分类层得到改进。
主要逻辑应该和上面一样,当然,如果你想使用triplet loss,那就需要三个输入(Anchor,Positive,Negative),但是一开始我建议坚持基础。
此外,最好查阅此文档:
我正在使用 Keras 为 224x224x3 大小的图像开发用于人脸识别的 Siamese 网络。 Siamese Network 的架构是这样的:
对于 CNN 模型,我正在考虑使用已经在 Keras.applications 模块中预训练的 InceptionV3 模型。
#Assume all the other modules are imported correctly
from keras.applications.inception_v3 import InceptionV3
IMG_SHAPE=(224,224,3)
def return_siamese_net():
left_input=Input(IMG_SHAPE)
right_input=Input(IMG_SHAPE)
model1=InceptionV3(include_top=False, weights="imagenet", input_tensor=left_input) #Left SubConvNet
model2=InceptionV3(include_top=False, weights="imagenet", input_tensor=right_input) #Right SubConvNet
#Do Something here
distance_layer = #Do Something
prediction = Dense(1,activation='sigmoid')(distance_layer) # Outputs 1 if the images match and 0 if it does not
siamese_net = #Do Something
return siamese_net
model=return_siamese_net()
由于模型是预训练的,我遇到了错误,现在我一直在为双网络实现距离层。
我应该在两者之间添加什么才能使这个 Siamese Network 正常工作?
一个非常重要的注意事项,在你使用距离层之前,要考虑到你只有一个卷积神经网络。
共享权重实际上只指一个卷积神经网络,共享权重是因为在传递一对图像时使用相同的权重(取决于使用的损失函数)以计算特征并随后每个输入图像的嵌入。
您将只有一个神经网络,块逻辑需要如下所示:
def euclidean_distance(vectors):
(features_A, features_B) = vectors
sum_squared = K.sum(K.square(features_A - features_B), axis=1, keepdims=True)
return K.sqrt(K.maximum(sum_squared, K.epsilon()))
image_A = Input(shape=...)
image_B = Input(shape=...)
feature_extractor_model = get_feature_extractor_model(shape=...)
features_A = feature_extractor(image_A)
features_B = feature_extractor(image_B)
distance = Lambda(euclidean_distance)([features_A, features_B])
outputs = Dense(1, activation="sigmoid")(distance)
siamese_model = Model(inputs=[image_A, image_B], outputs=outputs)
当然,特征提取器模型可以是来自Keras/TensorFlow的预训练网络,输出分类层得到改进。
主要逻辑应该和上面一样,当然,如果你想使用triplet loss,那就需要三个输入(Anchor,Positive,Negative),但是一开始我建议坚持基础。
此外,最好查阅此文档: