Pytorch学习(十)Pytorch中常用的损失函数

1. torch.nn.CrossEntropyLoss

CrossEntropyLoss的作用相当于将nn.LogSoftmax()和nn.NLLLoss()结合在一起,nn.LogSoftmax()相当于先对输入矩阵计算softmax值,然后取log。举例说明这几个函数的功能:
(1)使用nn.Softmax() + torch.log()来模拟nn.LogSoftmax()

import torch
import torch.nn as nn

# 随机生成输入
input = torch.randn(3, 3)
print("输入矩阵:\n", input)
label = torch.tensor([1, 2, 0])

# (1)使用nn.Softmax() + torch.log()来模拟nn.LogSoftmax()
# 对输入值计算softmax值
softmax = nn.Softmax(dim=1)      
softmax_output = softmax(input)
print("输入矩阵的softmax值: \n", softmax_output)
# 对softmax值取log
log_output = torch.log(softmax_output)
print("对softmax值取log: \n", log_output)

# 输出结果如下:
输入矩阵:
 tensor([[-0.8842, -0.4118,  0.6773],
        [-0.5324, -1.1168, -0.3089],
        [-0.5324,  1.9512,  1.6705]])
输入矩阵的softmax值: 
 tensor([[0.1357, 0.2176, 0.6467],
        [0.3561, 0.1985, 0.4453],
        [0.0454, 0.5439, 0.4108]])
对softmax值取log: 
 tensor([[-1.9974, -1.5250, -0.4359],
        [-1.0324, -1.6168, -0.8089],
        [-3.0927, -0.6091, -0.8898]])
# 对输入值直接使用nn.LogSoftmax()
log_softmax = nn.LogSoftmax(dim=1)
log_softmax_output = log_softmax(input)
print("nn.LogSoftmaxloss的输出结果: \n", log_softmax_output)
# 输出结果如下:
nn.LogSoftmaxloss的输出结果: 
 tensor([[-1.9974, -1.5250, -0.4359],
        [-1.0324, -1.6168, -0.8089],
        [-3.0927, -0.6091, -0.8898]])

上面两段代码的输出结果是相同的,所以使用nn.Softmax() + torch.log()可以实现nn.LogSoftmax()的功能
(2)使用nn.LogSoftmax()和nn.NLLLoss()[负对数似然函数]来模拟nn.CrossEntropyLoss()

# 使用nn.LogSoftmax()和nn.NLLLoss()
nllloss = nn.NLLLoss()
nllloss_output = nllloss(log_softmax_output, label)
print("NLLLoss的输出结果:\n", nllloss_output)
# 输出结果
NLLLoss的输出结果:
 tensor(1.8089)

那么NLLLoss的输出结果是如何计算的呢?
NLLLoss的结果就是把LogSoftmax的输出与Label对应的那个值拿出来,再去掉负号,再求均值。即 (1.5250+0.8089+3.0927)/3=1.8089

# 使用nn.CrossEntropyLoss()
cross_entropyloss = nn.CrossEntropyLoss()
cross_entropyloss_output = cross_entropyloss(input, label)
print("CrossEntropyLoss的输出结果:\n", cross_entropyloss_output)
# 输出结果
CrossEntropyLoss的输出结果:
 tensor(1.8089)

上面两段代码的输出结果是相同的,所以可以使用nn.LogSoftmax()和nn.NLLLoss()来模拟nn.CrossEntropyLoss()。
总结:
Pytorch中CrossEntropyLoss()函数的主要是将softmax-log-NLLLoss合并到一块得到的结果。

  • Softmax后的数值都在0~1之间,所以ln之后值域是负无穷到0。
  • 然后将Softmax之后的结果取log,将乘法改成加法减少计算量,同时保障函数的单调性 。
  • NLLLoss的结果就是把上面的输出与Label对应的那个值拿出来,去掉负号,再求均值。

2. L1损失,L1 Loss(L1 norm)

计算输入input和target中每个元素的平均绝对误差(mean absolute error [MAE]),input和target都是有着n个向量的认识形状的张量,二者形状相同。举例如下:

input = torch.randn((1, 2))
print("input\n", input)
target = torch.randn((1, 2))
print("target\n", target)
l1loss = nn.L1Loss()
l1loss_output = l1loss(input, target)
print("L1Loss输出:\n", l1loss_output)

# 输出结果
input
 tensor([[-0.3591, -1.1398]])
target
 tensor([[-0.1370, -0.8672]])
L1Loss输出:
 tensor(0.2474)

输出结果计算:(|-0.3591-(-0.1370)| + |-1.1398-(-0.8672)|) = 0.2474

3. L2损失,L2 Loss(L2 norm)

计算输入input和target中每个元素的均方误差(mean squared error [MSE]),input和target形状相同。举例如下:

input = torch.randn((1, 2))
print("input\n", input)
target = torch.randn((1, 2))
print("target\n", target)
mseloss = nn.MSELoss()
mseloss_output = mseloss(input, target)
print("MSELoss输出:\n", mseloss_output)
# 输出结果
input
 tensor([[0.3812, 1.2124]])
target
 tensor([[ 1.1891, -0.2384]])
MSELoss输出:
 tensor(1.3788)

输出结果计算:[(0.3812-1.1891)² + (1.2124-(-0.2384))²] / 2 = 1.3788

4. SmoothL1Loss

输入input和target形状相同,公式如下:
在这里插入图片描述
当预测值和ground truth差别较小的时候(绝对值差小于1),其实使用的是L2 Loss;而当差别大的时候,是L1 Loss的平移。SooothL1Loss其实是L2Loss和L1Loss的结合,它同时拥有L2 Loss和L1 Loss的部分优点。

  1. 当预测值和ground truth差别较小的时候(绝对值差小于1),梯度不至于太大。(损失函数相较L1 Loss比较圆滑)
  2. 当差别大的时候,梯度值足够小(较稳定,不容易梯度爆炸)。
    Pytorch学习(十)Pytorch中常用的损失函数_第1张图片
    此处参考这里

你可能感兴趣的:(Pytorch系列学习,深度学习与神经网络,Python,pytorch,深度学习,神经网络,python)