首页 > 其他分享 >标签平滑

标签平滑

时间:2023-12-10 17:02:18浏览次数:24  
标签:right target 标签 self labels hot 平滑 size

标签平滑

目录

前言

Label Smoothing(标签平滑)是一种正则化的方法,用于减轻过拟合的影响。其应用场景必须具备以下几个要素:

  1. 标签必须是one-hot向量
  2. 损失函数是交叉熵损失函数

交叉熵损失

交叉熵损失是做分类任务里常用的一种损失,公式如下:

\[\text { loss }=-\sum_{i=1}^n y_i \log \left(x_i\right) \]

这里\(x_{i}\)表示的是模型输出的logits后经softmax的结果,shape为($ N,M
\(),\)y_{i}$表示的是真实标签,通常用one-hot编码表示。

将以上公式拆解,可分为如下几部分

  • \(log \left(x_i\right)\)** (log softmax)** ​

    即softmax后取对数,公式如下

    \[\sum_{i=1}^n \log \left(\frac{\exp \left(x_i\right)}{\sum_{i=1}^n\left(\exp \left(x_i\right)\right)}\right) \]

  • NLL Loss

    全称为Negative log-likelihood(负对数似然损失),即

    \[L(\theta)=-\sum_i^n \log \left(P\left(x_i ; \theta\right)\right) \]

由于求loss的时候,采用了one-hot编码,除去当前类别为1其余都为0,所以有:

\[L(\theta)=-\log \left(P\left(x_i ; \theta\right)\right) \]

这个形式和CrossEntropyLoss一致。

最终在训练网络时,为了达到最好的拟合效果,最优的预测概率分布为:

