摘要

交叉熵是深度学习中非常常用的一种损失,通过交叉熵学到的特征表示会有比较大的类内的多样性。因为传统的softmax损失优化的是类内和类间的差异的最大化,也就是类内和类间的距离(logits)的差别的最大化,没有办法得到表示类别的向量表示来对类内距离进行正则化。之前的方法都是想办法增加类内的内聚性,而忽视了不同的类别之间的关系。本文提出了Radial Basis Function(RBF 径向基函数)距离来代替原来的softmax中的内积,这样可以自适应的给类内和类间距离施加正则化,可以得到更好的表示类别的向量,从而提高性能。

介绍

在使用交叉熵损失进行分类的时候,一般我们会将样本通过一个卷积神经网络,得到样本的特征表示,然后在来决定样本的类别标签。确定类别标签的时候,我们先计算样本表示向量和表示类别的向量的距离,得到logits,一般来说,距离的度量方式包括内积,余弦以及欧式距离,都可以用来得到logits,在很多现有方法中,得到的logits会进行softmax的归一化,得到每个类别的概率。
欧式距离是一种很常用的相似性度量方法,而且具有很清晰的几何意义。但是,现有的基于softmax的方法并不是直接去优化欧式距离,而是优化类内和类间的相对差别。对比损失和三元组损失则是直接去优化欧式距离,也得到了很好的效果,但是需要比较麻烦的样本挖掘方法,而且比较不容易收敛,所以,无法完全取代传统的softmax损失。
本文的贡献有:

1、讨论了传统的softmax的主要缺陷。

2、提出了RBF softmax的方法来解决传统softmax的问题。

3、通过实验证明了RBF softmax在分类上的有效性。

在mnist数据集中各种softmax的特征可视化如下:
在这里插入图片描述

2 方法

2.1softmax交叉熵损失以及Prototype的分析

传统的softmax交叉熵损失的计算方式为:
在这里插入图片描述
其中,   f i j \ f_{ij}  fij 表示样本   x i \ x_{i}  xi与类别特征   w j \ w_{j}  wj的相似度,当   j = y i \ j =y_i  j=yi时,表示的就是   x i \ x_{i}  xi与其对应的类别的特征   W j \ W_{j}  Wj的相似度,也就是说类内的sample-prototype距离,在文中我们叫做类内的logit。对应的,   j ≠ y \ j \neq y  j=y的时候叫做logit,在度量相似度的时候,常常会用内积和欧式距离。

在softmax损失中,prototype可以看做是一个特定类别的所有样本的代表,直觉上,这个理想的prototype应该在该类别的所有样本的特征向量的几何中心上。因此,prototype需要非常显著的表达能力,包括两个方面。
1、Prototype应该具有显著的区别不同类别的样本的能力。类间的距离需要大于类内的距离。

2、Prototype应该可以显示出类别之间的关系,也就是说相似的类别应该比差别明显的类别靠的更近。

图2中描述了这两个方面:
在这里插入图片描述

从a中可以看到,黑点是类别的prototype,各种颜色的圆点是样本的特征,相似的类别的特征和prototype是可分的,但是距离相比明显有区别的类别要更靠近一些。b是训练刚开始的阶段。c是训练的后期。

最后的特征分布非常依赖于使用的损失函数。softmax的logit的计算方法会导致两种缺陷。
训练的开始会有损失分配的偏差。 因为刚开始训练的时候,特征   x i \ x_i  xi和prototype   W y j \ W{yj}  Wyj并不能很好的表示他们之间的相似度,我们希望给样本的损失一些约束,以免受到离群点较大的负面影响。如图2(b)。表1显示了在训练开始的时候,样本的类内距离具有很大的多样性。最终,这种由偏差的损失会导致类别的prototype之间的显著的偏差,并影响真实的特征分布。
在这里插入图片描述

2.2 RBF-Softmax损失函数

为了解决上面的两个问题,我们提出了一个距离,叫做Radial Basis Function kernel distance(RBF-score),用来度量   x i \ x_i  xi   W j \ W_j  Wj之间的相似度。
在这里插入图片描述
其中,   d i j \ d_{ij}  dij   x i \ x_i  xi   W j \ W_j  Wj之间的欧式距离,   γ \ \gamma  γ是超参数。相比于无界的内积和欧式距离,RBF-score在欧式距离变大的时候会衰减,其值域是0到1,RBF-score很好的度量了   x i \ x_i  xi   w j \ w_j  wj之间的相似度,可以用作softmax中的logit。我们这样定义RBF-Softmax:
在这里插入图片描述
其中,s是超参数,用来扩张RBF-score的尺度。
我们在看下RBF-Softmax是如何克服上面的两个问题的。
刚开始训练的时候,我们需要平衡类内的logits,而开始的时候,类内的logits往往会比较大,我们通过RBF kernel可以将非常大的欧式距离映射成相对小的RBF-score,这样就显著的较小了类内的多样性。这样的话,训练的开始阶段,类内的偏差就会显著的变小。另一方面,在训练的后期,传统的softmax给出的概率很容易就可以到1,但是用RBF的概率很难到1,这样可以持续的进行优化。
超参数的影响。 我们看下不同的超参数   γ \ \gamma  γ,s对训练的影响,如下图。
在这里插入图片描述
图3(a)中,当   γ \ \gamma  γ变大的时候,RBF-score也会变大,样本及其对应的prototype的相似度也会变大,优化任务变得简单。图3(b)©显示了不同的s下将欧式距离和RBF-score映射到概率的表现。s控制了概率的范围以及分类任务的难易程度,对于固定的欧式距离和RBF-score,小的s导致了概率的狭窄的范围,使得分类任务变得困难。从梯度的角度也能得到相似的结论,RBF-score和s决定了梯度的大小。
在这里插入图片描述

