文章目录

  • 1. 交叉熵定义
  • 2.交叉熵损失思考
  • 3.交叉熵损失代码
  • 4. softmax 回归的简洁实现
    • 4.1 代码
    • 4.2 结果
  • 5. torch.nn.Softmax代码测试
    • 5.1 说明

注:本文代码参考李沐书籍,这里只做代码解析。

1. 交叉熵定义

交叉熵是信息论中的一个重要概念,主要用于度量两个概率分布间的差异性,要理解交叉熵,需要先了解下面几个概念

  • 信息量
    香农大佬说过"信息是用来消除随机不确定的东西",就是用信息量来表示一个事件从不确定到确定这种状态的量度单位。信息量的大小和信息发生的概率成反比。假设某一事件发生的概率为P(X),我们将信息量I(X)定义如下
    I ( X ) = − log ⁡ ( P ( X ) ) (1) I(X)=-\log(P(X))\tag1 I(X)=−log(P(X))(1)
  • 信息熵 H(X)
    信息熵表示的信息量的期望的和,我们知道,期望就是概率乘以值;那么可以得到。
    H ( X ) = − ∑ i = 1 n P ( x i ) log ⁡ P ( x i ) (2) H(X)=-\sum_{i=1}^{n}P(x_i)\log P(x_i)\tag2 H(X)=−i=1∑n​P(xi​)logP(xi​)(2)
    注:当我们求得的结果为两种情况,即二项式分布时候, n =2 时。那么
    H ( X ) = − [ P ( x i ) log ⁡ P ( x i ) + ( 1 − P ( x i ) ) log ⁡ ( 1 − P ( x i ) ) ] (3) H(X)=-[P(x_i)\log P(x_i)+(1-P(x_i))\log(1-P(x_i))]\tag3 H(X)=−[P(xi​)logP(xi​)+(1−P(xi​))log(1−P(xi​))](3)
  • 相对熵(KL 散度)
    如果对于同一个随机变量X有两个单独概率分布,P(X) 和 Q(X),我们通过 KL散度来描述两个概率分布之间的差异。那为什么要这样做呢?因为我们已经有了概率分布 P(X)的具体参数,我们希望对于未知的概率分布 Q(X) 的进行分析,最好是有一个参数 KL 散度 来描述这两个概率分布的差异,当 KL散度很小时,那么我们就可以说明这两个分布相似。
    D K L ( p ∣ ∣ q ) = ∑ i = 1 n p ( x i ) log ⁡ ( p ( x i ) q ( x i ) ) (4) D_{KL}(p||q)=\sum_{i=1}^np(x_i)\log{(\frac{p(x_i)}{q(x_i)})}\tag 4 DKL​(p∣∣q)=i=1∑n​p(xi​)log(q(xi​)p(xi​)​)(4)
    D K L ( p ∣ ∣ q ) = ∑ i = 1 n p ( x i ) log ⁡ ( p ( x i ) ) ⏟ p ( x i ) 的 信 息 熵 + − ∑ i = 1 n p ( x i ) log ⁡ ( q ( x i ) ) ⏟ p ( x i ) 和 q ( x i ) 的 交 叉 熵 (5) D_{KL}(p||q)=\underbrace{\sum_{i=1}^np(x_i)\log{(p(x_i))}}_{p(x_i)的信息熵}+\underbrace{-\sum_{i=1}^np(x_i)\log{(q(x_i))}}_{p(x_i)和q(x_i)的交叉熵}\tag {5} DKL​(p∣∣q)=p(xi​)的信息熵 i=1∑n​p(xi​)log(p(xi​))​​+p(xi​)和q(xi​)的交叉熵 −i=1∑n​p(xi​)log(q(xi​))​​(5)
    注:这里我们就出现了交叉熵了:
  • 交叉熵:
    − ∑ i = 1 n p ( x i ) log ⁡ ( q ( x i ) ) (6) -\sum_{i=1}^np(x_i)\log{(q(x_i))}\tag{6} −i=1∑n​p(xi​)log(q(xi​))(6)

2.交叉熵损失思考

