美文网首页机器学习
Label smoothing 标签平滑

Label smoothing 标签平滑

作者: 西北小生_ | 来源:发表于2019-10-19 22:00 被阅读0次

    Label smoothing是机器学习中的一种正则化方法,其全称是 Label Smoothing Regularization(LSR),即标签平滑正则化。其应用场景必须具备以下几个要素:

    1. 标签是one-hot向量
    2. 损失函数是交叉熵损失函数。
      其作用对象是真实标签,如果将其视为一个函数,即 LSR(grandtruth_targets)。

    为了说明这个方法的作用,我们追溯一下真实标签的使用场景。

    在神经网络训练中,真实标签主要用于两个方面:1)计算loss; 2)计算accuracy。
    计算accuracy时只拿真实标签值和预测索引值做比较,如果二者相等,则说明预测准确,此时真实标签并不参与计算。
    计算loss时,用到的交叉熵损失函数如下:
    Loss = -\sum_{i=1}^n y_{grandtruth}log(y_{inference})
    其中y_{grandtruth}就是本文的主角——真实标签,其为one-hot向量形式,y_{inference}是经softmax层输出的预测概率。可以看出,损失函数只与预测值和真实值有关,所以此处真实值的形式和数值大小对损失函数的计算影响非常大

    常用的真实标签的形式是one-hot向量,其值非0即1,计算Loss时如果是1,Loss中该项的log(y_{inference})就得到保留;如果是0,该项的log(y_{inference})就彻底抛弃。即:
    Loss=0×log(y_1) + 0×log(y_2) + ··· + 1×log(y_i)+ ··· +0×log(y_n)
    这样就使得模型过分相信标签的标注,只要是标签为1的项就保留,标签为0的项就统统抛弃,那万一标签标注错了岂不是错杀好人?标签是人为标注的,如果人在标注的时候一个不留神标错了,而模型的判决又“充分”信任人为标注的标签,它作为模型判断保留或丢弃某项数据的标准,这就会使错误标签在模型训练中产生较大的影响。

    标签平滑做的工作就是使真实标签不那么极端化,给予标签一定的容错概率。思想如下:

    对照上面计算Loss的交叉熵公式,真实标签y_{grandtruth}可视作加在预测值log(y_{inference})上的权重,也即模型用来评判保留或丢弃某项预测信息的概率,按one-hot形式的标签,模型只保留标签为1对应的log(y_{inference})中的值。

    我们假设标签有\epsilon的概率标注出错,即某个标签为真的概率为1-\epsilon,那其它为假的项也有\epsilon的概率是真,所以计算Loss时原来标签为0的值对应的log(y_{inference}0)项不应该完全抹杀,也要以\epsilon的概率保留下来,即\epsilon * log(y_{inference}0)

    在多分类任务中(假设有n类),我们用1-\epsilon来标记真实类别; 其余n-1项共同拥有\epsilon的概率标记出错,这里假设这n-1项服从均匀分布,即标记出错的概率与样本类别无关,所以每一项出错的概率为\frac{\epsilon}{n-1}

    此时的标签形式为:

    y'_{grandtruth}=[\frac{\epsilon}{n-1}, \frac{\epsilon}{n-1},1-\epsilon, \frac{\epsilon}{n-1},...,\frac{\epsilon}{n-1}]
    即用\frac{\epsilon}{n-1}替换0,用1-\epsilon代替1。其实在实际的实现中,分母直接采用类别数量n,而不是n-1。

    Loss为:

    Loss = -\sum_{i=1}^n y'_{grandtruth}log(y_{inference})
    这样,就使得预测的所有信息都得到一定程度的保留,提高了模型对标记错误的数据的容忍度,提高了模型的泛化能力。

    以下举一个例子阐述个人的理解,如果出错还望指出。

    在模型训练时,标签在引导模型的预测不断接近自己的标准,即如果预测值和标签一致,loss就会减小,否则增大。Loss变大则梯度\frac{dL}{dW}变大,梯度变大则参数更新幅度变大。举个例子:

    如果模型的预测值为: [0.1 0.6 0.2 0.1]
    而标注的one-hot标签为:[0 1 0 0]
    此时Loss=-ln(0.6)=0.51
    采用LSR时假设\epsilon=0.1,则标签为[\frac{0.1}{3}, 0.9, \frac{0.1}{3}, \frac{0.1}{3}]
    此时Loss=-\frac{0.1}{3}×ln(0.1)-0.9×ln(0.6)-\frac{0.1}{3}×ln(0.2)-\frac{0.1}{3}×ln(0.1)=0.67

    如果标签错误标注成了[0 0 1 0],此时模型的预测其实是对的,只是标签被人为标注错了,
    此时Loss=-ln(0.2)=1.61
    采用LSR时的标签为[\frac{0.1}{3}, \frac{0.1}{3}, 0.9, \frac{0.1}{3}]
    Loss=-\frac{0.1}{3}×ln(0.1)-\frac{0.1}{3}×ln(0.6)-0.9×ln(0.2)-\frac{0.1}{3}×ln(0.1)=1.62

    在这种情况下,如果采用one-hot标签,那么两种情况的Loss差距为 1.61-0.51=1.1
    如果采用LSR标签,则两种情况的差距为 1.62-0.67=0.95
    这种情况通俗的讲就是,在one-hot形式下,本来参数应该前进5步,却前进了16步,多前进了11步,离最优值距离进一步拉大。
    在LSR形式下,参数本应前进7步,却因为一个人为的错误前进了16步,多前进了9步,虽然离最优值的距离也拉大了,但相比one-hot,它犯错误的程度减小了,就好比同样是做错题,一个做错了11道,一个做错了9道。即LSR将错误标签对模型训练产生的反面影响降低了,进而提高了模型泛化能力。

    在应用中,\epsilon的常用值为0.1

    其代码实现如下:

    def label_smoothing(inputs, epsilon=0.1):
        K = inputs.get_shape().as_list()[-1]    # number of channels
        return ((1-epsilon) * inputs) + (epsilon / K)
    

    输入参数inputs是one-hot形式的真实标签。

    在tensorflow中,标签平滑已经封装在了

    tf.losses.softmax_cross_entropy(onehot_labels=new_onehot_labels, logits=out, label_smoothing=0)
    

    函数中,设置其中的label_smoothing的值(\epsilon)即可。

    Pytorch中标签平滑的应用场景不多,需要自行构建函数,因为pytorch中常采用的标签就是0,1,2,3,4……形式的,并非one-hot向量,计算loss时常用的损失函数的输入值也直接是网络的预测值(logits)和0,1,2,3,4……形式的真实值标签,而不是softmax输出值和one-hot标签,损失函数内部会自动将标签转换为one-hot向量进行计算。pytorch实现LSR的方法待更……

    相关文章

      网友评论

        本文标题:Label smoothing 标签平滑

        本文链接:https://www.haomeiwen.com/subject/clbnyctx.html