Skip to main content
 首页 » 编程设计

python-3.x之在 Keras 层内实现三重损失

2025年01月19日13daizhj

在此博客 post ,他在 Kears 层之外实现了三重损失。他得到了 anchor_out , pos_outneg_out来自网络,然后将它们传递给 triplet_loss()他定义的函数。

我想知道是否可以通过定义我自己的 Lambda 来计算 Keras 层内的triplet_loss层。

这是我的网络设计:

margin=1 
 
anchor_input = Input((600, ), name='anchor') 
positive_input = Input((600, ), name='positive_input') 
negative_input = Input((600, ), name='negative_input') 
 
# Shared embedding layer for positive and negative items 
Shared_DNN = Dense(300) 
 
encoded_anchor = Shared_DNN(anchor_input) 
encoded_positive = Shared_DNN(positive_input) 
encoded_negative = Shared_DNN(negative_input) 
 
DAP = Lambda(lambda tensors:K.sum(K.square(tensors[0] - tensors[1]),axis=1,keepdims=True),name='DAP_loss') #Distance for Anchor-Positive pair 
DAN = Lambda(lambda tensors:K.sum(K.square(tensors[0] - tensors[1]),axis=1,keepdims=True),name='DAN_loss') #Distance for Anchor-Negative pair 
Triplet_loss = Lambda(lambda loss:K.max([(loss[0] - loss[1] + margin),0],axis=0),name='Triplet_loss') #Distance for Anchor-Negative pair 
 
DAP_loss = DAP([encoded_anchor,encoded_positive]) 
DAN_loss = DAN([encoded_anchor,encoded_negative]) 
 
#call this layer on list of two input tensors. 
 
Final_loss = Triplet_loss([DAP_loss,DAN_loss]) 
 
model = Model(inputs=[anchor_input,positive_input, negative_input], outputs=Final_loss) 

但是,它给了我错误:
Tried to convert 'input' to a tensor and failed. Error: Shapes must be equal rank, but are 2 and 0 
    From merging shape 0 with other shapes. for 'Triplet_loss_4/Max/packed' (op: 'Pack') with input shapes: [?,1], [] 

错误来自 Triplet_loss层。在 K.max()函数,第一个数字 loss[0] - loss[1] + margin有形状 (None,1) .然而第二个数字 0 的形状是 (1) .这两个数字的形状不同,因此 K.max()函数给出错误。

我的问题是,如何解决这个错误?
我试过更换 0K.constant(0,shape=(1,))K.constant(0,shape=(None,1)) ,但它们不起作用。

请您参考如下方法:

这行得通吗?

Triplet_loss = Lambda(lambda loss: K.maximum(loss[0] - loss[1] + margin, 0.0), 
                      name='Triplet_loss') 

我认为这条线的问题
Triplet_loss = Lambda(lambda loss:K.max([(loss[0] - loss[1] + margin), 0],  
                      axis=0),name='Triplet_loss')  

是你在放 loss[0]-loss[1]+margin张量和 0在列表括号中,keras 将其解释为连接两个张量。由于大小不匹配而失败; 0是一个标量,秩为 0,而第一个是二维数组。这就是错误的含义。

要将张量与单个值元素进行比较,请使用 K.maximum ,当其中一个参数是标量时自动广播。