Center Loss

版权声明: https://blog.csdn.net/u013841196/article/details/89885167
  • Center Loss
    Wen Y, Zhang K, Li Z, et al. A discriminative feature learning approach for deep face recognition [C]// ECCV, 2016.

卷积神经网络的典型框架:
在这里插入图片描述
Center Loss的目的是关注类内分布的均匀性,想让其绕类内中心均匀分布,最小化类内差异,公式如下:
在这里插入图片描述
整体的损失函数:Softmax Loss (保证类之间的feature距离最大)与 Center Loss (保证类内的feature距离最小,更接近于类中心)
在这里插入图片描述
给每个label的数据定义一个center,大家要向center靠近, c y i c_{y_{i}} 表示 y i y_{i} 类别的特征中心。

c怎么定义呢?
batch训练的时候不断地计算更新它,每一轮计算一下当前数据和center的距离,然后把这个距离梯度叠加到center上:
在这里插入图片描述
每个batch的数据并不算多,这样更新会不会容易center产生抖动?
于是作者简单粗暴加了一个scale,让它不要太大:
在这里插入图片描述
这个scale肯定是小于1的。

计算流程如下(当λ=0时,就变成softmax loss):
在这里插入图片描述
Center的更新:
在这里插入图片描述
训练效果如下所示:
在这里插入图片描述
Center loss 实现:
1)定义每个类别的初始特征中心

with tf.variable_scope('center'):
centers = tf.get_variable('centers', [FLAGS.embedding_size, 512], dtype=tf.float32,\
        initializer=tf.constant_initializer(0), trainable=False)

2)更新batch_size中不同类别的特征中心和计算center loss损失

def update_centers(features, labels, alpha):
    with tf.variable_scope('center', reuse=True):
        centers = tf.get_variable('centers')
    
    labels = tf.reshape(labels, [-1])
    print(labels)
    centers_batch = tf.gather(centers, labels)
    print(centers_batch)
    loss = tf.reduce_mean(tf.reduce_sum((features - centers_batch) ** 2, [1]))
    diff = centers_batch - features

    # 获取一个batch中同一样本出现的次数,这里需要理解论文中的更新公式
    unique_label, unique_idx, unique_count = tf.unique_with_counts(labels)
    appear_times = tf.gather(unique_count, unique_idx)
    appear_times = tf.reshape(appear_times, [-1, 1])

    diff = diff / tf.cast((1 + appear_times), tf.float32)
    diff = alpha * diff
    # 更新中心
    centers = tf.scatter_sub(centers,labels, diff)
    return centers, loss

引用函数:
tf.gather(等待被取元素的张量,索引)
tf.gather根据索引,从输入张量中依次取元素,构成一个新的张量。

tf.unique_with_counts函数
tf.unique_with_counts(
x,
out_idx=tf.int32,
name=None
)
在一维张量中找到唯一的元素。
该操作返回一个张量 y,该张量包含出现在 x 中的以相同顺序排序的 x 的所有的唯一元素。此操作还会返回一个与 x 具有相同大小的张量 idx,包含唯一的输出 y 中 x 的每个值的索引。最后,它返回一个包含第三个张量 count,其中包含 x 中 y 的每个元素的计数,即:
y[idx[i]] = x[i] for i in [0, 1,…,rank(x) - 1]
例如:

# tensor 'x' is [1, 1, 2, 4, 4, 4, 7, 8, 8]
y, idx, count = unique_with_counts(x)
y ==> [1, 2, 4, 7, 8]
idx ==> [0, 0, 1, 2, 2, 2, 3, 4, 4]
count ==> [2, 1, 3, 1, 2]
函数参数:
x:一个 Tensor,是 1-d 的。
out_idx:可选的 tf.DType 来自:tf.int32, tf.int64;默认为 tf.int32。
name:操作的名称(可选)。
函数返回值:
Tensor 对象的元组(y,idx,count)。
y:一个 Tensor,与 x 类型相同。
idx:一个 out_idx 类型的 Tensor。
count:一个 out_idx 类型的 Tensor。

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

猜你喜欢

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