我试图用Keras实现一个Siamese网络,我有两个输入数据,
X1形状:(10000,52) X2形状:(10000,600)
假设X1中的每个样本与X2中的样本相似。例如:X1 [0]类似于X2 [0]。因此,当两个输入合并时,我使用了“余弦相似度”。我试图使用以下代码:
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
return K.mean(y_true * K.square(y_pred) + (1 - y_true) * K.square(K.maximum(margin - y_pred, 0)))
left_branch = Sequential()
left_branch.add(Embedding(1000, 32, input_length=52))
left_branch.add(LSTM(64))
left_branch.add(Dense(256))
right_branch = Sequential()
right_branch.add(Embedding(1000, 32, input_length=600))
right_branch.add(LSTM(64))
right_branch.add(Dense(256))
merged = Merge([left_branch, right_branch], mode='cos',dot_axes=1)
final_model = Sequential()
final_model.add(merged)
final_model.summary()
x1 = np.random.randint(1000, size=(10000, 52))
x2 = np.random.randint(1000, size=(10000, 600))
y = np.ones((10000,),dtype=np.int)
final_model.compile(optimizer='adam', loss=contrastive_loss)
final_model.fit([x1, x2], y, nb_epoch=2, batch_size=32)
getoutput_t = K.function([merged.layers[0].layers[0].input], [merged.layers[0].layers[2].output])
getoutput_d = K.function([merged.layers[1].layers[0].input], [merged.layers[1].layers[2].output])
t1 = getoutput_t([x1])[0]
t2 = getoutput_d([x2])[0]
我的问题是:训练后,t1 [0]与t1 [1]非常相似,但与t2 [0]非常不同。我检查了t1和t2的输出,生成的输出很奇怪:
T1:
array([[-3.48182112e-01,6.57344190e-03,-6.75882818e-03, 4.11706511e-03,-2.41146213e-03,-1.14028137e-02, 2.49683809e + 00,-9.19755269e-03,-2.37327255e-02 ....]
[-3.48182231e-01,6.57369522e-03,-6.75880583e-03, 4.11719829e-03,-2.41167075e-03,-1.14026833e-02, 2.49683785e + 00,-9.19752941e-03,-2.37324722e-02,...] .......]])
t1 [0]几乎与t1 [1]相同,在t2也发现了同样的问题。
因此,我不得不担心:
我的Siamese型号有什么问题吗? (例如损失函数或图层设计)
到目前为止我没有负抽样,因此,目标值是“1”,这是问题吗?
答案 0 :(得分:1)
如果通过
目标值是“1”,这是问题吗?
你的意思是你没有负面/不相似的对,那么是的,这是一个问题。如果不是这种情况,请忽略本答复的其余部分。
源代码中引用的paper的第3页:
涉及不相对的LD的对比术语是至关重要的。 简单地在所有类似对的集合上最小化DW(X~1,X~2) 通常会导致崩溃的解决方案,因为DW和损失L 然后可以通过将GW设置为常数使其为。大多数以能源为主 模型要求在损失中使用明确的对比术语 功能
“对比术语”是指取决于负对的损失函数项。公式3中的L_D。请注意GW是从输入到输出向量的模型/映射。基本上,没有负对,学习者可以通过学习仅将输入向量映射到相同输出向量的平凡模型来达到其优化目标(其被简化为最小化相似/正对之间的距离)。
直观地说,对比度损失通过强制平衡最小化相似对之间的距离来帮助您找到最佳模型,同时使用GW中设置的相同参数最大化(达到边距)不同对之间的距离。
如果您没有负对,则可以尝试通过随机配对数据集中的元素来生成负对。
在Keras主要回购中有一个使用对比度损失的例子:
https://github.com/fchollet/keras/blob/master/examples/mnist_siamese_graph.py