那为什么交叉熵能够表示两个概率之间的差异呢?为什么它就很方便的表达了。这里我们假设这里的 p ( x i ) p(x_i) p(xi​)为模型中实际的概率标签 y i y_i yi​, q ( x i ) q(x_i) q(xi​)为模型预测的 y i ^ \hat{y_i} yi​^​,假设 类别数n = q代入上式可得:
l ( y i , y i ^ ) = − ∑ j = 1 q y i log ⁡ y i ^ (7) l(y_i,\hat{y_i})=-\sum_{j=1}^q y_i\log{\hat{y_i}}\tag{7} l(yi​,yi​^​)=−j=1∑q​yi​logyi​^​(7)
假设模型预测的 y i ^ \hat{y_i} yi​^​是通过 softmax运算得到的,满足如下:
y j ^ = s o f t m a x ( o j ) = e x p ( o j ) ∑ k e x p ( o k ) (8) \hat{y_j}=softmax(o_j)=\frac{exp(o_j)}{\sum_kexp(o_k)}\tag{8} yj​^​=softmax(oj​)=∑k​exp(ok​)exp(oj​)​(8)
将 (8) 带入到 (7) 可得:
l ( y i , y i ^ ) = − ∑ j = 1 q y j log ⁡ e x p ( o j ) ∑ k e x p ( o k ) (9) l(y_i,\hat{y_i})=-\sum_{j=1}^q y_j\log{\frac{exp(o_j)}{\sum_kexp(o_k)}}\tag{9} l(yi​,yi​^​)=−j=1∑q​yj​log∑k​exp(ok​)exp(oj​)​(9)
l ( y i , y i ^ ) = ∑ j = 1 q y j log ⁡ ∑ k e x p ( o k ) − ∑ j = 1 q y j o j (10) l(y_i,\hat{y_i})=\sum_{j=1}^q y_j\log\sum_kexp(o_k)-\sum_{j=1}^qy_jo_j\tag{10} l(yi​,yi​^​)=j=1∑q​yj​logk∑​exp(ok​)−j=1∑q​yj​oj​(10)
注:当我们用 one-hot 独热编码表示 y i y_i yi​时,那么除了第 j 项为1,其他均为 0 ,则:
l ( y i , y i ^ ) = log ⁡ ∑ k = 1 q e x p ( o k ) − ∑ j = 1 q y j o j (11) l(y_i,\hat{y_i})=\log\sum_{k=1}^qexp(o_k)-\sum_{j=1}^qy_jo_j\tag{11} l(yi​,yi​^​)=logk=1∑q​exp(ok​)−j=1∑q​yj​oj​(11)
对上式求导可得:
∂ l ( y i , y i ^ ) ∂ o j = e x p ( o j ) ∑ k = 1 q e x p ( o k ) − y j (12) \frac{\partial l(y_i,\hat{y_i})}{\partial o_j}=\frac{exp(o_j)}{\sum_{k=1}^qexp(o_k)}-y_j\tag{12} ∂oj​∂l(yi​,yi​^​)​=∑k=1q​exp(ok​)exp(oj​)​−yj​(12)
注意:此时我们发现 y j ^ = s o f t m a x ( o j ) = e x p ( o j ) ∑ k e x p ( o k ) \hat{y_j}=softmax(o_j)=\frac{exp(o_j)}{\sum_kexp(o_k)} yj​^​=softmax(oj​)=∑k​exp(ok​)exp(oj​)​
∂ l ( y i , y i ^ ) ∂ o j = y j ^ − y j (13) \frac{\partial l(y_i,\hat{y_i})}{\partial o_j}=\hat{y_j}-y_j\tag{13} ∂oj​∂l(yi​,yi​^​)​=yj​^​−yj​(13)
重点:上式说明了,当我们用交叉熵表示损失函数的时候,我们模型中预测用到 softmax 时候,交叉熵的导数即为预测标签 y i ^ \hat{y_i} yi​^​与真实标签 y i y_i yi​的差。这样就非常方便了,我们只需要用交叉熵为损失函数就可以了。
我们可以类比最小二乘法的损失函数 :
l ( y i , y i ^ ) = 1 2 ( y j ^ − y j ) 2 (14) l(y_i,\hat{y_i})=\frac{1}{2}(\hat{y_j}-y_j)^2\tag{14} l(yi​,yi​^​)=21​(yj​^​−yj​)2(14)
∂ l ( y i , y i ^ ) ∂ o j = y j ^ − y j (15) \frac{\partial l(y_i,\hat{y_i})}{\partial o_j}=\hat{y_j}-y_j\tag{15} ∂oj​∂l(yi​,yi​^​)​=yj​^​−yj​(15)
这样类比后,我们发现,用交叉熵做损失函数也能跟用最小二乘法表示一样实现。

3.交叉熵损失代码

  • 代码核心思想:交叉熵采用真实标签的预测概率的负对数似然
    举例1 :
    假设我们有真实标签 y i y_i yi​,用它来表示样本中真实样本的位置
y = torch.tensor([0,2]) # 0,2 表示样本中真实正确标签的位置

我们用 y i ^ \hat{y_i} yi​^​来表示样本中各个类别的概率分布,并用 y 来告诉程序哪个概率是正确的。

y_hat = torch.tensor([[0.1, 0.3, 0.6], [0.3, 0.2, 0.5]])

结合起来如下:

