交叉熵损失的来源、说明、求导与pytorch实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kevin_zhao_zl/article/details/90735991

1. (信息)熵

  一条信息的信息量大小和它的不确定性有直接关系。给定一个离散的随机变量 x x ,信息的度量依赖于概率分布 p ( x ) p(x) ,此时需要求出一个函数 I ( x ) I(x) 来表示信息的内容,它应该是概率 p ( x ) p(x) 的单调函数。
  假设现在有两个不相关的事件 x x y y ,那么观察到两个事件同时发生时获得的信息量应该等于观察到各自发生时获得的信息之后即: I ( x , y ) = I ( x ) + I ( y ) I(x,y)=I(x)+I(y) ,而且由于这两个事件不相关则有 p ( x , y ) = p ( x ) p ( y ) p(x,y)=p(x)p(y) ,可以看出概率 p ( x ) p(x) 的函数 I ( x ) I(x) p ( x ) p(x) 的对数存在一定的关系(cause: l o g a ( m n ) = l o g a m + l o g a n log_a(mn)=log_am+log_an ),由此得: I ( x ) = l o g p ( x ) I(x)=-logp(x)
  其中负号用来保证信息量非负, l o g log 的基数是任意选择的(信息论中通常选择2,机器学习青睐自然常数 e e ), I ( x ) I(x) 也被称为随机变量 x x 的自行西,描述随机变量的某个事件发生所带来的信息量。
  若将该随机变量由发送者传输给接收者,整个过程传输的平均信息量即 I ( x ) I(x) 关于概率分布 p ( x ) p(x) 的期望得到,即:

H ( X ) = x p ( x ) l o g p ( x ) = i = 1 n p ( x i ) l o g p ( x i ) H(X)=-\sum_xp(x)logp(x)=-\sum_{i=1}^np(x_i)logp(x_i)

   H ( X ) H(X) 就称为随机变量 x x 的熵,表示随机变量不确定的度量,是对所有可能发生的事件产生的信息量的期望,从公式中可以看到随机变量的取值个数越多,状态数也就越多,信息上就越大,混乱程度就越大,当随机分布为均匀分布时,熵最大,且 0 H ( X ) l o g n 0\leq H(X) \leq logn

证明:

因为 p ( 1 ) + p ( 2 ) + . . . + p ( n ) = 1 p(1)+p(2)+...+p(n)=1 ,所以有目标函数: f ( p ( 1 ) , p ( 2 ) , . . . , p ( n ) ) = ( p ( 1 ) l o g p ( 1 ) + . . . + p ( n ) l o g p ( n ) ) f(p(1),p(2),...,p(n))=-(p(1)logp(1)+...+p(n)logp(n)) 约束条件 g ( p ( 1 ) , . . . , p ( n ) , λ ) = p ( 1 ) + . . . + p ( n ) 1 = 0 g(p(1),...,p(n),\lambda)=p(1)+...+p(n)-1=0 ,定义拉格朗日函数: L ( p ( 1 ) , . . . , p ( n ) , λ ) = ( p ( 1 ) l o g p ( 1 ) + . . . + p ( n ) l o g p ( n ) ) + λ ( p ( 1 ) + . . . + p ( n ) 1 ) L(p(1),...,p(n),\lambda)=-(p(1)logp(1)+...+p(n)logp(n))+\lambda(p(1)+...+p(n)-1) 分别对 p ( 1 ) , p ( 2 ) , . . . , p ( n ) p(1),p(2),...,p(n) 求偏导,令偏导数为0,则有:

λ l o g ( e ( 1 ) ) = 0 \lambda-log(e \cdotp(1))=0 ,

λ l o g ( e ( 2 ) ) = 0 \lambda-log(e \cdotp(2))=0 ,

λ l o g ( e ( n ) ) = 0 \lambda-log(e \cdotp(n))=0 ,

可知 p ( 1 ) , . . . , p ( n ) p(1),...,p(n) 都相等且和为1,此时得: p ( 1 ) = . . . p ( n ) = 1 n p(1)=...p(n)=\frac{1}{n} ,带入函数求得极值 f ( 1 n , . . . , 1 n ) = ( 1 n l o g 1 n × n ) = l o g ( 1 n ) = l o g n f(\frac{1}{n},...,\frac{1}{n})=-(\frac{1}{n}log\frac{1}{n} \times n)=-log(\frac{1}{n})=logn

