Siamese Loss

版权声明: https://blog.csdn.net/u013841196/article/details/89877340

孪生网络中的Siamese Loss,来自Yann LeCun的论文《Learning a Similarity Metric Discriminatively, with Application to Face Verification》,最小化把相同类的数据之间距离,最大化不同类之间的距离
引入了siamese网络结构的思想,具体使用的网络形式完全可以自己定义
在这里插入图片描述
主要思想:
1、输入不再是单个样本,而是一对样本,不再给单个的样本确切的标签,而且给定一对样本是否来自同一个类的标签,是就是0,不是就是1
2、设计了两个一模一样的网络,网络共享权值W,对输出进行了距离度量,可以说l1、l2等。
3、针对输入的样本对是否来自同一个类别设计了损失函数,损失函数形式有点类似交叉熵损失:

在这里插入图片描述
最后使用获得的损失函数,使用梯度反传去更新两个网络共享的权值W。

注:损失函数中的 2 Q e 2.77 Q E w 2Qe^{-\frac{2.77}{Q}E_{w}} ,可以用hinge loss代替。

优点: Siamese网络是一种相似性度量方法。传统的用于区分的分类方法是需要确切的知道每个样本属于哪个类,需要针对每个样本有确切的标签。而且相对来说标签的数量是不会太多的。当类别数量过多,每个类别的样本数量又相对较少的情况下,这些方法就不那么适用了。其实也很好理解,对于整个数据集来说,我们的数据量是有的,但是对于每个类别来说,可以只有几个样本,那么用分类算法去做的话,由于每个类别的样本太少,我们根本训练不出什么好的结果,所以只能去找个新的方法来对这种数据集进行训练,从而提出了siamese网络。siamese网络从数据中去学习一个相似性度量,用这个学习出来的度量去比较和匹配新的未知类别的样本。这个方法能被应用于那些类别数多或者整个训练样本无法用于之前方法训练的分类问题。

代码实现:

#注:label=1,同一人;label=0,不同人。
def siamese_loss(model1, model2, y):
    # L(W,Y,X1,X2) = Y*2/Q*||CNN(p1i)-CNN(p2i)||^2 + (1-Y)*2*Q*exp(-2.77/Q*||CNN(p1i)-CNN(p2i)||
    margin = 5.0
    Q = tf.constant(margin, name="Q", dtype=tf.float32)
    E_w = tf.sqrt(tf.reduce_sum(tf.square(model1 - model2),1))
    pos = tf.multiply(tf.multiply(tf.to_float(y), 2/Q), tf.square(E_w))
    neg = tf.multiply(tf.multiply(tf.to_float(1-y),2*Q),tf.exp(-2.77/Q*E_w))
    loss = pos + neg
    loss = tf.reduce_mean(loss, name="loss")
    return model1, model2, loss

注:博众家之所长,集群英之荟萃。

猜你喜欢

转载自blog.csdn.net/u013841196/article/details/89877340