y_hat[[0, 1], y] # 等价于 y_hat[[0, 1], [0,2]]
# 就是 0 对应于0; 1 对应于 2
# 第 0 个 [0.1, 0.3, 0.6] 中选择 第 0 个 ,即 0.1
# 第 1 个 [0.3, 0.2, 0.5] 中选择 第 2 个 ,即 0.5
# 所以以上代码输出结果为:tensor([0.1000, 0.5000])

那么我们就可以将上述得到的值求负对数似然即可

  • 交叉熵代码
def cross_entropy(y_hat, y):return -torch.log(y_hat[range(len(y_hat)), y])

4. softmax 回归的简洁实现

我们这里应用pytorch 框架的相关函数来搭建 softmax 回归,在搭建过程中十分的方便。

4.1 代码

# -*- coding: utf-8 -*-
# @Project: zc
# @Author: zc
# @File name: softmax的简洁实现
# @Create time: 2021/11/22 18:09# 1.导入相关库
import torch
from torch import nn
from d2l import torch as d2l
import matplotlib.pyplot as plt# 2.将数据导入并生成train_iter训练集,test_iter 测试集
batch_size = 256  # 设置批量大小
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)  # 将数据加载到迭代器中# 3. 定义模型
# PyTorch不会隐式地调整输⼊的形状。因此,
# 我们在线性层前定义了展平层(flatten),来调整⽹络输⼊的形状
net = nn.Sequential(nn.Flatten(), nn.Linear(784, 10)
)# 4.初始化模型值
def init_weights(m):if type(m) == nn.Linear:nn.init.normal_(m.weight, std=0.01)net.apply(init_weights)# 5. 定义损失函数loss = nn.CrossEntropyLoss()# 6. 定义优化器trainer = torch.optim.SGD(net.parameters(), lr=0.1)# 7.开始训练模型
num_epochs = 10  # 训练次数为 10# 8.开始训练
d2l.train_ch3(net=net, train_iter=train_iter, test_iter=test_iter, loss=loss, num_epochs=num_epochs, updater=trainer)
# 9.预测
d2l.predict_ch3(net,test_iter)
plt.show() # 显示结果

4.2 结果

  • 训练
  • 预测

5. torch.nn.Softmax代码测试

5.1 说明

softmax的作用是将张量中的值变成非负值,并且总和值为1;

  • 官网解释
    将Softmax函数应用于一个n维输入张量,对其进行缩放,使n维输出张量的元素位于[0,1]范围内,总和为1
  • 公式
    S o f t m a x ( x i ) = exp ⁡ ( x i ) ∑ j exp ⁡ ( x j ) Softmax(x_i)=\frac{\exp(x_i)}{\sum_j\exp(x_j)} Softmax(xi​)=∑j​exp(xj​)exp(xi​)​
  • 函数
torch.nn.Softmax(dim=None)
  • dim
    表示对指定维度进行Softmax计算
    dim=0,是 行与行 之间进行 Softmax 计算;dim=1,是 列与列 之间进行 Softmax 计算;
  • 代码
import torch
from torch.nn import functional as Fx = torch.Tensor([[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]])# dim=0 ,先将此x[i]求指数再除以行与行之间的指数值的和
# y_dim_0[0,0] = [exp^(1)]/{[exp^(1)]+[exp^(1)]+[exp^(1)]}=0.333
y_dim_0 = F.softmax(x, dim=0)
# dim=1 ,先将此x[i]求指数再除以列与列之间的指数值的和
# y_dim_1[0,0] = [exp^(1)]/{[exp^(1)]+[exp^(2)]+[exp^(3)]+[exp^(4)]}=0.321
y_dim_1 = F.softmax(x, dim=1)
print(f'x={x}')
print(f'x={x.shape}')
print(f'y_dim_0={y_dim_0}')
print(f'y_dim_0_shape={y_dim_0.shape}')
print(f'y_dim_1={y_dim_1}')
print(f'y_dim_1_shape={y_dim_1.shape}')
  • 结果
x=tensor([[1., 2., 3., 4.],[1., 2., 3., 4.],[1., 2., 3., 4.]])
x=torch.Size([3, 4])
y_dim_0=tensor([[0.3333, 0.3333, 0.3333, 0.3333],[0.3333, 0.3333, 0.3333, 0.3333],[0.3333, 0.3333, 0.3333, 0.3333]])
y_dim_0_shape=torch.Size([3, 4])
y_dim_1=tensor([[0.0321, 0.0871, 0.2369, 0.6439],[0.0321, 0.0871, 0.2369, 0.6439],[0.0321, 0.0871, 0.2369, 0.6439]])
y_dim_1_shape=torch.Size([3, 4])
  • 小结
    程序计算的结果跟分析的一致。

