T.P*_*Poe 5 python conv-neural-network keras tensorflow
我想实现一个图像检索模型。该模型将使用三元组损失函数(与 facenet 或类似架构相同)进行训练。我的想法是使用来自 Keras 的预训练分类模型(例如 resnet50),并使其成为三重架构。这是我在 Keras 中的模型:
resnet_input = Input(shape=(224,224,3))
resnet_model = ResNet50(weights='imagenet', include_top = False, input_tensor=resnet_input)
net = resnet_model.output
net = Flatten(name='flatten')(net)
net = Dense(512, activation='relu', name='embded')(net)
net = Lambda(l2Norm, output_shape=[512])(net)
base_model = Model(resnet_model.input, net, name='resnet_model')
input_shape=(224,224,3)
input_anchor = Input(shape=input_shape, name='input_anchor')
input_positive = Input(shape=input_shape, name='input_pos')
input_negative = Input(shape=input_shape, name='input_neg')
net_anchor = base_model(input_anchor)
net_positive = base_model(input_positive)
net_negative = base_model(input_negative)
positive_dist = Lambda(euclidean_distance, name='pos_dist')([net_anchor, net_positive])
negative_dist = Lambda(euclidean_distance, name='neg_dist')([net_anchor, net_negative])
stacked_dists = Lambda(
lambda vects: K.stack(vects, axis=1),
name='stacked_dists'
)([positive_dist, negative_dist])
model = Model([input_anchor, input_positive, input_negative], stacked_dists, name='triple_siamese')
def triplet_loss(_, y_pred):
margin = K.constant(1)
return K.mean(K.maximum(K.constant(0), K.square(y_pred[0]) - K.square(y_pred[1]) + margin))
def accuracy(_, y_pred):
return K.mean(y_pred[0] < y_pred[1])
def l2Norm(x):
return K.l2_normalize(x, axis=-1)
def euclidean_distance(vects):
x, y = vects
return K.sqrt(K.maximum(K.sum(K.square(x - y), axis=1, keepdims=True), K.epsilon()))
Run Code Online (Sandbox Code Playgroud)
该模型应该为每个图像预测一个特征向量。如果图像来自同一类,则这些向量之间的距离(在这种情况下为欧几里得)应该接近于零,如果不是,则接近于 1。
我已经尝试了不同的学习步骤、批量大小、损失函数中的不同边距、从原始 resnet 模型中选择不同的输出层、将不同的层添加到 resnet 的末尾、只训练新添加的层 vs 训练整个模型。我也尝试使用这个没有预训练权重的 resnet 模型,结果仍然相同,大约 0.5 准确度和 1.0 损失,无论我做什么。(输入图像以该模型预期的方式进行了预处理keras.applications.resnet50.preprocess_input
)
我没有进行任何可能导致收敛缓慢的硬负挖掘,但在这种情况下,0.5 的准确度(检查函数)仍然是随机预测。
所以我开始想也许我在这里错过了一些非常重要的东西(这是一个非常困难的架构)。所以,如果您在我的实现中发现错误或可疑之处,我会非常高兴。
如果有人有兴趣,重写
y_pred[0]
和y_pred[1]
到
y_pred[:,0,0]
和y_pred[:,1,0]
修复。
现在模型似乎正在训练(损失在减少,准确性在增加)。
归档时间: |
|
查看次数: |
3778 次 |
最近记录: |