交叉熵损失函数和softmax笔记
文章目录
- 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∑nP(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∑np(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∑np(xi)log(p(xi))+p(xi)和q(xi)的交叉熵 −i=1∑np(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∑np(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∑qyilogyi^(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)=∑kexp(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∑qyjlog∑kexp(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∑qyjlogk∑exp(ok)−j=1∑qyjoj(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∑qexp(ok)−j=1∑qyjoj(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=1qexp(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)=∑kexp(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)=∑jexp(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笔记相关推荐
- 交叉熵损失函数以及softmax损失函数
交叉熵损失函数以及softmax损失函数 周六总结 参考资料: https://blog.csdn.net/u014380165/article/details/77284921 https://ww ...
- 交叉熵损失函数(softmax分类器)
对于训练集中第iii张图片数据xix_ixi,在WWW下会有一个得分结果向量fyif_{y_i}fyi,则损失函数几座Li=−log(efyi∑jefj)L_i=-log(\frac{e^{f_ ...
- softmax函数与交叉熵损失函数
本文主要介绍了当前机器学习模型中广泛应用的交叉熵损失函数与softmax激励函数. 这个损失函数主要应用于多分类问题,用于衡量预测值与实际值之间的相似程度. 交叉熵损失函数定义如下: LCE(y^,y ...
- SoftMax函数,交叉熵损失函数与熵,对数似然函数
深度学习以及机器学习中都会用到SoftMax函数,交叉熵损失函数与熵,对数似然函数等一些数学方面的知识,此文作为个人学习笔记. 1.softmax函数 (1)定义 多分类问题中,我们可以使用SoftM ...
- 二分类交叉熵损失函数python_【深度学习基础】第二课:softmax分类器和交叉熵损失函数...
[深度学习基础]系列博客为学习Coursera上吴恩达深度学习课程所做的课程笔记. 本文为原创文章,未经本人允许,禁止转载.转载请注明出处. 1.线性分类 如果我们使用一个线性分类器去进行图像分类该怎 ...
- 深度学习中softmax交叉熵损失函数的理解
1. softmax层的作用 通过神经网络解决多分类问题时,最常用的一种方式就是在最后一层设置n个输出节点,无论在浅层神经网络还是在CNN中都是如此,比如,在AlexNet中最后的输出层有1000个节 ...
- 简单易懂的softmax交叉熵损失函数求导
简单易懂的softmax交叉熵损失函数求导 本博客转自:http://m.blog.csdn.net/qian99/article/details/78046329 来写一个softmax求导的推导过 ...
- 人脸识别-Loss-2010:Softmax Loss(Softmax激活函数 + “交叉熵损失函数”)【样本3真实标签为c_5,则样本3的损失:loss_3=-log(\hat{y}_5^3)】
一般一个CNN网络主要包含卷积层,池化层(pooling),全连接层,损失层等. 全连接层:等号左边部分就是全连接层做的事, W W W 是全连接层的参数,我们也称为权值, X X X 是全连接层的输 ...
- 交叉熵损失函数分类_PyTorch学习笔记——多分类交叉熵损失函数
理解交叉熵 关于样本集的两个概率分布p和q,设p为真实的分布,比如[1, 0, 0]表示当前样本属于第一类,q为拟合的分布,比如[0.7, 0.2, 0.1]. 按照真实分布p来衡量识别一个样本所需的 ...
最新文章
- 开发日记-20190409 关键词 理想activity模型
- python小游戏代码大全-Python实现打砖块小游戏代码实例
- 用时间分类能量再用能量分类时间
- spring 源码分析01
- __doPostBack用法 【csdn】
- 应用的生命周期各个程序运行状态时代理的回调
- matlab mat文件
- 动态规划之袋鼠过河问题
- 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_03 斗地主案例(单列)_1_斗地主案例的需求分析...
- 深度学习模型的前馈运算与反馈运算
- LeetCode题解之Missing Number
- 【暴力破解】字典工具
- 2018python教程百度云盘_python基础教程视频网盘_python教学视频2018百度云
- python 对象的销毁_python对象销毁(垃圾回收)
- pybind11学习 | 面向对象编程
- 用HTML实现旋转地球,使用CSS3和贴图实现的旋转的蓝色地球
- EPLAN 设备选择
- 10套苹果CMS模板打包下载/苹果CMS视频影视网站源码下载
- 女生无法拒绝的表白拼图
- C语言结构体大小计算
热门文章
- 修改网站TITLE被降权恢复过程
- Police Station
- itop4412的uboot
- STM32通过ESP8266与平台通信——远程控制STM32——TLINK
- 传统图像处理之随机脉冲噪声检测
- qq飞车手游服务器维修,QQ飞车手游:1年半都没修复,这BUG能卡十秒,官方不管了?...
- 【招聘】百度AI算法和产品招聘专场
- Axure知识点:如何制作轮播图效果(以泉州师范学院官网为例)
- Slowfast环境配置问题 | 安装PyAV报错An error occurred while installing package ‘conda-forge::olefile-0.46-pyh9f
- Java如何快速入门?Java初学者从入门到精通必看!