背景
我们知道,交叉熵本质上是两个概率分布之间差异的度量,公式如下
其中概率分布P是基准,我们知道H(P,Q)>=0,那么H(P,Q)越小,说明Q约接近P。
损失函数本质上也是为了度量模型和完美模型的差异,因此可以用交叉熵作为损失函数,公式如下
其中
的部分不过是考虑到每次都是输入一批样本,因此把每个样本的交叉熵求出来以后要再求个平均。
注意,我的代码没有考虑标签是soft embedding的情况,如果遇到标注Y是[[0.1,0.1,0.8],[0.1,0.8,0.1],[0.1,0.1,0.8]],那么你需要把代码再推广一下。
自定义交叉熵损失
from typing import List
import mathdef my_softmax(x:List[List[float]])->List[List[float]]:new_x:List[List[float]] = []for i in range(len(x)):sum:float = 0new_x_i = []for j in range(len(x[0])):sum += math.exp(x[i][j])for j in range(len(x[0])):new_x_i.append(math.exp(x[i][j])/sum)new_x.append(new_x_i)return new_xdef my_cross_entropy(x:List[List[float]],y:List[int])->float:res:float = 0x = my_softmax(x)for i in range(len(x)):res += -math.log(x[i][y[i]]) # 根号外面的1和底数e省去了res /= len(x) # meanreturn res# 假设有一个简单的三分类问题,批量大小为2
# 预测输出(通常是模型的原始输出,没有经过softmax)
logits = [[1.5, 0.5, -0.5], [1.2, 0.2, 3.0]]
# 0 和 2 分别表示第一个和第三个类别是正确的
targets = [0, 2]
print(my_cross_entropy(logits,targets))
Pytorch交叉熵损失
import torch
import torch.nn as nnlogits = torch.tensor([[1.5, 0.5, -0.5],[1.2, 0.2, 3.0]])targets = torch.tensor([0, 2]) criterion = nn.CrossEntropyLoss()loss = criterion(logits, targets)print(loss.item())