代码之家  ›  专栏  ›  技术社区  ›  Raven Cheuk

在Keras层内实现三重态损耗

  •  3
  • Raven Cheuk  · 技术社区  · 7 年前

    post ,他在Kears层外实现了三重损失。他得到了 anchor_out , pos_out neg_out triplet_loss() 他定义的功能。

    我想知道我是否可以通过定义自己的三重态损耗来计算Keras层中的三重态损耗 Lambda 层。

    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.最大值() 函数发出错误。

    我的问题是,如何解决这个错误? 我试过换新的 0 具有 K.constant(0,shape=(1,)) K.constant(0,shape=(None,1))

    1 回复  |  直到 7 年前
        1
  •  5
  •   Kota Mori    7 年前

    这有用吗?

    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

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