torch 交叉熵
1.softmax函数
对前层网络的输出si做如下变换,norms = (e^s1,e^s2,...,e^sk)/∑e^sj,
这样norms中的元素均为正值且和为1。
对应损失函数,L = -log(e^syi//∑e^sj),其中yi是样本i的标签(即样本真实类别)在类别集合中的序号。
2.onehot编码
适用于离散特征,比如color:[red,blue,green],如果给每个颜色一个对应值,便得到[0,1,2];
当然,也可以这样分配,我有red,blue,green三个类别,如果属性为red,就取[1,0,0];是blue,就取[0,1,0];依照这种思路得到的就是onehot编码。
torch中使用如下方式获得
#真实类别标签 target=torch.tensor([1,0,2]) # 对真实类别标签做 独热编码 one_hot = F.one_hot(target)
如果按照一开始的思路,得到[0,1,2],可以按照下面的方式转为对应的onehot编码。(eye(3)返回类似单位矩阵的张量)
one_hot2 = torch.eye(3)[target.long(),:]
3.多分类交叉熵
L=-1/N * ∑ ∑yic*log(pic)
第1个∑ ,1-N,N个样本;第2个∑ ,1-K,K个分类
pic是前层网络计算出来的在各个类别上的分值(经过softmax处理的);
yic是onehot编码,若第i个样本属于类别c,则对应位置的元素取1,否则取0
下面是几种计算方式:
1.分步计算交叉熵
#预测值,假设已做softmax pred=torch.tensor([[0.2,0.3,0.5],[0.3,0.2,0.5],[0.4,0.4,0.2]]) #真实类别标签 target=torch.tensor([1,0,2]) # 对真实类别标签做 独热编码 one_hot = F.one_hot(target) log = torch.log(pred)#以自然对数e为底 res=-torch.sum(one_hot*log)/target.shape[0]#这里的*是张量对应元素相乘 print(res)
2.使用nll_loss计算交叉熵时,无需对标签进行onehot编码
#预测值,假设已做softmax pred=torch.tensor([[0.2,0.3,0.5],[0.3,0.2,0.5],[0.4,0.4,0.2]]) #真实类别标签 target=torch.tensor([1,0,2]) log = torch.log(pred) res2=F.nll_loss(log, target) print(res2)
3.使用log_softmax+nll_loss
#4个样本,3分类 pred=torch.rand(4,3) #真实类别标签 target=torch.tensor([0,1,0,2]) logsoftmax = F.log_softmax(pred) res2 = F.nll_loss(logsoftmax,target) print(res2)
4.使用CrossEntropyLoss ,其等于softmax+log+nll_loss
#4个样本,3分类 pred=torch.rand(4,3) #真实类别标签 target=torch.tensor([0,1,0,2]) res=F.cross_entropy(pred, target) print(res)

浙公网安备 33010602011771号