举个栗子:加入该随机变量有四种可能状态且每个状态等可能发生,则传输过程需要 H ( X ) = 4 × 1 4 l o g 2 1 4 = 2 b i t s H(X)=-4 \times \frac{1}{4}log_2\frac{1}{4}=2 bits 的信息量,若四种可能的状态出现的概率不等,各自为{0.5,0.25,0.125,0.125},此时熵为: H ( X ) = 0.5 l o g 2 0.5 0.25 l o g 2 0.25 2 × 0.125 l o g 2 0.125 = 1.75 b i t s H(X)=-0.5log_20.5-0.25log_20.25-2 \times 0.125log_20.125=1.75bits ,可以看出非均匀分布要比均匀分布的熵小,如果要把变量状态的类别传递给接收者,用0、10、110、111表示四个出现概率不一致的状态,传输的编码的平均长度: A C L = 0.5 × 1 + 0.25 × 2 + 2 × 0.125 × 3 = 1.75 b i t s a ACL=0.5 \times 1+0.25 \times 2+2 \times 0.125 \times3=1.75bitsa ,熵和最短编码长度的相等关系在香农编码定理中具体阐述,即熵是传输一个随机变量状态值所需的比特位下界,因此信息熵也可以应用在数据压缩方面。

2. 条件熵

  条件熵 H ( Y X ) H(Y|X) 表示已知随机变量 X X 的条件下随机变量 Y Y 的不确定性:
H ( Y X ) = x p ( x ) H ( Y X = x ) = x p ( x ) y p ( y x ) l o g p ( y x ) = x y p ( x , y ) l o g p ( y x ) = x , y p ( x , y ) l o g p ( y x ) H(Y|X)=\sum_xp(x)H(Y|X=x)\\ =-\sum_xp(x)\sum_yp(y|x)logp(y|x)\\ =-\sum_x\sum_yp(x,y)logp(y|x)\\ =-\sum_{x,y}p(x,y)logp(y|x)

3. 相对熵(KL散度)

  设 p ( x ) , q ( x ) p(x),q(x) 是离散随机变量 X X 中取值的两个概率分布,则 p p q q 的相对熵:
D K L ( p q ) = x p ( x ) l o g p ( x ) q ( x ) = E p ( x ) l o g p ( x ) q ( x ) D_{KL}(p||q)=\sum_xp(x)log\frac{p(x)}{q(x)}=E_{p(x)}log\frac{p(x)}{q(x)}
有如下性质:

  • r若 p ( x ) p(x) q ( x ) q(x) 分布相同,则相对熵为0

  • D K L ( p q ) ! = D K L ( q p ) D_{KL}(p||q) != D_{KL}(q||p) ,即相对熵不具有对称性

  • D K L ( p q ) 0 D_{KL}(p||q)\geq0 ,证明:

D K L ( p q ) = x p ( x ) l o g p ( x ) q ( x ) = x p ( x ) l o g q ( x ) p ( x ) = E p ( x ) ( l o g q ( x ) p ( x ) ) l o g E p ( x ) ( q ( x ) p ( x ) ) = l o g x p ( x ) q ( x ) p ( x ) = l o g x q ( x ) = 0 D_{KL}(p||q)=\sum_xp(x)log\frac{p(x)}{q(x)}\\ =-\sum_xp(x)log\frac{q(x)}{p(x)}\\ =-E_{p(x)}\left(log\frac{q(x)}{p(x)}\right)\\ \geq -logE_{p(x)}(\frac{q(x)}{p(x)})\\ =-log\sum_xp(x)\frac{q(x)}{p(x)}\\ =-log\sum_xq(x)=0

综上相对熵用来很亮两个概率分布之间的差异,即求 p p q q 之间的对数差在 p p 上的期望值。