交叉熵损失函数和softmax笔记相关推荐

  1. 交叉熵损失函数以及softmax损失函数

    交叉熵损失函数以及softmax损失函数 周六总结 参考资料: https://blog.csdn.net/u014380165/article/details/77284921 https://ww ...

  2. 交叉熵损失函数(softmax分类器)

    对于训练集中第iii张图片数据xix_ixi​,在WWW下会有一个得分结果向量fyif_{y_i}fyi​​,则损失函数几座Li=−log(efyi∑jefj)L_i=-log(\frac{e^{f_ ...

  3. softmax函数与交叉熵损失函数

    本文主要介绍了当前机器学习模型中广泛应用的交叉熵损失函数与softmax激励函数. 这个损失函数主要应用于多分类问题,用于衡量预测值与实际值之间的相似程度. 交叉熵损失函数定义如下: LCE(y^,y ...

  4. SoftMax函数,交叉熵损失函数与熵,对数似然函数

    深度学习以及机器学习中都会用到SoftMax函数,交叉熵损失函数与熵,对数似然函数等一些数学方面的知识,此文作为个人学习笔记. 1.softmax函数 (1)定义 多分类问题中,我们可以使用SoftM ...

  5. 二分类交叉熵损失函数python_【深度学习基础】第二课:softmax分类器和交叉熵损失函数...

    [深度学习基础]系列博客为学习Coursera上吴恩达深度学习课程所做的课程笔记. 本文为原创文章,未经本人允许,禁止转载.转载请注明出处. 1.线性分类 如果我们使用一个线性分类器去进行图像分类该怎 ...

  6. 深度学习中softmax交叉熵损失函数的理解

    1. softmax层的作用 通过神经网络解决多分类问题时,最常用的一种方式就是在最后一层设置n个输出节点,无论在浅层神经网络还是在CNN中都是如此,比如,在AlexNet中最后的输出层有1000个节 ...

  7. 简单易懂的softmax交叉熵损失函数求导

    简单易懂的softmax交叉熵损失函数求导 本博客转自:http://m.blog.csdn.net/qian99/article/details/78046329 来写一个softmax求导的推导过 ...

  8. 人脸识别-Loss-2010:Softmax Loss(Softmax激活函数 + “交叉熵损失函数”)【样本3真实标签为c_5,则样本3的损失:loss_3=-log(\hat{y}_5^3)】

    一般一个CNN网络主要包含卷积层,池化层(pooling),全连接层,损失层等. 全连接层:等号左边部分就是全连接层做的事, W W W 是全连接层的参数,我们也称为权值, X X X 是全连接层的输 ...

  9. 交叉熵损失函数分类_PyTorch学习笔记——多分类交叉熵损失函数

    理解交叉熵 关于样本集的两个概率分布p和q,设p为真实的分布,比如[1, 0, 0]表示当前样本属于第一类,q为拟合的分布,比如[0.7, 0.2, 0.1]. 按照真实分布p来衡量识别一个样本所需的 ...

最新文章

  1. 开发日记-20190409 关键词 理想activity模型
  2. python小游戏代码大全-Python实现打砖块小游戏代码实例
  3. 用时间分类能量再用能量分类时间
  4. spring 源码分析01
  5. __doPostBack用法 【csdn】
  6. 应用的生命周期各个程序运行状态时代理的回调
  7. matlab mat文件
  8. 动态规划之袋鼠过河问题
  9. 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_03 斗地主案例(单列)_1_斗地主案例的需求分析...
  10. 深度学习模型的前馈运算与反馈运算
  11. LeetCode题解之Missing Number
  12. 【暴力破解】字典工具
  13. 2018python教程百度云盘_python基础教程视频网盘_python教学视频2018百度云
  14. python 对象的销毁_python对象销毁(垃圾回收)
  15. pybind11学习 | 面向对象编程
  16. 用HTML实现旋转地球,使用CSS3和贴图实现的旋转的蓝色地球
  17. EPLAN 设备选择
  18. 10套苹果CMS模板打包下载/苹果CMS视频影视网站源码下载
  19. 女生无法拒绝的表白拼图
  20. C语言结构体大小计算

热门文章

  1. 修改网站TITLE被降权恢复过程
  2. Police Station
  3. itop4412的uboot
  4. STM32通过ESP8266与平台通信——远程控制STM32——TLINK
  5. 传统图像处理之随机脉冲噪声检测
  6. qq飞车手游服务器维修,QQ飞车手游:1年半都没修复,这BUG能卡十秒,官方不管了?...
  7. 【招聘】百度AI算法和产品招聘专场
  8. Axure知识点:如何制作轮播图效果(以泉州师范学院官网为例)
  9. Slowfast环境配置问题 | 安装PyAV报错An error occurred while installing package ‘conda-forge::olefile-0.46-pyh9f
  10. Java如何快速入门?Java初学者从入门到精通必看!