实现

3.1 Prototype的探索实验

图4显示了WordNet上的不同类别的prototype的相似度矩阵。
在这里插入图片描述
由上图可以看出,RBF-softmax得到的相似矩阵比wordNet的相似矩阵更加类似。
表2显示了两种不同的指标
在这里插入图片描述

MNIST上的探索实验

不同超参下的准确率
在这里插入图片描述
不同loss的准确率:
在这里插入图片描述

CIFAR-10/100上的实验

不同损失函数的准确率:
在这里插入图片描述
在这里插入图片描述

ImageNet的实验

在这里插入图片描述

实现

pytorch实现
https://github.com/2han9x1a0release/RBF-Softmax/blob/master/pycls/losses/rbflogit.py

import torch.nn as nn
import torch


class RBFLogits(nn.Module):
    def __init__(self, feature_dim, class_num, scale, gamma):
        super(RBFLogits, self).__init__()
        self.feature_dim = feature_dim
        self.class_num = class_num
        self.weight = nn.Parameter( torch.FloatTensor(class_num, feature_dim))
        self.bias = nn.Parameter(torch.FloatTensor(class_num))
        self.scale = scale
        self.gamma = gamma
        nn.init.xavier_uniform_(self.weight)
    def forward(self, feat, label):
        diff = torch.unsqueeze(self.weight, dim=0) - torch.unsqueeze(feat, dim=1)
        diff = torch.mul(diff, diff)
        metric = torch.sum(diff, dim=-1)
        kernal_metric = torch.exp(-1.0 * metric / self.gamma)
        if self.training:
            train_logits = self.scale * kernal_metric
            # ###
            # Add some codes to modify logits, e.g. margin, temperature and etc.
            # ###
            return train_logits
        else:
            test_logits = self.scale * kernal_metric
            return test_logits

tensorflow实现


"""
RBF_softmax:Learning Deep Representative Prototypes with Radial Basis Function Softmax
交叉熵是深度学习中非常常用的一种损失,通过交叉熵学到的特征表示会有比较大的类内的多样性。因为传统的softmax损失优化的是类内和类间的差异的最大化,也就是类内和类间的距离(logits)的差别的最大化,没有办法得到表示类别的向量表示来对类内距离进行正则化。之前的方法都是想办法增加类内的内聚性,而忽视了不同的类别之间的关系。本文提出了Radial Basis Function(RBF)距离来代替原来的softmax中的內积,这样可以自适应的给类内和类间距离施加正则化,可以得到更好的表示类别的向量,从而提高性能。
github源码:https://github.com/2han9x1a0release/RBF-Softmax
主要参考实现:https://github.com/2han9x1a0release/RBF-Softmax/blob/master/pycls/losses/rbflogit.py

"""
 
# 以下是使用tensorflow重现RBF softmax
"""
以下是使用tensorflow重现RBF softmax
"""
 
 
import tensorflow as tf
 
 
class RBFSoftmax(tf.layers.Layer):
 
    def __init__(self, feature_dim, num_classes, scale, gamma):
        super(RBFSoftmax, self).__init__()
 
        self.feature_dim = feature_dim
        self.num_classes = num_classes
        self.scale = scale
        self.gamma = gamma
 
    def build(self, input_shape):
        # 代表着每个类都有一个类中心的向量,用来计算RBF score (也可以添加偏置bias)
        self.weight = tf.Variable(tf.truncated_normal(shape=(self.num_classes, self.feature_dims), stddev=0.02))
        # self.bias = tf.Variable([0] * self.num_classes)
        self.built = True
 
    def call(self, inputs, training=None):
        """ 计算RBF logits
        :param inputs: Tensor, shape:(batch, feature_dim)
        :return: Tensor, shape:(batch, num_classes)
        可以先经过若干层的dense层,再进行计算RBFSoftmax
        """
 
        diff = tf.expand_dims(self.weight, axis=0) - tf.expand_dims(inputs, axis=1)
        diff = tf.multiply(diff, diff)
        metric = tf.reduce_sum(diff, axis=-1)  # shape: (batch, num_classes)
        kernel_metric = tf.exp(-1.0 * metric / self.gamma)
        logits = self.scale * kernel_metric
        return logits
 
 
"""
使用样例demo: 
rbflogit = RBFSoftmax(...)
logits = rbflogit(inputs)
true_one_hot_labels = ...
losses = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=true_one_hot_labels, logits=logits)
loss = tf.reduce_mean(losses)
"""

参考链接

RBF-Softmax: Learning Deep Representative
Prototypes with Radial Basis Function Softmax

tensorflow 实现RBFSoftmax
https://blog.csdn.net/u010626747/article/details/108728038

RBF-Softmax:让模型学到更具表达能力的类别表示
https://blog.csdn.net/abcdefg90876/article/details/108688023

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