4. 交叉熵

  有两个关于样本集的概率分布 p ( x ) p(x) q ( x ) q(x) ,其中 p ( x ) p(x) 为真实分布, q ( x ) q(x) 为非真实分布,若用真实分布 p ( x ) p(x) 来衡量识别一个样本所需要编码长度的期望(平均编码长度)为: H ( p ) = x p ( x ) l o g 1 p ( x ) H(p)=\sum_xp(x)log\frac{1}{p(x)} ,若使用非真实分布 q ( x ) q(x) 来表示来自真实分布 p ( x ) p(x) 的平均编码长度,则为: H ( p , q ) = x p ( x ) l o g 1 q ( x ) H(p,q)=\sum_xp(x)log\frac{1}{q(x)} ,此时称 H ( p , q ) H(p,q) 为交叉熵。举个栗子:一个随机变量 x x ,真实分布 p ( x ) = ( 0.5 , 0.25 , 0.125 , 0.125 ) p(x)=(0.5,0.25,0.125,0.125) ,非真实分布 q ( x ) = ( 0.25 , 0.25 , 0.25 , 0.25 ) q(x)=(0.25,0.25,0.25,0.25) ,则 H ( p ) = 1.75 b i t s , H ( p , q ) = 2 b i t s H(p)=1.75bits,H(p,q)=2bits
  简化一下相对熵: D K L ( p q ) = x p ( x ) l o g p ( x ) q ( x ) = x p ( x ) l o g p ( x ) p ( x ) l o g q ( x ) = H ( p , q ) H ( p ) D_{KL}(p||q)=\sum_xp(x)log\frac{p(x)}{q(x)}=\sum_xp(x)logp(x)-p(x)logq(x)=H(p,q)-H(p)
  已经证明 D K L ( p q ) 0 D_{KL}(p||q) \geq 0 ,所以 H ( p , q ) H ( p ) H(p,q)\geq H(p) ,当 p ( x ) = q ( x ) p(x)=q(x) 时,此时交叉熵等于信息熵,当H§为常量时,最小化相对熵等价于最小化交叉熵也等价于最大似然估计。
  希望模型学到的分布和训练数据的分布尽量相同,则可以通过最小化训练数据的经验误差来降低模型的泛化误差。交叉熵可以用来计算学习模型分布和训练分布的差异,由此引出交叉熵损失。

5.交叉熵损失函数

5.1 交叉熵+Sigmoid

   二分类问题中,真实样本的标签[0,1],模型最后通常通过一个Sigmoid函数,输出一个概率值,概率越大属于正类的可能性越大,Sigmoid公式如下:
g ( s ) = 1 1 + e s g(s)=\frac{1}{1+e^{-s}}

  其中s是模型上一层的输出,这里g(s)就是交叉熵公式中的模型预测输出,表征了当前样本标签为1的概率:
y ^ = P ( y = 1 x ) \hat y=P(y=1|x)

很明显当前样本标签为0的概率为:
1 y ^ = P ( y = 0 x ) 1-\hat y=P(y=0|x)

  从极大似然的角度出发,整合在一起有:
P ( y x ) = y ^ y ( 1 y ^ ) 1 y P(y|x)=\hat y^y \cdot (1-\hat y)^{1-y}

  当真实样本标签y=0,则 P ( y = 0 x ) = 1 y ^ P(y=0|x)=1-\hat y ,当真实样本标签y=1,则 P ( y = 1 x ) = y ^ P(y=1|x)=\hat y
  引入不影响单调性的对数运算有:
l o g P ( y x ) = y l o g ( y ^ ) + ( 1 y ) l o g ( 1 y ^ ) logP(y|x)=ylog(\hat y)+(1-y)log(1-\hat y)

  希望 P ( y x ) P(y|x) 越大越好,即令 l o g P ( y x ) -logP(y|x) 越小越好,引入损失函数 L o s s = l o g P ( y x ) Loss=-logP(y|x) ,得单个样本的损失函数:
L = [ y l o g ( y ^ ) + ( 1 y ) l o g ( 1 y ^ ) ] L=-[ylog(\hat y)+(1-y)log(1-\hat y)]   N个样本的总损失函数:
L = i = 1 N y ( i ) l o g ( y ^ ( i ) ) + ( 1 y ( i ) ) l o g ( 1 y ^ ( i ) ) ] L=\sum_{i=1}^Ny^{(i)}log(\hat y^{(i)})+(1-y^{(i)})log(1-\hat y^{(i)})]

5.2 交叉熵+Softmax

  同Sigmoid一样,softmax可以作为分类任务的输出层,输出几个类别选择的概率,公式如下:
S i = e z i k e z k S_i=\frac{e^{z_i}}{\sum_ke^{z_k}}

  其中 z i z_i 表示网络的第 i i 个输出:
