python - 尝试重新配置在三元组上训练的连体网络以对对进行操作时出现 ValueError
问题描述
我的问题
我正在尝试[anchor_input, similar_input, different_input]
在 Keras中实现一个 Siamese 网络,该网络经过三元组训练——并成对执行——[input_a, input_b]
告诉我它们是相似还是不同。我能够很好地训练三元组,甚至已经训练和测试了对,但是当我训练三元组并尝试创建我的成对网络时,我收到以下错误:
ValueError:logits 和标签必须具有相同的形状 (() vs (?, ?))
当前网络概览
我的三元组网络是使用以下代码定义的,对于本示例,我已将其缩减为非常小的内容:
def siamese_triplet(in_shape, feature_dim):
input_a = Input(shape=in_shape) # input is a series, n_samples by n_features
input_b = Input(shape=in_shape)
input_c = Input(shape=in_shape)
base_network = create_model() # makes my Siamese kernel network
processed_a = base_network(input_a) # base_network outputs a vector, say 50 elements long
processed_b = base_network(input_b)
processed_c = base_network(input_c)
l1_distance = lambda x: K.abs(x[0] - x[1]) # vector, 50 elements long
p_distance = Lambda(l1_distance,
output_shape=lambda x: x[0])([processed_a, processed_b])
n_distance = Lambda(l1_distance,
output_shape=lambda x: x[0])([processed_a, processed_c])
triplet_loss = Lambda(lambda x: K.mean(K.maximum(0, x[0] - x[1] + 1)),
output_shape=(1,))([p_distance, n_distance]) # scalar
model = Model([input_a, input_b, input_c], triplet_loss)
optimizer = SGD()
model.compile(optimizer=optimizer,
loss=lambda x, y: y) # passes triplet loss through
我训练网络并得到一个合适的model
对象。然后,我尝试使用围绕输入对构建的结构重新创建网络,并将base_network
从 my 中提取的层传递给它model
,最终结果是model.layers[3]
:
# triplet_net = siamese_triplet(...)
# model = triplet_net.fit(...)
pair_net = siamese_pair(input_shape, model.layers[3])
siamese_pair
定义为:
def siamese_pair(in_shape, base_network):
input_a = Input(shape=in_shape)
input_b = Input(shape=in_shape)
processed_a = base_network(input_a) # vector, 50 elements
processed_b = base_network(input_b)
distance = Lambda(lambda x: K.abs(x[0] - x[1]),
output_shape=lambda x: x[0])([processed_a, processed_b]) # vector, 50 elements
prediction = Lambda(lambda x: K.mean(x),
output_shape=(1,))(distance) # scalar
model = Model([input_a, input_b], prediction)
optimizer = SGD()
model.compile(optimizer=optimizer,
loss='binary_crossentropy') # for evaluation purposes
该model.compile(...)
行引发错误。
请注意,对于相同的对象(类),三元组损失应该将距离推向接近零,对于0
不同的对象(类),将它们推向 1 1
,因此设置prediction = K.mean(distance)
应该非常接近这些类标签之一,我会思考。
我从三元组损失训练到成对评估的过渡对我来说似乎有点笨拙,我很想找出最好的方法,所以我愿意接受改进设计的建议。同时,我很高兴能克服这个错误,这样我至少可以运行并评估我的性能,将输入对分类为相似或不同。
我的问题
- 为什么我会收到上述错误?似乎对损失函数完全没有期望
y_true
,这对我来说很奇怪。 - 如何解决上述错误?
- 有没有更好的方法可以将我的训练传递
base_layer
到不同的连体网络结构中? base_layer
有没有更好的方法可以从我接受不同网络结构的训练中获得成对预测?
只回答前两个会很好,但如果有人对后两个也有建议,我会全神贯注。
解决方案
推荐阅读
- python - 是否可以从条目小部件或文本小部件在树视图中插入多行文本?或类似的东西?
- c# - 自定义调整窗口大小
- python - Python Tkinter 应用程序将焦点从打开的文件夹中移开
- javascript - 如何条带化 HTML标记并将其替换为
? - macos - macOS (AppKit/SwiftUI) 中的自定义对象全选/取消选择菜单项
- c# - 如何在 .NET Core 中使用依赖注入注册多个项目?
- django - django 数据库的初始动态数据
- python - tkinter 将第二帧放在顶层
- rust - try_lock 在异步之外的 futures::lock::Mutex 上?
- javascript - 点倍增 (P -> 2P) Secp256k1 椭圆曲线的基点