\[Z_i=\left\{\begin{array}{l} +\infty, \text { if }(i=y) \\ 0, \text { if }(i \neq y) \end{array}\right. \]

也就是说,网络会驱使自己往正确标签和错误标签差值最大的方向学习,在训练数据不足以表征所有样本特征的情况下,就会导致过拟合。

Label Smoothing

由于softmax的过拟合问题,即模型对于弱项的照顾很小。标签平滑就是为了降低softmax所带来的高Confiidence的影响,让模型略微关注到低概率分布的权重。这样做也有些影响,即最终的输出置信度会稍微低一些,需要细致的阈值过滤。

在Label Smoothing中,标签的编码不再单纯使用one-hot编码,而是用以下形式来表示:

\[y(i)= \begin{cases}\frac{\varepsilon}{n - 1}, & i \neq \text { target } \\ 1-\varepsilon & i=\text { target }\end{cases} \]

即用\(\frac{\varepsilon}{n - 1}\)来代替0,用\(1-\varepsilon\)来代替1。其中\(\varepsilon\)是预设的一个超参数,一般取0.1,\(n\)是该分类问题的类别个数。

代码实现

class LSR(nn.Module):

    def __init__(self, e=0.01,reduction='mean'):
        super().__init__()

        self.log_softmax = nn.LogSoftmax(dim=1)
        self.e = e
        self.reduction = reduction

    def _one_hot(self, labels, classes, value=1):
        """
            Convert labels to one hot vectors

        Args:
            labels: torch tensor in format [label1, label2, label3, ...]
            classes: int, number of classes
            value: label value in one hot vector, default to 1

        Returns:
            return one hot format labels in shape [batchsize, classes]
        """
        #print("classes", classes)
        one_hot = torch.zeros(labels.size(0), classes)

        # labels and value_added  size must match
        labels = labels.view(labels.size(0), -1)
        value_added = torch.Tensor(labels.size(0), 1).fill_(value)

        value_added = value_added.to(labels.device)
        one_hot = one_hot.to(labels.device)

        one_hot.scatter_add_(1, labels, value_added)

        return one_hot

    def _smooth_label(self, target, length, smooth_factor):
        """convert targets to one-hot format, and smooth
        them.

        Args:
            target: target in form with [label1, label2, label_batchsize]
            length: length of one-hot format(number of classes)
            smooth_factor: smooth factor for label smooth

        Returns:
            smoothed labels in one hot format
        """
        #print("length", length)
        #print("smooth_fact", smooth_factor)
        one_hot = self._one_hot(target, length, value=1 - smooth_factor)
        one_hot += smooth_factor / length

        return one_hot.to(target.device)

    def forward(self, x, target):

        if x.size(0) != target.size(0):
            raise ValueError('Expected input batchsize ({}) to match target batch_size({})'
                             .format(x.size(0), target.size(0)))

        if x.dim() < 2:
            raise ValueError('Expected input tensor to have least 2 dimensions(got {})'
                             .format(x.size(0)))

        if x.dim() != 2:
            raise ValueError('Only 2 dimension tensor are implemented, (got {})'
                             .format(x.size()))
        #print("x: ", x)
        #print("target", target)

        smoothed_target = self._smooth_label(target, x.size(1), self.e)
        x = self.log_softmax(x)
        loss = torch.sum(- x * smoothed_target, dim=1)
        if self.reduction == 'none':
            return loss

        elif self.reduction == 'sum':
            return torch.sum(loss)

        elif self.reduction == 'mean':
            return torch.mean(loss)

        else:
            raise ValueError('unrecognized option, expect reduction to be one of none, mean, sum')

可以看到这个代码和公式有些出入,上述代码公式可写为

\[y(i)= \begin{cases}\frac{\varepsilon}{n}, & i \neq \text { target } \\ 1-\varepsilon+\frac{\varepsilon}{n} & i=\text { target }\end{cases} \]

标签:right,target,标签,self,labels,hot,平滑,size
From: https://www.cnblogs.com/horolee/p/17892878.html

相关文章

  • Ubuntu网络标签消失,没有网络
    问题描述:在ubuntu18.04.5中,突兀网络连接器图标消失解决方法:sudoservicenetwork-managerstopsudorm/var/lib/NetworkManager/NetworkManager.statesudoservicenetwork-managerstartsudogedit/etc/NetworkManager/NetworkManager.conf打开NetworkManager.conf文件,......
  • Java中<where>和<if>标签的组合使用
     在Java中,并没有<where>和<if>标签的组合使用。这两个标签不是Java编程语言或Java标准库的一部分,它们可能是你所使用的特定框架或库提供的自定义标签。如果你正在使用某个特定的Java框架或模板引擎(如MyBatis、Thymeleaf等),这些框架或引擎可能提供了自定义标签,使得在代码中使用......
  • Vue 3中的路由跳转及在新标签页中打开链接
    前言在Vue3中,VueRouter是一个常用的路由管理库,它提供了一种简单而强大的方式来实现路由跳转和导航。本文将介绍如何在Vue3中设置路由跳转,并且重点讨论如何在新标签页中打开链接。步骤一:安装VueRouter首先,我们需要安装VueRouter。在命令行中执行以下命令:npminstallvue-ro......
  • Java中<where>和<if>标签的组合使用
    在Java中,并没有<where>和<if>标签的组合使用。这两个标签不是Java编程语言或Java标准库的一部分,它们可能是你所使用的特定框架或库提供的自定义标签。如果你正在使用某个特定的Java框架或模板引擎(如MyBatis、Thymeleaf等),这些框架或引擎可能提供了自定义标签,使得在代码中使用类似于<......
  • HTML中title标签的使用
    HTML中的title标签是非常重要的标签之一,它用来描述网页的标题。在搜索引擎优化中,title标签是非常关键的,因为搜索引擎会将title标签中的文字作为页面的主要描述,并根据其相关性来判断网页内容的质量和权重。本文将详细讲解title标签的使用,包括以下内容:@[toc]##1.title标签的基本用......
  • mybatis解析settings标签
    settings标签也是一个很重要的标签,虽然我们在使用的时候,没怎么配置settings标签里面的内容。好像一开始为了看sql语句,我们在settings标签里面配置了日志。<settings><settingname="logImpl"value="SLF4J"/></settings>其他的好像就没干什么了。其实settings标签......
  • HTML列表标签学习
    一、有序列表例子:<ol> <li>苹果</li> <li>梨子</li></ol>其中有序列表可以有不同的排序方式:<h4>大写字母列表:</h4><oltype="A"><li>Apples</li><li>Bananas</li><li>Lemons</li><li>......
  • Java登陆第二十天——HTML常用标签
    文本标签文本常用的HTML标签:标签名标签描述<h1></h1>标题标签<h6></h6>标题标签<p></p>段落标签<hr>换行标签<br>换行标签标签栗子:<!DOCTYPEhtml><htmllang="en"><head><metacharset=&quo......
  • Chrome浏览器对不同标签页进行着色
    方法1:使用标签组Chrome浏览器的标签组功能允许您将标签分组在一起,并为每个组分配不同的颜色。要创建标签组,请右键单击一个标签,然后选择“添加到新组”。您还可以将标签拖放到另一个标签上以将其添加到组中。要更改标签组的颜色,请单击标签组的圆点,然后选择“更改颜色”。您可以......
  • vue 的标签内属性的各使用形式
    标签内属性形式在Vue中,v-xx、@xx和:xx是不同的语法形式,具有不同的用途和语义v-xx形式:这是用于注册或使用Vue提供的内置指令或自定义指令。v-是Vue指令的前缀,后面跟着指令的名称例如,内置指令:v-if可以根据条件控制元素的显示和隐藏,v-for可以用于循环渲染列表,......