精华内容
下载资源
问答
  • PyTorch 分类损失函数

    千次阅读 2020-03-05 00:01:00
    PyTorch提供了丰富的损失函数,而分类任务用到最多的就是nn.CrossEntropyLoss和nn.NLLLoss了,不妨讨论一下。 nn.CrossEntropyLoss CrossEntropy顾名思义就是交叉熵,概念来自香农的信息论,用于度量两个概率...

    PyTorch提供了丰富的损失函数,而多分类任务用到最多的就是nn.CrossEntropyLossnn.NLLLoss了,不妨讨论一下。

    nn.CrossEntropyLoss

    CrossEntropy顾名思义就是交叉熵,概念来自香农的信息论,用于度量两个概率分布间的差异性信息,可以认为是在给定的真实分布下,使用非真实分布的策略消除系统的不确定性所需要付出的努力的大小。交叉熵越小,证明计算出的非真实分布越接近真实分布。

    公式如下:

    H(p,q)=−∑k=1N(pk∗logqk)H(p,q)=−∑k=1N(pk∗logqk)

    在PyTroch的文档中明确指出它和nn.NLLLoss之间的关系,后面我们会进行测试。

    This criterion combines nn.LogSoftmax() and nn.NLLLoss() in one single class.

    nn.NLLLoss

    全名是负对数似然损失函数(Negative Log Likelihood),在PyTorch的文档中有如下说明:

    Obtaining log-probabilities in a neural network is easily achieved by adding a LogSoftmax layer in the last layer of your network. You may use CrossEntropyLoss instead, if yo

    展开全文
  • pytorch多损失回传案例

    2021-05-24 17:19:39
    一个输入两个输出的全连接网络 import torch import torch.nn as nn import torch.nn.functional as F class LinearNet(nn.Module): def __init__(self): super(LinearNet, self).__init__() self.fc1...多损失回传机制
    1. 一个输入两个输出的全连接网络
    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    
    
    class LinearNet(nn.Module):
        def __init__(self):
            super(LinearNet, self).__init__()
            self.fc1 = nn.Linear(5, 4)
            self.fc2 = nn.Linear(4, 3)
            self.fc3 = nn.Linear(4, 3)
    
        def forward(self, x):
            mid = self.fc1(x)
            out1 = self.fc2(mid)
            out2 = self.fc3(mid)
            return out1, out2
    
    
    x = torch.randn((3, 5))
    y = torch.torch.randint(3, (3,), dtype=torch.int64)
    model = LinearNet()
    model.train()
    optim = torch.optim.RMSprop(model.parameters(), lr=0.001)
    
    print(model.fc2.weight)
    print(model.fc3.weight)
    for i in range(5):
        out1, out2 = model(x)
        loss1 = F.cross_entropy(out1, y)
        loss2 = F.cross_entropy(out2, y)
        loss = 0*loss1 + 1*loss2
        optim.zero_grad()
        # loss1.backward(retain_graph=True)
        # loss2.backward()
        # print(loss)
        loss.backward()
        optim.step()
    print("-------------after-----------")
    print(model.fc2.weight)
    print(model.fc3.weight)
    

    多分支网络图
    上述代码是一个简单的双分支输出的全连接网络,可以通过控制loss1和loss2的权重分别去控制每个输出对网络的梯度影响。如果loss1或者loss2的权重设置为0则该损失所影响的部分梯度不再更新。
    2. 一个输入两个输出的卷积网络

    import torch
    from torch.autograd import Variable
    import torch.nn as nn
    import torch.nn.functional as F
    class Net(nn.Module):
        def __init__(self):
            #使用super()方法调用基类的构造器,即nn.Module.__init__(self)
            super(Net,self).__init__()
            # 1 input image channel ,6 output channels,5x5 square convolution kernel
            self.conv1=nn.Conv2d(1,6,5)
            # 6 input channl,16 output channels,5x5 square convolution kernel
            self.conv2=nn.Conv2d(6,16,5)
            self.conv3 = nn.Conv2d(6, 16, 5)
            # an affine operation:y=Wx+b
            # self.fc1=nn.Linear(16*5*5,120)
            # self.fc2=nn.Linear(120,84)
            # self.fc3=nn.Linear(84,10)
        def forward(self,x):
            # x是网络的输入,然后将x前向传播,最后得到输出
            # 下面两句定义了两个2x2的池化层
            x=F.max_pool2d(F.relu(self.conv1(x)),(2,2))
            # if the size is square you can only specify a single number
            x1=F.max_pool2d(F.relu(self.conv2(x)),2)
            x2 = F.max_pool2d(F.relu(self.conv3(x)), 2)
            # x=x.view(-1,self.num_flat_features(x))
            # x=F.relu(self.fc1(x))
            # x=F.relu(self.fc2(x))
            # x=self.fc3(x)
            return x1,x2
        def num_flat_features(self,x):
            size=x.size()[1:] # all dimensions except the batch dimension
            num_features=1
            for s in size:
                num_features*=s
            return num_features
    if __name__ == '__main__':
    
        net=Net()
        print(net)
        net.train()
        optim = torch.optim.RMSprop(net.parameters(), lr=0.001)
        x = Variable(torch.randn(1, 1, 64, 64))
        # y1,y2 = net(x)
        y = Variable(torch.randn(1, 16, 13,13))
        # print(y)
        # print(y1.shape,y2.shape)
        print(net.conv2.weight)
        print(net.conv3.weight)
        mseloss = torch.nn.MSELoss()
        for i in range(4):
            y1, y2 = net(x)
            print(y1[0].shape,y.shape)
            loss1 = mseloss(y1,y)
            loss2 = mseloss(y2,y)
            loss = 0*loss1 + 1 * loss2
            optim.zero_grad()
            # loss1.backward(retain_graph=True)
            # loss2.backward()
            # print(loss)
            loss.backward()
            optim.step()
        print("-------------after-----------")
        print(net.conv2.weight)
        print(net.conv3.weight)
    

    上述代码是一个简单的双分支输出的卷积神经网络,与全连接网络类似,该网络也可以通过控制loss1和loss2的权重分别去控制每个输出对网络的梯度影响。而且通过加权计算的loss统一进行梯度回归计算出的值和loss1和loss2分别进行梯度回归计算出的值大小是一致的。
    参考链接,我是参考这个博主的资料的,感谢该博主。多损失回传机制

    展开全文
  • pytorch笔记】损失函数nll_loss

    千次阅读 2020-06-07 16:12:26
    本文主要讲解在使用pytorch中对损失函数`nll_loss`的一些理解与思考。

    使用场景

    在用pytorch做训练、测试时经常要用到损失函数计算输出与目标结果的差距,例如下面的代码:

    # 训练
    for batch_idx, (data, target) in enumerate(train_loader):
    	data, target = data.to(device), target.to(device)
    	optimizer.zero_grad()
    	output = model(data)
    	loss = F.nll_loss(output, target)
    	loss.backward()
    	optimizer.step()
    # 测试
    for data, target in test_loader:
    	data, target = data.to(device), target.to(device)
    	output = model(data)
    	test_loss += F.nll_loss(output, target, reduction = 'sum')
    

    前一部分是训练过程,计算输出outputtarget的误差回传,后一部分是测试过程,计算outputtarget误差,并进行误差求和。

    函数理解

    在该函数中重要的参数主要有三个,分别是:

    • input: ( N , C ) (N,C) (N,C),其中C表示分类的数量,N表示数据的条数,由于数据的输入是按batch输入,所以N也是batch的大小。
    • target: ( N ) (N) (N)目标结果,即常见分类任务中的label,包含N个。
    • reduction:对计算结果采取的操作,通常我们用sum(对N个误差结果求和),mean(对N个误差结果取平均),默认是对所有样本求loss均值

    例子演示

    采用官方提供的演示代码如下:

    input = torch.randn(3, 5, requires_grad=True)
    # each element in target has to have 0 <= value < C
    target = torch.tensor([1, 0, 4])
    print('input:{}\n target:{}'.format(input,target))
    print('log softmax:{}'.format(F.log_softmax(input,dim=1)))
    output = F.nll_loss(F.log_softmax(input,dim=1), target)
    print('output:{}'.format(output))
    output.backward()
    

    jupyter notebook打印一下中间结果:
    在这里插入图片描述
    这里做了一次log softmax操作,softmax实际上就是对输入tensor中的元素按照数值计算了比例,dim=1保证所有分类概率和为1,最后对每个数值取了log。最终要求的就是log softmax后结果与target的误差。

    我们重点关注这一步计算:

    • log softmax tensor(模型output):
      tensor([[-3.2056, -1.7804, -0.4350, -3.9833, -2.0795],
          [-2.1543, -1.8606, -1.5360, -1.1057, -1.7025],
          [-2.3243, -0.7615, -1.1595, -2.5594, -3.1195]]
      
    • target:
      tensor([1, 0, 4])
      

    标签代表了tensor中每一行向量应该检查的位置,例如第一个标签是1,这表示在tensor第一行中应该选择1号位置的元素-1.7804(代表了模型将数据分为1类的概率)取出,同理取第2行0号位置元素-2.1543,取第三行4号位置元素-3.1195,将它们去除负号求和再取均值。
    则该模型输出outputtarget之间误差应为:(1.7804+2.1543+3.1195)/3 = 2.3514

    回顾上文的output结果2.35138....与预期相符。

    • reduction
      同样是上面的输入,我们添加reductionsum,查看output结果:
      在这里插入图片描述
      发现计算结果是7.054...,说明没有执行前面 (1.7804+2.1543+3.1195)/3 = 2.3514求均值的操作。直接将各个样本与label之间的误差求和返回。

    总结

    nll_loss 函数接收两个tensor第一个是模型的output,第二个是label targetoutput中每一行与一个标签中每一列的元素对应,根据target的取值找出output行中对应位置元素,求和取平均值。

    展开全文
  • Pytorch中的损失函数

    2020-10-22 23:54:08
    pytorch中的损失函数 0.前言 1.Loss Function 1.1 _Loss基类 1.2 nn.CrossEntropyLoss 1.2.1 有关交叉熵、信息熵、相对熵的基本概念: 1.2.2 pytorch中的交叉熵 1.3 nn.NLLLoss 1.4 nn.BCELoss 1.5 nn....
     
     
    

    pytorch中的损失函数

    0.前言

      深度学习中优化方法直接作用的对象是损失函数。损失函数表示了预测值与真实值之间的差距程度,一个最优化问题的目标是将损失函数最小化,针对分类问题,直观的表现就是.分类的正确样本越多越好;回归问题中,直观的表现就是预测值与实际值的误差越小越好。

    • 损失函数(Loss Function):
      L o s s = f ( y , , y ) Loss=f(y^,,y) Loss=f(y,,y)
    • 代价函数(Cost Fuction):
      C o s t = 1 N ∑ i = 0 N f ( y i , y i ) Cost=\frac{1}{N}\sum_{i=0}^{N}f(y_{i}^, y_{i}) Cost=N1i=0Nf(yi,yi)
        Pytorch中nn模块下提供了多种可以直接使用的损失函数,如交叉熵、均方误差等,针对不同的问题,可以直接调用现有的损失函数,常用的损失函数以及适合的问题如下表。
    损失函数名称适应问题
    torch.nn.L1Loss()平均绝对值损失回归
    torch.nn.MSELoss()均方误差损失回归
    torch.nn.CrossEntropyLoss()交叉熵损失多分类
    torch.nn.CTCLoss()
    torch.nn.NLLLoss()负数对数似然函数损失多分类
    torch.nn.KLDivLoss()KL散度损失回归
    torch.nn.BCELoss()二分类交叉熵损失二分类
    torch.nn.MarginRankingLoss评价相似度损失
    torch.nn.MultiLabelMarginLoss多标签分类损失多标签分类
    torch.nn.SmoothL1Loss平滑L1损失回归
    torch.nn.SoftMarginLoss多标签二分类损失多标签二分类

    接下来对部分损失函数,以及pytorch框架下的api进行整理说明。

    1.Loss Function

    1.1 _Loss基类

      在pytorch中nn模块下定义的loss的源码类,分别定义LOSS的类以及的带有权重系数的类。

    from .module import Module
    from .. import functional as F
    from .. import _reduction as _Reduction
    
    from torch import Tensor
    from typing import Optional
    
    
    class _Loss(Module):
        reduction: str
    
        def __init__(self, size_average=None, reduce=None, reduction: str = 'mean') -> None:
            super(_Loss, self).__init__()
            if size_average is not None or reduce is not None:
                self.reduction = _Reduction.legacy_get_string(size_average, reduce)
            else:
                self.reduction = reduction
    
    
    class _WeightedLoss(_Loss):
        def __init__(self, weight: Optional[Tensor] = None, size_average=None, reduce=None, reduction: str = 'mean') -> None:
            super(_WeightedLoss, self).__init__(size_average, reduce, reduction)
            self.register_buffer('weight', weight)
    
    

    1.2 nn.CrossEntropyLoss

    1.2.1 有关交叉熵、信息熵、相对熵的基本概念:

    使用交叉熵是为衡量两个数据概率分布差异,所以交叉熵制越低两个值相差越相似。
    交叉熵 = 信息熵 + 相对熵 \text{交叉熵 = 信息熵 + 相对熵} 交叉熵 = 信息熵 + 相对熵
    1.交叉熵
    H ( P , Q ) = − ∑ i = 1 N P ( x i ) l o g Q ( x i ) H(P,Q) = -\sum_{i=1}^NP(x_{i})logQ(x_{i}) H(P,Q)=i=1NP(xi)logQ(xi)
    2.自信息,衡量单个事件的不确定性
    l ( x ) = − l o g [ p ( x ) ] l(x) = -log[p(x)] l(x)=log[p(x)]
    3.熵(信息熵),简答讲事件的越不确定性越大,熵的值越大,自信的期望
    H ( P ) = E x   p [ I ( x ) ] = − ∑ i N P ( x i ) l o g P ( x i ) H(P) = E_{x~p}[I(x)] = -\sum_{i}^NP(x_{i})logP(x_{i}) H(P)=Ex p[I(x)]=iNP(xi)logP(xi)
    4.相对熵(KL散度),衡量两个分布之间的差异,不具备对称性。
    D K L ( P , Q ) = E x   p [ l o g P ( x ) Q ( x ) ] = E x − p [ l o g P ( x ) − l o g Q ( x ) ] = ∑ i = 1 N P ( x i ) [ l o g P ( x i ) − l o g Q ( x i ) ] = ∑ i = 1 N P ( x i ) l o g P ( x i ) − ∑ i = 1 N P ( x i ) l o g Q ( x i ) = H ( P , Q ) − H ( P ) D_{KL}(P,Q) = E_{x~p}[log\frac{P(x)}{Q(x)}]\\=E_{x-p}[logP(x)-logQ(x)]\\=\sum_{i=1}^NP(x_{i})[logP(x_{i})-logQ(x_{i})]\\=\sum_{i=1}^NP(x_{i})logP(x_{i})-\sum_{i=1}^NP(x_{i})logQ(x_{i})\\=H(P,Q)-H(P) DKL(P,Q)=Ex p[logQ(x)P(x)]=Exp[logP(x)logQ(x)]=i=1NP(xi)[logP(xi)logQ(xi)]=i=1NP(xi)logP(xi)i=1NP(xi)logQ(xi)=H(P,Q)H(P)

      结合上面的公式可以得出结论: 交叉熵: H ( P , Q ) = D K L ( P , Q ) + H ( P ) \text{交叉熵:}H(P, Q) = D_{KL}(P,Q)+H(P) 交叉熵:H(P,Q)=DKL(P,Q)+H(P),其中P代表实际样本的数据分布,Q代表预测结果的分布。

    1.2.2 pytorch中的交叉熵

      功能:nn.LogSoftmax()与nn.NLLLoss()结合,进行交叉熵计算。本该损失函数与公式中的交叉熵损失存在区别,采用了nn.LogSoftmax对数据进行归一化处理,即[0,1]的区间。

      在官网的计算公式如下:

    1. 无权重
      l o s s ( x , c l a s s ) = − l o g ( e x p ( x [ c l a s s ] ) ∑ j e x p ( x [ j ] ) ) = − x [ c l a s s ] + l o g ( ∑ j e x p ( x [ j ] ) ) loss(x, class)=-log(\frac{exp(x[class])}{\sum_{j}exp(x[j])}) \\=-x[class] + log(\sum_{j}exp(x[j])) loss(x,class)=log(jexp(x[j])exp(x[class]))=x[class]+log(jexp(x[j]))
    2. 有权重
      l o s s ( x , c l a s s ) = w e i g h t [ c l a s s ] ( − x [ c l a s s ] + l o g ( ∑ j e x p ( x [ j ] ) ) ) loss(x, class) = weight[class](-x[class] + log(\sum_{j}exp(x[j]))) loss(x,class)=weight[class](x[class]+log(jexp(x[j])))

    其中 x x x表示输出的概率值, c l a s s class class表示类别值;
      将pytorch中的定义与原始交叉熵公式 H ( P , Q ) = − ∑ i = 1 N P ( x i ) l o g Q ( x i ) H(P,Q) = -\sum_{i=1}^NP(x_{i})logQ(x_{i}) H(P,Q)=i=1NP(xi)logQ(xi)相对缺少了求和以及 P x i P{x_{i}} Pxi。因为pytorch中是对某一个元素求交叉熵,因此不需要求和项,而且已经确定的了是哪一个元素,因此 P x i = 1 P{x_{i}}=1 Pxi=1,综上pytorch中的交叉熵公式可以简单为 H ( P , Q ) = − l o g ( Q ( x i ) ) H(P,Q)=-log(Q(x_{i})) H(P,Q)=log(Q(xi))
    主要参数:

    
    torch.nn.CrossEntropyLoss(weight: Optional[torch.Tensor] = None,  # 各类别loss设置的权重
                            size_average=None,                          
                            ignore_index: int = -100,                   # 忽略某个类别
                            reduce=None, 
                            reduction: str = 'mean')                    # 计算模式 可以为none/sum/mean,none-逐个元素计算;sum-所有元素求和; mean-加权平均,返回标量。
    

      通过代码示例对此函数中的相关参数设置进行理解

    import torch
    import torch.nn as nn
    
    import numpy as np
    #------fake data
    
    inputs =torch.tensor([[1, 2], [1, 3], [1, 3]], dtype=torch.float)
    targets = torch.tensor([0, 1, 1], dtype=torch.long)
    
    # ------------
    flag = 0
    if flag:
        
        loss_f_none = nn.CrossEntropyLoss(weight=None, reduction='none')
        loss_f_sum = nn.CrossEntropyLoss(weight=None, reduction='sum')
        loss_f_mean = nn.CrossEntropyLoss(weight=None, reduction='mean')
    
        # forward
        loss_none = loss_f_none(inputs, targets)
        loss_sum = loss_f_sum(inputs, targets)
        loss_mean = loss_f_mean(inputs, targets)
    
        # view
        print(f'Cross Entropy loss: \n{loss_none, loss_sum, loss_mean}')
    >>>
    Cross Entropy loss: 
    (tensor([1.3133, 0.1269, 0.1269]), tensor(1.5671), tensor(0.5224))
    

      为了进一步的熟悉pytorch中CrossEntropyLoss计算过程,手动编写了一个计算过程,代码如下:

    ##--------------compute by hand
    flag = 1
    if flag:
        idx = 0
        #inputs =torch.tensor([[1, 2], [1, 3], [1, 3]], dtype=torch.float)
        #targets = torch.tensor([0, 1, 1], dtype=torch.long)
    
        inputs_1 = inputs.detach().numpy()[idx]
        targets_1 = targets.numpy()[idx]
    
        # 第一项
        x_class = inputs_1[targets_1]
        
        # 第二项
        sigma_exp_x = np.sum(list(map(np.exp, inputs_1)))
        log_sigma_exp_x = np.log(sigma_exp_x)
    
        # 输出loss
        loss_1 = -x_class + log_sigma_exp_x
        print('第一个样本loss 为:',loss_1)
    >>>
    '''
    计算的过程:取出输入的第一个元素[1, 2] loss = x[class] + log(exp(x[j])) 此处的log表示是数学中的ln
     log(exp(x[j])) = ln(e+e^2)
     x[class] = 1
     >>>loss = ln(e+e^2) -1 
    '''
       第一个样本loss 为: 1.3132617 
    

      比较上面的那个代码块的运行结果可以发现,计算结果是一致的。

    1.3 nn.NLLLoss

      功能:实现负对数似然函数的负号功能,计算公式
    l ( x , y ) = L = ( l i , . . . . , l N ) T , l n = − w y n x n , y n l(x, y)=L=(l_{i},....,l_{N})^T,l_{n}=-w_{yn}x_{n,y_{n}} l(x,y)=L=(li,....,lN)T,ln=wynxn,yn
    主要参数:

    
    nn.NLLLoss(weight=None, # 各类别的loss设置的权值
        size_average=None, 
        ignore_index=-100,  # 忽略某个类别
        reduce=None,
        reduce='mean')   # 计算模式
    

      直接通过代码观察此损失函数

    
    import torch
    import torch.nn as nn
    
    import numpy as np
    #------fake data
    
    inputs =torch.tensor([[1, 2], [1, 3], [1, 3]], dtype=torch.float)
    targets = torch.tensor([0, 1, 1], dtype=torch.long)
    
    flag = 1
    if flag:
        weights = torch.tensor([1, 1], dtype=torch.float)
        
        loss_f_none_w =nn.NLLLoss(weight=weights, reduction='none')
        loss_f_sum = nn.NLLLoss(weight=weights, reduction='sum')
        loss_f_mean = nn.NLLLoss(weight=weights, reduction='mean')
    
        # forward
        loss_none_w = loss_f_none_w(inputs, targets)
        loss_sum = loss_f_sum(inputs, targets)
        loss_mean = loss_f_mean(inputs, targets)
    
        # view
        print('\nweights:', weights)
        print('nll loss', loss_none_w, loss_sum, loss_mean)
    >>>>
    weights: tensor([1., 1.])
    nll loss tensor([-1., -3., -3.]) tensor(-7.) tensor(-2.3333)
    

    1.4 nn.BCELoss

      功能:二分类的交叉熵损失函数,注意事项,输入值得取值范围必须在[0, 1]
    l n = − w n [ y n ∗ l o g x n + ( 1 − y n ) ∗ l o g ( 1 − x n ) ] l_{n}=-w_{n}[y_{n}*logx_{n} + (1-y_{n})*log(1-x_{n})] ln=wn[ynlogxn+(1yn)log(1xn)]

    其中 x n x_{n} xn表示模型输出的概率取值, y n y_{n} yn表示标签值,因为是二分类任务,因此 y n y_{n} yn的取值只能是0或者1.

    主要参数:

        nn.BCELoss(weight=None,  # 各类别权重
                size_average=None,
                reduce=None,
                reduction='mean' # 计算模式)
    

    代码示例

    flag =1
    if flag:
        inputs = torch.tensor([[1, 2], [2, 2], [3, 4], [4, 5]], dtype=torch.float)
        target = torch.tensor([[1, 0], [1, 0], [0, 1], [0, 1]], dtype=torch.float)
        
        target_bce = target
    
        # itarget
        inputs = torch.sigmoid(inputs)
        
        weights = torch.tensor([1, 1], dtype=torch.float)
        
        loss_f_none = nn.BCELoss(weights, reduction='none')
        loss_f_sum = nn.BCELoss(weights, reduction='sum')
        loss_f_mean = nn.BCELoss(weights, reduction='mean')
    
        # forward
        loss_none_w = loss_f_none(inputs, target_bce)
        loss_sum = loss_f_sum(inputs, target_bce)
        loss_mean = loss_f_mean(inputs, target_bce)
    
        print(f'\nweights: {weights}')
        print(f'BCELoss ', loss_none_w, loss_sum, loss_mean)
        >>>>
    weights: tensor([1., 1.])
    BCELoss  tensor([[0.3133, 2.1269],
            [0.1269, 2.1269],
            [3.0486, 0.0181],
            [4.0181, 0.0067]]) tensor(11.7856) tensor(1.4732)
    

    1.5 nn.BCEWithLogitsLoss

      功能:结合sigmoid与二分类交叉熵,注意事项,网络最后不加sigmoid函数,公式如下:
    l n = − w n [ y n ∗ l o g δ ( x n ) + ( 1 − y n ) ∗ l o g ( 1 − δ ( x n ) ) ] l_{n} = -w_{n}[y_{n}*log\delta(x_{n}) + (1-y_{n})*log(1-\delta(x_{n}))] ln=wn[ynlogδ(xn)+(1yn)log(1δ(xn))]

    主要参数即示例代码

    '''
    nn.BCEWithLogitsLoss()
    '''
    flag =1
    if flag:
        inputs = torch.tensor([[1, 2], [2, 2], [3, 4], [4, 5]], dtype=torch.float)
        target = torch.tensor([[1, 0], [1, 0], [0, 1], [0, 1]], dtype=torch.float)
        
        target_bce = target
        weights = torch.tensor([1], dtype=torch.float)
        pos_w = torch.tensor([3],dtype=torch.float)
        
        loss_f_none = nn.BCEWithLogitsLoss(weights, reduction='none',pos_weight=pos_w)
        loss_f_sum = nn.BCEWithLogitsLoss(weights, reduction='sum', pos_weight=pos_w)
        loss_f_mean = nn.BCEWithLogitsLoss(weights, reduction='mean', pos_weight=pos_w)
    
        # forward
        loss_none_w = loss_f_none(inputs, target_bce)
        loss_sum = loss_f_sum(inputs, target_bce)
        loss_mean = loss_f_mean(inputs, target_bce)
    
        print(f'\npos_w: {pos_w}')
        print(f'BCEWithLogitsLoss ', loss_none_w, loss_sum, loss_mean)
    
    >>>
    pos_w: tensor([3.])
    BCEWithLogitsLoss  tensor([[0.9398, 2.1269],
            [0.3808, 2.1269],
            [3.0486, 0.0544],
            [4.0181, 0.0201]]) tensor(12.7158) tensor(1.5895)
    # 当pos_w = torch.tensor([1],dtype=torch.float),从输出结果中可以看出正样本的loss,乘以了3倍,模型更加关注正样本数据
    >>>>pos_w: tensor([1.])
    BCEWithLogitsLoss  tensor([[0.3133, 2.1269],
            [0.1269, 2.1269],
            [3.0486, 0.0181],
            [4.0181, 0.0067]]) tensor(11.7856) tensor(1.4732)
    

    1.6 nn.L1Loss(数据回归)

      功能:计算inputs与target之差的绝对值,公式如下:
    l n = ∣ x n − y n ∣ l_{n}=|x_{n}-y_{n}| ln=xnyn
    主要参数以及代码示例

    '''
    nn.L1Loss(reduce='none')
    '''
    flag =1
    if flag:
        inputs = torch.ones((2, 2))
        target = torch.ones((2, 2)) * 3
        
        loss_f = nn.L1Loss(reduce='none')
        loss = loss_f(inputs, target)
    
        print(f'input:{inputs}\ntarget:{target}\nL1Loss:{loss}')
    #>>>从下面的结果,可以验证与公式的计算结果是一致的
    
    input:tensor([[1., 1.],
            [1., 1.]])
    target:tensor([[3., 3.],
            [3., 3.]])
    L1Loss:tensor([[2., 2.],
            [2., 2.]])
    

    1.7 nn.MSELoss(数据回归)

      功能:计算inputs与target之差的平方,公式如下
    l n = ( x n − y n ) 2 l_{n}=(x_{n}-y_{n})^2 ln=(xnyn)2
    主要参数以及代码示例:

    flag =1
    if flag:
        inputs = torch.ones((2, 2))
        target = torch.ones((2, 2)) * 3
        
        loss_f = nn.MSELoss(reduction='none')
        loss = loss_f(inputs, target)
    
        print(f'input:{inputs}\ntarget:{target}\nMSELoss:{loss}')
    >>>>
    input:tensor([[1., 1.],
            [1., 1.]])
    target:tensor([[3., 3.],
            [3., 3.]])
    MSELoss:tensor([[4., 4.],
            [4., 4.]])
    #>>>如果 nn.MSELoss(reduction='sum')
    MSELoss:16.0
    

    1.8 nn.SmoothL1Loss(数据回归)

      功能:平滑的L1Loss,先来看一下SmoothL1Loss的计算公式:
    l o s s ( x , y ) = 1 n ∑ i z i loss(x, y)=\frac{1}{n}\sum_{i}z_{i} loss(x,y)=n1izi
    z i = { 0.5 ( x i − y i ) 2 ,  if ∣ x i − y i ∣ < 1 ∣ x i − y i ∣ − 0.5 , otherwise z_{i}=\begin{cases} 0.5(x_{i}-y_{i})^2, \ \text{if}|x_{i}-y_{i}|<1 \\ |x_{i}-y_{i}|-0.5, \text{otherwise} \end{cases} zi={0.5(xiyi)2, ifxiyi<1xiyi0.5,otherwise
    SmoothL1Loss如图1所示:
            [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vowr00oD-1603382011459)(./out_imgs/loss/l1_smooth_l1.png)]
    主要参数以及代码示例:

    flag = 1
    
    if flag:
        inputs = torch.linspace(-3, 3, steps=500)
        target = torch.zeros_like(inputs)
    
        loss_f = nn.SmoothL1Loss(reduction='none')
        loss_smooth = loss_f(inputs, target)
        loss_l1 = np.abs(inputs.numpy())
        plt.plot(inputs.numpy(), loss_smooth.numpy(), label='smooth_l1_loss')
        plt.plot(inputs.numpy(), loss_l1, label='l1 loss')
        plt.xlabel('x_i - y_i')
        plt.ylabel('loss')
        plt.legend()
        plt.grid()
        plt.savefig('../out_imgs/loss/l1_smooth_l1.png') ##保存的即为上图
    

    1.9 nn.PoissonNLLLoss

      功能:泊松分布的负数对数似然损失函数,计算公式如下:

    log_input = True l o s s ( i n p u t , t a r g e t ) = e x p ( i n p u t ) − t a r g e t ∗ i n p u t \text{log\_input = True} \\loss(input, target)=exp(input) - target * input log_input = Trueloss(input,target)=exp(input)targetinput

    log_input = False l o s s ( i n p u t , t a r g e t ) = i n p u t − t a r g e t ∗ l o g ( i n p u t + e p s ) \text{log\_input = False} \\loss(input, target)= input- target * log(input+eps) log_input = Falseloss(input,target)=inputtargetlog(input+eps)

    相关参数以及代码实例如下:

    '''---------------------------PoissonNLLLoss
    nn.PoissonNLLLoss(log_input=True,   # 输入是否为对数形式,决定计算公式
                    full=Flase,         # 计算所有loss,默认False
                    reduction='mean',
                    eps=1e-8            # 修正项,避免log(输入)为nan 
                    )
    '''
    flag = 1
    if flag:
        inputs = torch.randn((2, 2))
        target = torch.randn((2, 2))
        # 有关reduction的其它计算模式在接下来的损失示例中不在一一描述
        loss_f = nn.PoissonNLLLoss(log_input=True, full=False, reduction='none')
        loss = loss_f(inputs, target)
        print('inputs :{}\ntarget is{}\nPoissonNLLLoss :{}'.format(inputs, target, loss))
    
    #---------------compute by hand 
    flag = 1
    if flag:
        idx = 0
        # 当full=False时,采用的计算公式
        loss_1 = torch.exp(inputs[idx, idx]) - target[idx, idx]* inputs[idx, idx]
        print('第一个元素的loss', loss_1)
    #>>>> 从输出结果可以看出,手动计算的结果与pytorch api 调用输出的结果是一致的
    inputs :tensor([[ 0.0553,  0.2444],
            [-0.5864,  0.1678]])
    target istensor([[-1.1071, -0.4799],
            [ 1.1683, -1.4043]])
    PoissonNLLLoss :tensor([[1.1180, 1.3942],
            [1.2415, 1.4185]])
    第一个元素的loss tensor(1.1180)
    

    1.10 nn.KLDivLoss

      功能:计算KLD(divergence),前文介绍交叉熵也曾提到过,KLD即相对熵(计算两个分布的距离)。注意事项,需要提前将输入计算log-probabilities,如通过计算nn.logsoftmax,计算公式下:
    D K L ( P ∣ ∣ Q ) = E x − p [ l o g P ( x ) Q ( x ) ] = E x − p [ l o g P ( x ) − l o g Q ( x ) ] = ∑ i = 1 N P ( x i ) ( l o g P ( x i ) − l o g ( Q ( x i ) ) ) D_{KL}(P||Q) = E_{x-p}[log\frac{P(x)}{Q(x)}]\\=E_{x-p}[logP(x)-logQ(x)]\\=\sum_{i=1}^NP(x_{i})(logP(x_{i})-log(Q(x_i))) DKL(PQ)=Exp[logQ(x)P(x)]=Exp[logP(x)logQ(x)]=i=1NP(xi)(logP(xi)log(Q(xi)))
    其中P表示真实数据分布,Q表示拟合出来的数据分布。但是实际pytorch中使用了如下的计算公式:
    l n = y n ∗ ( l o g y n − x n ) l_{n} = y_{n}*(logy_{n}-x_{n}) ln=yn(logynxn)
    其中 y n y_{n} yn表示标签, x n x_{n} xn模型的输出值。
      比较上面的两个公式,一一对应来看,括号中减去的输入数据(模型的预测值)并没有像上式那样进行取对数,但是从实际理论出现KL散度是比较两个数据分布的关系,所以依据注意事项中的内容需要对输入的数据计算log-probabilities。
      相关参数以及代码示例

    flag =1 
    if flag:
        # input tensor_size:(2, 3),为了方便理解可以想像成全连接的最终输出是3个神经元,2个batch的数据
        inputs = torch.tensor([[0.5, 0.3, 0.2], [0.2, 0.2, 0.5]])  
        inputs_log = torch.log(inputs)
        target = torch.tensor([[0.9, 0.05, 0.05], [0.1, 0.7, 0.2]], dtype=torch.float)
    
        loss_f_none = nn.KLDivLoss(reduction='none')
        loss_f_mean = nn.KLDivLoss(reduction='mean')
        # 根据inputs的维度的batcsize的大小为2
        loss_f_batch_mean = nn.KLDivLoss(reduction='batchmean')
    
        loss_none = loss_f_none(inputs, target)
        loss_mean = loss_f_mean(inputs, target)
        loss_bs_mean = loss_f_batch_mean(inputs, target)
    
        print('loss_none:{}\nloss_mean:{}\nloss_bs_mean:{}'.format(loss_none, loss_mean, loss_bs_mean))
    #-----------------compute by hand
    flag = 1
    if flag:
        idx = 0
        
        # 理论上需要对后一项括号中的inputs[idx, idx]取对数,但是此处输入值直接采用了[0,1]之间的数模拟概率值,同时也是直接模拟pytorch中所采用的计算公式。
        loss_1 = target[idx, idx]*(torch.log(target[idx, idx])-inputs[idx, idx])
        print('loss_1', loss_1)
    # >>> 可以看出手动计算的第一个元素的loss与api的结果一致
    loss_none:tensor([[-0.5448, -0.1648, -0.1598],
            [-0.2503, -0.3897, -0.4219]])
    loss_mean:-0.3218694031238556
    loss_bs_mean:-0.9656082391738892
    loss_1 tensor(-0.5448)
    

    1.11 nn.MarginRankingLoss

      功能:计算两个向量之间的相似度,用于排序任务。计算公式如下:
    l o s s ( x , y ) = m a x ( 0 , − y ∗ ( x 1 − x 2 ) + m a r g i n ) loss(x, y) = max(0, -y * (x_{1}-x_{2}) + margin) loss(x,y)=max(0,y(x1x2)+margin)
    y y y表示取值标签,只能是1或者-1, x 1 x_{1} x1 x 2 x_{2} x2表示向量的每个元素,因此可以得到以下的结论:

    • y = 1时,希望 x 1 > x 2 x_{1}>x_{2} x1>x2, 当 x 1 > x 2 x_{1}>x_{2} x1>x2时,不会产生loss
    • y = -1时,希望 x 2 > x 1 x_{2}>x_{1} x2>x1, 当 x 2 > x 1 x_{2}>x_{1} x2>x1时,不会产生loss

    特别说明,该方法计算两组数据之间的差异,返回一个n*n的loss矩阵。
    主要参数以及代码示例:

    flag = 1
    if flag:
        x1 = torch.tensor([[1], [2], [3]],dtype=torch.float)
        x2 = torch.tensor([[2], [2], [2]], dtype=torch.float)
    
        target = torch.tensor([1, 1, -1], dtype=torch.float)
    
        loss_f_none = nn.MarginRankingLoss(margin=0, reduction='none')
        
        loss =loss_f_none(x1, x2, target)
        print('MarginRankingLoss', loss)
    #>>>
    MarginRankingLoss tensor([[1., 1., 0.],
            [0., 0., 0.],
            [0., 0., 1.]])
    '''
    1.对计算结果进行一个简单说明,输入的是2*3的一个矩阵,利用x1矩阵中每一个元素与x2中的每个元素进行比较,每个结果就是一个输出的loss,因此最终会生成一个3*3的输出loss.
    2.以x1中的第一个元素为例,1将于x2中的每个元素进行比较,因为target[0]=1,根据上述公式当x1>x2是loss为0,否则为x2-x1+margin(0)。逐个元素去比较,1<2,loss[0][0] = 2-1
    '''
    

    1.12 nn.MultiLabelMarginLoss(多标签分类)

      功能:多标签边界损失函数,对于多标签即一张图片对应多个类别。
    如:四分类任务,样本x属于0类和3类,标签[0, 3, -1, -1],不是[1, 0, 0,1]
    计算公式如下:
    l o s s ( x , y ) = ∑ i j m a x ( 0 , 1 − ( x [ y [ j ] ] − x [ i ] ) ) x . s i z e ( 0 ) loss(x, y)=\sum_{ij}\frac{max(0, 1-(x[y[j]]-x[i]))}{x.size(0)} loss(x,y)=ijx.size(0)max(0,1(x[y[j]]x[i]))

    where i== 0 to x.size(0), j==0 to y.size(0),y[j]>=0, and i不等于y[j] for all i and j \text{where i== 0 to x.size(0), j==0 to y.size(0),y[j]>=0, and i不等于y[j] for all i and j} where i== 0 to x.size(0), j==0 to y.size(0),y[j]>=0, and i不等于y[j] for all i and j
    对于公式中分子括号中的简单理解为使用标签神经元减去非标签神经元,为什么需要这样设计,对于多标签分类,希望是标签的输出大于非标签预测输出,因此使用 m a x ( 0 , 1 − ( x [ y [ j ] ] ) − x [ i ] ) max(0, 1-(x[y[j]])-x[i]) max(0,1(x[y[j]])x[i])
    主要参数以及代码示例:

    flag = 1
    if flag:
        x = torch.tensor([[0.1, 0.2, 0.4, 0.8]])
        y = torch.tensor([[0, 3, -1, -1]], dtype=torch.long)
    
        loss_f = nn.MultiLabelMarginLoss(reduction='none')
        loss = loss_f(x, y)
        print('MultiLabelMarginLoss', loss)
    # ------------compute by hand
    flag = 1
    if flag:
        x = x[0]
    
        item_1 = (1-(x[0]-x[1])) + (1 - (x[0]-x[2]))
        item_2 = (1-(x[3]-x[1])) + (1-(x[3]-x[2]))
        loss_h = (item_1 + item_2) / x.shape[0]
        print('compute by hand ', loss_h)
    # >>>
    MultiLabelMarginLoss tensor([0.8500])
    compute by hand  tensor(0.8500)
    

    1.13 nn.SoftMarginLoss(二分类)

      功能:计算二分类的logistic损失,计算公式如下:
    l o s s ( x , y ) = ∑ i l o g ( 1 + e x p ( − y [ i ] ∗ x [ i ] ) ) x . n e l e m e n t loss(x, y)=\sum_{i}\frac{log(1+exp(-y[i] * x[i]))}{x.nelement} loss(x,y)=ix.nelementlog(1+exp(y[i]x[i]))
    主要参数以及代码示例:

    flag = 1
    if flag:
        
        inputs = torch.tensor([[0.3, 0.7], [0.5, 0.5]])
        target = torch.tensor([[-1, 1], [1, -1]], dtype=torch.float)
    
        loss_f = nn.SoftMarginLoss(reduction='none')
        loss = loss_f(inputs, target)
    
        print('SoftMarginLoss', loss)
    
    #-----------compute by hand
    flag = 1
    if flag:
        idx = 0
    
        inputs_i = inputs[idx, idx]
        target_i = target[idx, idx]
    
        loss_h = np.log(1+ np.exp(-target_i * inputs_i))
        
        print('compute by hand', loss_h)
    # >>>
    SoftMarginLoss tensor([[0.8544, 0.4032],
            [0.4741, 0.9741]])
    compute by hand tensor(0.8544)
    

    1.14 MultiLabelSoftMarginLoss

      功能:SoftMarginLoss多标签版本,计算公式如下:
    l o s s ( x , y ) = − 1 C ∗ ∑ i y [ i ] ∗ l o g ( ( 1 + e x p ( − x [ i ] ) ) − 1 ) + ( 1 − y [ i ] ) ∗ l o g ( e x p ( − x [ i ] ) 1 + e x p ( − x [ i ] ) ) loss(x, y)=-\frac{1}{C} * \sum_{i}y[i]*log((1+exp(-x[i]))^{-1})+(1-y[i])*log(\frac{exp(-x[i])}{1+exp(-x[i])}) loss(x,y)=C1iy[i]log((1+exp(x[i]))1)+(1y[i])log(1+exp(x[i])exp(x[i]))
    C表示标签的数量 , y [ i ] 为 标 签 , x [ i ] 表 示 模 型 的 输 出 值 。 以 四 分 类 为 例 , 此 处 的 y [ i ] 必 须 是 一 个 [ 1 , 0 , 0 , 1 ] 形 式 , 根 据 公 式 可 以 看 出 当 y [ i ] 是 标 签 时 , 采 用 公 式 前 面 一 项 计 算 , 否 则 采 用 后 面 的 公 式 计 算 \text{C表示标签的数量},y[i]为标签,x[i]表示模型的输出值。以四分类为例,此处的y[i]必须是一个[1,0,0, 1]形式,根据公式可以看出当y[i]是标签时,采用公式前面一项计算,否则采用后面的公式计算 C表示标签的数量y[i]x[i]y[i][1,0,0,1]y[i]
      主要参数以及代码示例:

    flag = 1
    if flag:
        # 三分类任务
        inputs = torch.tensor([[0.3, 0.7, 0.8]])
        target = torch.tensor([[0, 1, 1]], dtype=torch.float)
    
        loss_f = nn.MultiLabelSoftMarginLoss(reduction='none')
        loss = loss_f(inputs, target)
        print('MultiLabelSoftMarginLoss', loss)
    # --------------compute by hand
    flag = 1
    if flag:
        # MultiLabelSoftMarginLoss需要对每个神经元进行计算
    
        # 非标签计算,计算公式后一项
        i_0 = torch.log(torch.exp(-inputs[0, 0])/ (1+torch.exp(-inputs[0, 0])))
    
        # 标签计算,采用公式第一项计算
        i_1 = torch.log(1 / (1+ torch.exp(-inputs[0, 1])))
        i_2 = torch.log(1 / (1+ torch.exp(-inputs[0, 2])))
    
        loss_h = (i_0 + i_1 + i_2) / -3
        print('compute by hand', loss_h)
    >>>>
    MultiLabelSoftMarginLoss tensor([0.5429])
    compute by hand tensor(0.5429)
    

    1.15 nn.MultiMarginLoss(多分类)

      功能:计算多分类的折页损失,计算公式如下:
    l o s s ( x , y ) = ∑ i m a x ( 0 , m a r g i n − x [ y ] + x [ i ] ) p x . s i z e ( 0 ) loss(x, y) = \frac{\sum_{i}max(0, margin-x[y]+x[i])^p}{x.size(0)} loss(x,y)=x.size(0)imax(0,marginx[y]+x[i])p

    where x ∈ 0 , . . . , x . s i z e ( 0 ) − 1 , y ∈ 0 , . . . , y . s i z e ( 0 ) − 1 , 0 ≤ y [ j ] ≤ x . s i z e ( 0 ) − 1 , x \in {0, ..., x.size(0)-1}, y \in {0,...,y.size(0)-1}, 0 \leq y[j] \leq x.size(0)-1, x0,...,x.size(0)1,y0,...,y.size(0)1,0y[j]x.size(0)1, and i ≠ y [ j ] i \neq y[j] i=y[j] for all i and j
    其中 x [ y ] x[y] x[y]表示了标签所在的神经元, x [ i ] x[i] x[i]非标签所在神经元,
      主要参数以及代码示例:

    # nn.MultiMarginLoss(p=1,    # 可选1或2
    #                 margin=1.0,  
    #                 weight=None,  # 各类别的loss设置权限
    #                 reduction='none'  # 计算模式,可选none/sum/mean)
    
    flag = 1
    if flag:
        x = torch.tensor([[0.1, 0.2, 0.7], [0.2, 0.5, 0.3]])
        y = torch.tensor([1, 2], dtype=torch.long)
        
        loss_f = nn.MultiMarginLoss(reduction='none')
        
        loss = loss_f(x, y)
        print('MultiMarginLoss', loss)
    
    #--------compute by hand
    flag = 1
    if flag:
        # 以输入的第一个数据为例,in:[0.1, 0.2, 0.7],相当于三分类最后的预测得分,对应的标签为1,即0.2为此类。
        # 根据公式,分别使用0.2(标签值)与0.1、0.7(非标签值)做差,再相加后除以数据总数
        x = x[0]
    
        margin = 1
    
        i_0 = margin - (x[1] -x[0])
    
        i_2 = margin - (x[1] - x[2])
        
        loss_h = (i_0 + i_2) / x.shape[0]
        print('compute by hand',loss_h)
    >>>>
    MultiMarginLoss tensor([0.8000, 0.7000])
    compute by hand tensor(0.8000)
    

    1.16 TripletMarginLoss(三元组损失)

      功能:计算三元组损失 ,人脸验证中常用。计算公式如下:
    L ( a , p , n ) = m a x ( d ( a i , p i ) − d ( a i , n i ) + m a r g i n , 0 ) d ( x i , y i ) = ∣ ∣ x i − y i ∣ ∣ p L(a,p,n)=max({d(a_{i}, p_{i}) - d(a_{i}, n_{i}) + margin, 0}) \\d(x_{i}, y_{i}) = ||x_{i}-y_{i}||_{p} L(a,p,n)=max(d(ai,pi)d(ai,ni)+margin,0)d(xi,yi)=xiyip

    主要参数以及代码示例:

    # --------------
    # nn.TripletMarginLoss(margin=1.0, # 边界值
    #                     p =2.0,   # 范数的阶,默认为2
    #                     eps=1e-6,
    #                     swap=False,
    #                     reduction='none'  # 计算模式 none/sum/mean)
    flag = 1
    if flag:
        anchor =torch.tensor([[1.]])
        pos = torch.tensor([[2.]])
        neg = torch.tensor([[0.5]])
    
        loss_f = nn.TripletMarginLoss(margin=1.0, p=1)
        loss = loss_f(anchor, pos, neg)
    
        print('TripletMarginLoss:', loss)
    >>>>
    TripletMarginLoss: tensor(1.5000)
    

    1.17 TripletMarginLoss(非线性embedding和半监督学习)

      功能:计算两个输入的相似性,特别注意:输入x应为两个输入之差的绝对值.计算公式如下:
    l n = { x n , i f y n = 1 , m a x 0 , Δ − x n , i f y n = − 1 l_{n} = \begin{cases} x_{n}, if y_{n} = 1,\\max{0, \Delta-x_{n}}, if y_{n} = -1 \end{cases} ln={xn,ifyn=1,max0,Δxn,ifyn=1

    主要参数以及代码示例:

    
    # nn.HingeEmbeddingLoss(margin=1.0,  # 边界值
    #                 reduction='none'  # 计算模式 可为none/sum/mean/
    #                 )
    
    flag = 1
    if flag:
        inputs = torch.tensor([[1., 0.8, 0.5]])
        target = torch.tensor([[1, 1, -1]])
        
        loss_f = nn.HingeEmbeddingLoss(margin=1.0, reduction='none')
    
        loss = loss_f(inputs, target)
        print('HingeEmbeddingLoss:', loss)
    # >>> 当标签值为1时,直接输出x,当标签为-1时,使用margin-x与0做一个max
    HingeEmbeddingLoss: tensor([[1.0000, 0.8000, 0.5000]])
    

    1.18 CosineEmbeddingLoss(embedding和半监督学习)

      功能:采用余弦相似性计算两个输入的相似性,使用余弦主要考虑两个特征在方向上的差异,计算公式如下:
    l o s s ( x , y ) = { 1 − c o s ( x 1 , x 2 ) , i f y = 1 m a x ( 0 , c o s ( x 1 , x 2 ) − m a r g i n ) , i f y = − 1 loss(x, y) = \begin{cases} 1-cos(x_{1}, x_{2}), \qquad if \quad y =1\\max(0, cos(x_{1}, x_{2})-margin), \qquad if \quad y =-1 \end{cases} loss(x,y)={1cos(x1,x2),ify=1max(0,cos(x1,x2)margin),ify=1

    c o s ( θ ) = A ∗ B ∣ ∣ A ∣ ∣ ∣ ∣ B ∣ ∣ = ∑ i = 1 n A i × B i ∑ i = 1 n ( A i ) 2 × ∑ i = 1 n ( B i ) 2 cos(\theta)=\frac{A*B}{||A||||B||}=\frac{\sum_{i=1}^nA_{i}\times B_{i}}{\sqrt{\sum_{i=1}^n(A_{i})^2}\times\sqrt{\sum_{i=1}^n(B_{i})^2}} cos(θ)=ABAB=i=1n(Ai)2 ×i=1n(Bi)2 i=1nAi×Bi
    主要参数以及代码示例:

    flag = 1
    if flag:
    
        x1 = torch.tensor([[0.3, 0.5, 0.7], [0.3, 0.5, 0.7]])
        x2 = torch.tensor([[0.1, 0.3, 0.5], [0.1, 0.3, 0.5]])
    
        target = torch.tensor([[1, -1]], dtype=torch.float)
    
        loss_f = nn.CosineEmbeddingLoss(margin=0., reduction='none')
        loss = loss_f(x1, x2,target)
        print('CosineEmbeddingLoss:', loss)
    
    # --------------------compute by hand
    flag = 1
    if flag:
        
        margin = 0.
    
        def cosine(a, b):
            numerator = torch.dot(a, b)
            denpminator = torch.norm(a, 2)* torch.norm(b,2)
            return float(numerator / denpminator)
    
        l_1 = 1-(cosine(x1[0], x2[0]))
        l_2 = max(0, cosine(x1[0], x2[0]))
    
        print(l_1, l_2)
    >>>>
    CosineEmbeddingLoss: tensor([[0.0167, 0.9833]])
    0.016662120819091797 0.9833378791809082
    

    1.19 nn.CTCLoss

      功能:计算CTC(Connectionist Temproal Classification)损失,解决时序类数据的分类.
    主要参数以及代码示例:

        flag = 1
        if flag:
            T = 50   # input sequence length
            C = 20   # number of classes (including blank)
            N =16    # batch size 
            S = 30   # target sequence length of longest target in batch
            S_min =10  # minimum target length, for demonstration purposes
    
            # initialize random batch of input vector for *size = (T, N,C)  
            inputs = torch.randn(T,N, C).log_softmax(2).detach().requires_grad_()
    
            # initialize random batch of target (0 = blank, 1:c = classes)
            target = torch.randint(low=1, high=C, size=(N, S), dtype=torch.long)
            
            input_lengths = torch.full(size=(N,), fill_value=T, dtype=torch.long)
    
            target_lengths = torch.randint(low=S_min, high=S, size=(N,), dtype=torch.long)
    
            ctc_loss = nn.CTCLoss()
            loss = ctc_loss(inputs, target, input_lengths, target_lengths)
            print('ctc loss:',loss)
    >>>
    ctc loss: tensor(6.6770, grad_fn=<MeanBackward0>)
    
    展开全文
  • 损失函数 损失函数(loss):Loss=f(y^,y)Loss=f(\hat{y}, y)Loss=f(y^​,y) ,衡量模型输出与真实标签的差异,针对一个样本。 代价函数(cost):Coss=1N∑iNf(y^i,yi)Coss=\frac{1}{N}\sum_i^Nf(\hat{y}_i, y_i)...
  • 交叉熵损失函数,是一种在分类任务标签学习中效果较好的损失函数。 criterion = nn.CrossEntropyLoss() ... # train ... for i, (features, length, label) in enumerate(train_loader): ... loss = ...
  • Pytorch学习之损失函数

    2020-07-12 16:09:55
    损失函数 损失函数通过torch.nn包实现, 1 基本用法 criterion = LossCriterion() #构造函数有自己的参数 loss = criterion(x, y) #调用标准时也有参数 2 损失函数 2-1 L1范数损失 L1Loss 计算 output 和 target 之...
  • 由于Pytorch中使用mini-batch进行计算,因此其损失函数的计算结果会对mini-batch取平均 常见的Pytorch中内置的损失函数有: nn.L1Loss 计算input与output的差的绝对值,input与output应该是同一维度,得到的loss也是...
  • 最近学习 pytorch,将其损失函数大致使用场景做了一下汇总,参考网上大家的文章,或直接引用,文后附有原文链接,如有不对,欢迎指正 一、L1Loss L1 Loss,它有几个别称: L1 范数损失 最小绝对值偏差(LAD) ...
  • 2.1.4 Pytorch中的分类交叉熵损失 分类任务的交叉熵loss为: class torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='mean') Pytorch的CrossEntropy...
  • Pytorch打卡任务(四)

    2019-08-13 11:58:36
    【Task4(2天)】用PyTorch实现多层网络 1.引入模块,读取数据 2.构建计算图(构建网络模型) 3.损失函数与优化器 4.开始训练模型 5.对训练的模型预测结果进行评估 ..有点跟不上,后面补上,还在深入探究原理 ...
  • PyTorch损失函数

    2020-02-25 12:12:56
    列出PyTorch常用损失函数,直到大概作用再详细自己查吧
  • pytorch损失函数

    2020-09-18 22:14:22
    pytorch损失函数可用于数据在2维以上的导出与导入 损失函数在torch.nn中。 可用于数据在2维以上的 L1范数损失 L1Loss torch.nn.L1Loss(reduction='mean') 参数:reduction-三个值,none: 不使用约简;mean:返回loss...
  • 文章目录PyTorch损失函数和优化器损失函数优化器总结 PyTorch损失函数和优化器 损失函数 一般来说,PyTorch损失函数有两种形式:函数形式和模块形式。前者调用的是torch.nn.functional库中的函数,通过传入...
  • Pytorch损失函数

    2021-08-19 15:40:42
    学习过程知识粗略记录,用于个人理解和日后查看 包导入 import torch from torch import nn MSELoss-均方差损失 常用于回归问题中 对于每一个输入实例都只有一个输出值,把所有输入实例的...False时,损失为每个min.
  • pytorch中常见的损失函数 参考自:https://mp.weixin.qq.com/s/2oUNYUwkrVUN1fV4zDER7Q 文章目录pytorch中常见的损失函数1.交叉熵损失交叉熵简介BCELossBCEWithLogitsLossNLLLossCrossEntropyLoss2.KL散度KL散度简介...
  • PyTorch里的分类损失函数

    万次阅读 2018-09-10 14:25:55
    最近大热的PyTorch即将推出1.0版,做为各类深度学习任务的最优框架之一,PyTorch提供了丰富的损失函数,而分类任务用到最多的就是n...
  • 目录数据集类的构建torch.utils.data.Datasetimplementation导入包\__init__()\__len__()\__getitem__()检验数据集类手动提取数据DataLoader多任务网络的搭建与训练导入包检查是否可使用GPU多任务网络的搭建设置网络...
  • 点击我爱计算机视觉标星,更快获取CVML新技术今天跟大家分享一款新晋开源的出自香港中文大学MMLab实验室的人脸识别库,其最大特点是支持人脸多任务训练,方便使用PyTorch进行人脸识别...
  • pytorch任务

    2019-05-16 09:44:40
    1.2 损失函数 二、代码实现 2.1 导入相关库 2.2 导入数据 三 方法1:直接使用logistic regression(逻辑回归)定义+pytorch梯度计算 3.1 初始化 3.2 训练 4 方法2:使用神经网络方法 4.1 导入相关库 4.2 ...
  • 损失函数L1 lossL2 loss L1 loss L1损失就是直接计算target与网络输出之间的距离,对于超分而言计算公式如下: ...pytorch中继承了这个简单的损失函数具体代码如下: import torch import torch.nn as nn #创建评
  • 浅谈Label Smoothing Label Smoothing也称之为标签平滑,其实是一种防止过...现在假设一个分类任务标签是[1,0,0],如果它本身的label的出现了问题,这对模型的伤害是非常大的,因为在训练的过程中强行学习一个非本
  • pytorch分割损失函数

    2021-03-01 21:37:33
    通道输出时的交叉熵损失计算 通道输出交叉熵损失计算示意图 首先,假设我们研究的是一个二分类语义分割问题。 网络的输入是一个 2×2 的图像,设置 batch_size 为 2,网络输出(二)通道特征图。网络的标签...
  • 3. 损失函数与优化器 4. 开始训练模型 5. 对训练的模型预测结果进行评估 数据采用糖尿病分类数据集diabetes.csv。这是一个典型的分类问题数据,包含768个样本,每个样本的数据包含8个特征,分别代表受试者的不同身体...
  • Pytorch损失函数Loss function

    万次阅读 多人点赞 2019-03-01 15:22:05
    0 损失函数 损失函数,又叫目标函数,是编译一个神经网络模型必须的两个参数之一。另一个必不可少的参数是优化器。 损失函数是指用于计算标签值和预测值之间差异的函数,在机器学习过程中,有多种损失函数可供选择...
  • Pytorch损失函数篇

    2020-10-07 22:16:24
    点击关注我哦一篇文章带你了解pytorch中常用的损失函数Q:什么是损失函数?训练神经网络类似于人类的学习方式。我们将数据提供给模型,它可以预测某些内容,并告诉其预测是否正确。然后,模型...
  • 本文截取自《PyTorch 模型训练实用教程》,获取全文pdf请点击:https://github.com/tensor-yu/PyTorch_Tutorial 文章目录1.L1loss2.MSELoss3.CrossEntropyLoss4.NLLLoss5.PoissonNLLLoss6.KLDivLoss7.BCELoss8....
  • pytorch损失函数理解

    2020-01-13 14:31:57
    对于loss的定义和选择,是...从pytorch的loss的使用来看,是对于loss的理解的一个很好的入口。 https://blog.csdn.net/jacke121/article/details/82812218 对于Loss的理解应该是无止境的,有如下的一些比较高阶...
  • 具有分类损失多任务学习(半监督学习) 。 效果和细节 1. 增加批大小并用批范数替换实例范数这种变化使模型能够识别男性和女性头发长度的差异。 应用此更改后,生成器开始绘制或擦除头发。 2.平滑标记和模型架构...
  • Pytorch - 损失函数nn.CrossEntropyLossnn.NLLLossnn.BCELossnn.BCEWithLogitLossnn.L1Lossnn.MSELossnn.SmoothL1Lossnn.PossionNLLLossnn.KLDivLossnn.MarginRankingLossnn.MultiLabelMarginLossnn....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,012
精华内容 3,204
关键字:

pytorch多任务损失