在使用Pytorch时经常碰见这些函数cross_entropy,CrossEntropyLoss, log_softmax, softmax。
首先要知道上面提到的这些函数一部分是来自于torch.nn,而另一部分则来自于torch.nn.functional(常缩写为F)。
下面是对与cross entropy有关的函数做的总结:
torch.nn | torch.nn.functional (F) |
CrossEntropyLoss | cross_entropy |
LogSoftmax | log_softmax |
NLLLoss | nll_loss |
下面将主要介绍torch.nn.functional中的函数为主,torch.nn中对应的函数其实就是对F里的函数进行包装以便管理变量等操作。
一、F.cross_entropy( )
这个函数就是我们常说的softmax Loss。这里暂时只说一下pytorch中该函数的用法(主要是一些平时被忽略的参数)
函数原型为:
cross_entropy(input, target, weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='elementwise_mean')
- input 一个shape为[N,C]的Tensor,其中N代表样本个数,C代表类别数目
- target 样本标签,其shape要求为大小为
n
的1—D
tensor
,包含类别的索引(0到 n-1
),要求 0 <= targets[i] <= C-1 - weight 该参数指定每个类别占loss的权重.。
1-D
tensor,n
个元素,分别代表n
类的权重,如果你的训练样本很不均衡的话,是非常有用的。默认值为None。,默认各类loss权重相同 - size_average(该参数不建议使用,后续版本可能被废弃),该参数指定loss是否在一个Batch内平均,即是否除以N。默认为True
- ignore_index 指定忽略某些类别的loss
- reduce (该参数不建议使用,后续版本可能会废弃),首先说明该参数与size_average冲突,当该参数指定为False时size_average不生效,该参数默认为True。reduce为False时,对batch内的每个样本单独计算loss,loss的返回值Shape为[N],每一个数对应一个样本的loss。reduce为True时,根据size_average决定对N个样本的loss进行求和还是平均,此时返回的loss是一个数。
- reduction 该参数在新版本中是为了取代size_average和reduce参数的。它共有三种选项'elementwise_mean','sum'和'none'。'elementwise_mean'为默认情况,表明对N个样本的loss进行求平均之后返回(相当于reduce=True,size_average=True);'sum'指对n个样本的loss求和(相当于reduce=True,size_average=False);'none'表示直接返回n分样本的loss(相当于reduce=False)
举几个例子来说明情况(只讲讲reduction,其他都好理解就不说了)
1.默认情况,reduction = 'elementwise_mean'
假设网络的输出为out,标签为target(需要LongTensor)。我们的Batch_size为2,总共两个样本,3类。
import torch.nn.functional as F
out = torch.Tensor([[1,2,3],[3,4,1]])
target = torch.LongTensor([0,1])
loss = F.cross_entropy(out,target)
print(loss)
"""
out 为
tensor(1.3783)
"""
2.reduction = 'sum'
import torch.nn.functional as F
out = torch.Tensor([[1,2,3],[3,4,1]])
target = torch.LongTensor([0,1])
loss = F.cross_entropy(out,target,reduction='sum')
print(loss)
"""
out 为
tensor(2.7566)
"""
观察一下,是不是等于1中loss的两倍呢?
3.reduction = 'none'
import torch.nn.functional as F
out = torch.Tensor([[1,2,3],[3,4,1]])
target = torch.LongTensor([0,1])
loss = F.cross_entropy(out,target,reduction='none')
print(loss)
"""
out 为
tensor([2.4076, 0.3490])
"""
此次输出就是一个和样本数相等的向量了(前两个情况都是一个数),观察一下对这个向量求和或者求平均是不是等于前两个情况呢?