python - 了解 Keras MNIST 连体网络并将其调整为三元组
问题描述
我目前正在使用 Keras 在 Python 中调整这个连体网络。但是,我目前不明白损失是如何工作的(不是函数本身,而是哪些参数在哪里传递)
好的,现在一步一步我认为这是如何工作的:
distance = Lambda(euclidean_distance,
output_shape=eucl_dist_output_shape)([processed_a, processed_b])
这是两个单独网络的输出合并的行,自定义层应用以下功能:
def euclidean_distance(vects):
x, y = vects
sum_square = K.sum(K.square(x - y), axis=1, keepdims=True)
return K.sqrt(K.maximum(sum_square, K.epsilon()))
def eucl_dist_output_shape(shapes):
shape1, shape2 = shapes
return (shape1[0], 1)
因此,当该层的输入为 (128, 128) 时,输出将为 (128, 1)。在最后一步中,损失计算如下:
def contrastive_loss(y_true, y_pred):
'''Contrastive loss from Hadsell-et-al.'06
http://yann.lecun.com/exdb/publis/pdf/hadsell-chopra-lecun-06.pdf
'''
margin = 1
square_pred = K.square(y_pred)
margin_square = K.square(K.maximum(margin - y_pred, 0))
return K.mean(y_true * square_pred + (1 - y_true) * margin_square)
在这里,预测的 128D 向量与 128D 地面实况向量进行比较。
现在我将 Lambda 层更改为:
distance = Lambda(euclidean_distance,
output_shape=eucl_dist_output_shape)([processed_a, processed_b, processed_c])
所以我现在有三个具有以下适应功能的网络(应该将三个输出组合成一个输出,形状为 (128, 3)):
def euclidean_distance(vects):
return vects
def eucl_dist_output_shape(shapes):
shape1, shape2, shape3 = shapes
return (shape1, shape2, shape3)
然后是新的损失函数:
def loss_desc_triplet(vects, margin=5):
"""Triplet loss.
"""
d1, d2, d3 = vects
d_pos = K.sqrt(K.sum(K.square(d1 - d2), axis=1))
pair_dist_1_to_3 = K.sqrt(K.sum(K.square(d1 - d3), axis=1))
d_neg = pair_dist_1_to_3
return Activation.relu(d_pos - d_neg + margin)
但现在我得到这个错误:
文件“DeepLearningWithAugmentationWithTriplets.py”,第 233 行,在 output_shape=eucl_dist_output_shape)([processed_a, processes_b, processed_c])
文件“lib/python3.7/site-packages/keras/engine/base_layer.py”,第 497 行,调用 参数=user_kwargs)
文件“lib/python3.7/site-packages/keras/engine/base_layer.py”,第 565 行,在 _add_inbound_node output_tensors[i]._keras_shape = output_shapes[i]
IndexError:列表索引超出范围
但我不确定是什么原因造成的。
解决方案
我通过连接输出解决了这个问题:
merged_vector = concatenate([processed_a, processed_b, processed_c], axis=-1, name='merged_layer')
然后在我的损失函数中分解向量:
d1 = y_pred[:,0:128]
d2 = y_pred[:,128:256]
d3 = y_pred[:,256:384]
不过,我不确定这是否是最好的解决方案。
推荐阅读
- python - 如何将此代码应用于多个 csv?
- kubernetes - 用于 kube2iam 角色的 Cloudformation
- python - 如何在预训练的 VGG16 上训练 FCN 模型
- javascript - 不能在 tree.enumNodeFragments() 委托中使用全局变量
- r - 使用 R 从非 HTML 网站上抓取表格,但显示的示例适用于 HTML
- cmder - 有没有办法用cmder启动一个新选项卡的命令?
- python - Python:迭代将 cookie 从请求会话传输到 Selenium
- javascript - 为什么我的状态没有在使用 React.js 实现的示例中共享
- transactions - Hyperledger-Burrow,有没有办法将 miningreward 和 gasprice 设置为 0?
- azure - 在 Windows Server 版本 1803 中未激活 Hyper-V 隔离