z i = j w i j x i j + b z_i=\sum_jw_{ij}x_{ij}+b

  其中 w i j i j b w_{ij}是第i个神经元的第j个权重,b是偏移值 ,加一个softmax函数就变成了上面的 S i S_i 公式,表示softmax函数的第 i i 个输出。
  神经网络反向传播中需要一个损失函数,表示真实值和网络估计值的误差,知道误差才能知道怎样修改网络的权重,而选择交叉熵损失的原因主要是因为求导结果简单便于计算,而且可以解决某些损失函数学习缓慢的问题,交叉熵函数表示为:
C = i y i l n S i C=-\sum_iy_ilnS_i

   y i y_i 表示真实的分类结果, S i S_i 是softmax的输出值,然后求loss对神经元输出 z i z_i 的梯度,即:
C z i \frac{\partial C}{\partial z_i}

  根据复合函数求导法则:
C z i = C S j S j z i \frac{\partial C}{\partial z_i}=\frac{\partial C}{\partial S_j} \frac{\partial S_j}{\partial z_i}

  这里是 S j S_j 而不是 S i S_i ,是因为softmax公式的分母包含了所有神经元的输出,对于不等于 i i 的其他输出也包含着 z i z_i ,所有的 S S 都要纳入计算范围,其中:
C S j = ( j y j l n S j ) S j = j y j 1 S j \frac{\partial C}{\partial S_j}=\frac{\partial(-\sum_jy_jlnS_j)}{\partial S_j}=-\sum_jy_j\frac{1}{S_j}

  后半部分分两种情况:

  1. i = j : S i z i = ( e z i k e z k ) z i = k e z k e z i ( e z i ) 2 k ( e z k ) 2 = ( e z i k e z k ) ( 1 e z i k e z k ) = S i ( 1 S i ) 若i=j:\\ \frac{\partial S_i}{\partial z_i}=\frac{\partial (\frac{e^{z_i}}{\sum_ke^{z_k}})}{\partial z_i}=\frac{\sum_ke^{z_k}e^{z_i}-(e^{z_i})^2}{\sum_k(e^{z_k})^2}\\=(\frac{e^{z_i}}{\sum_ke^{z_k}})(1-\frac{e^{z_i}}{\sum_ke^{z_k}})=S_i(1-S_i)

i ! = j : S j z i = ( e z j k e z k ) z i = e z j ( 1 k e z k ) e z i = S i S j 若i !=j:\\ \frac{\partial S_j}{\partial z_i}=\frac{\partial (\frac{e^{z_j}}{\sum_ke^{z_k}})}{\partial z_i}\\=-e^{z_j}(\frac{1}{\sum_ke^{z_k}})e^{z_i}=-S_iS_j

  上面两种情况组合起来:

C z i = ( j y j 1 S j ) S j z i = y i S i S i ( 1 S i ) + j ! = i y j S j S i S j = y i + y i S i + j ! = i y i S i = y i + S i j y j \frac{\partial C}{\partial z_i}=(-\sum_jy_j\frac{1}{S_j})\frac{\partial S_j}{\partial z_i}\\ =-\frac{y_i}{S_i}S_i(1-S_i)+\sum_{j!=i}\frac{y_j}{S_j}S_iS_j\\ =-y_i+y_iS_i+\sum_{j!=i}y_iS_i\\ =-y_i+S_i\sum_jy_j

6. 交叉熵损失pytorch实现

from torch import nn

loss = nn.CrossEntropyLoss()
input = torch.randn(3, 5, requires_grad=True)
target = torch.empty(3, dtype=torch.long).random_(5)
output = loss(input, target)
output.backward()

其中有几个参数:

weight (Tensor, optional): 每一个类的权重,可选,是一个尺寸为 C C (类别数)的张量。

size_average (bool, optional): 布尔值,可选。若为“Default”,一个批次中所有样本的损失求和后平均;若为"False", 求和不平均。

ignore_index (int, optional): 指定值对梯度没有贡献

reduce (bool, optional): 设置为"False",忽略size_average

reduction(string,optional): 为"mean",输出求平均;为"sum",求和。

参考了以下文章:

  1. 详解机器学习中的熵、条件熵、相对熵和交叉熵
  2. 简单的交叉熵损失函数
  3. 简单的softmax交叉熵损失函数求导

欢迎扫描二维码关注微信公众号 深度学习与数学   [每天获取免费的大数据、AI等相关的学习资源、经典和最新的深度学习相关的论文研读,算法和其他互联网技能的学习,概率论、线性代数等高等数学知识的回顾]
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/kevin_zhao_zl/article/details/90735991
今日推荐