PyTorch的SoftMax交叉熵损失和梯度用法


Posted in Python onJanuary 15, 2020

在PyTorch中可以方便的验证SoftMax交叉熵损失和对输入梯度的计算

关于softmax_cross_entropy求导的过程,可以参考HERE

示例

# -*- coding: utf-8 -*-
import torch
import torch.autograd as autograd
from torch.autograd import Variable
import torch.nn.functional as F
import torch.nn as nn
import numpy as np

# 对data求梯度, 用于反向传播
data = Variable(torch.FloatTensor([[1.0, 2.0, 3.0], [1.0, 2.0, 3.0], [1.0, 2.0, 3.0]]), requires_grad=True)

# 多分类标签 one-hot格式
label = Variable(torch.zeros((3, 3)))
label[0, 2] = 1
label[1, 1] = 1
label[2, 0] = 1
print(label)

# for batch loss = mean( -sum(Pj*logSj) )
# for one : loss = -sum(Pj*logSj)
loss = torch.mean(-torch.sum(label * torch.log(F.softmax(data, dim=1)), dim=1))

loss.backward()
print(loss, data.grad)

输出:

tensor([[ 0., 0., 1.],
    [ 0., 1., 0.],
    [ 1., 0., 0.]])
# loss:损失 和 input's grad:输入的梯度
tensor(1.4076) tensor([[ 0.0300, 0.0816, -0.1116],
    [ 0.0300, -0.2518, 0.2217],
    [-0.3033, 0.0816, 0.2217]])

注意

对于单输入的loss 和 grad

data = Variable(torch.FloatTensor([[1.0, 2.0, 3.0]]), requires_grad=True)


label = Variable(torch.zeros((1, 3)))
#分别令不同索引位置label为1
label[0, 0] = 1
# label[0, 1] = 1
# label[0, 2] = 1
print(label)

# for batch loss = mean( -sum(Pj*logSj) )
# for one : loss = -sum(Pj*logSj)
loss = torch.mean(-torch.sum(label * torch.log(F.softmax(data, dim=1)), dim=1))

loss.backward()
print(loss, data.grad)

其输出:

# 第一组:
lable: tensor([[ 1., 0., 0.]])
loss: tensor(2.4076) 
grad: tensor([[-0.9100, 0.2447, 0.6652]])

# 第二组:
lable: tensor([[ 0., 1., 0.]])
loss: tensor(1.4076) 
grad: tensor([[ 0.0900, -0.7553, 0.6652]])

# 第三组:
lable: tensor([[ 0., 0., 1.]])
loss: tensor(0.4076) 
grad: tensor([[ 0.0900, 0.2447, -0.3348]])

"""
解释:
对于输入数据 tensor([[ 1., 2., 3.]]) softmax之后的结果如下
tensor([[ 0.0900, 0.2447, 0.6652]])
交叉熵求解梯度推导公式可知 s[0, 0]-1, s[0, 1]-1, s[0, 2]-1 是上面三组label对应的输入数据梯度
"""

pytorch提供的softmax, 和log_softmax 关系

# 官方提供的softmax实现
In[2]: import torch
 ...: import torch.autograd as autograd
 ...: from torch.autograd import Variable
 ...: import torch.nn.functional as F
 ...: import torch.nn as nn
 ...: import numpy as np
In[3]: data = Variable(torch.FloatTensor([[1.0, 2.0, 3.0]]), requires_grad=True)
In[4]: data
Out[4]: tensor([[ 1., 2., 3.]])
In[5]: e = torch.exp(data)
In[6]: e
Out[6]: tensor([[ 2.7183,  7.3891, 20.0855]])
In[7]: s = torch.sum(e, dim=1)
In[8]: s
Out[8]: tensor([ 30.1929])
In[9]: softmax = e/s
In[10]: softmax
Out[10]: tensor([[ 0.0900, 0.2447, 0.6652]])
In[11]: # 等同于 pytorch 提供的 softmax 
In[12]: org_softmax = F.softmax(data, dim=1)
In[13]: org_softmax
Out[13]: tensor([[ 0.0900, 0.2447, 0.6652]])
In[14]: org_softmax == softmax # 计算结果相同
Out[14]: tensor([[ 1, 1, 1]], dtype=torch.uint8)

# 与log_softmax关系
# log_softmax = log(softmax)
In[15]: _log_softmax = torch.log(org_softmax) 
In[16]: _log_softmax
Out[16]: tensor([[-2.4076, -1.4076, -0.4076]])
In[17]: log_softmax = F.log_softmax(data, dim=1)
In[18]: log_softmax
Out[18]: tensor([[-2.4076, -1.4076, -0.4076]])

官方提供的softmax交叉熵求解结果

# -*- coding: utf-8 -*-
import torch
import torch.autograd as autograd
from torch.autograd import Variable
import torch.nn.functional as F
import torch.nn as nn
import numpy as np

data = Variable(torch.FloatTensor([[1.0, 2.0, 3.0], [1.0, 2.0, 3.0], [1.0, 2.0, 3.0]]), requires_grad=True)
log_softmax = F.log_softmax(data, dim=1)

label = Variable(torch.zeros((3, 3)))
label[0, 2] = 1
label[1, 1] = 1
label[2, 0] = 1
print("lable: ", label)

# 交叉熵的计算方式之一
loss_fn = torch.nn.NLLLoss() # reduce=True loss.sum/batch & grad/batch
# NLLLoss输入是log_softmax, target是非one-hot格式的label
loss = loss_fn(log_softmax, torch.argmax(label, dim=1))
loss.backward()
print("loss: ", loss, "\ngrad: ", data.grad)

"""
# 交叉熵计算方式二
loss_fn = torch.nn.CrossEntropyLoss() # the target label is NOT an one-hotted
#CrossEntropyLoss适用于分类问题的损失函数
#input:没有softmax过的nn.output, target是非one-hot格式label
loss = loss_fn(data, torch.argmax(label, dim=1))
loss.backward()
print("loss: ", loss, "\ngrad: ", data.grad)
"""
"""

输出

lable: tensor([[ 0., 0., 1.],
    [ 0., 1., 0.],
    [ 1., 0., 0.]])
loss: tensor(1.4076) 
grad: tensor([[ 0.0300, 0.0816, -0.1116],
    [ 0.0300, -0.2518, 0.2217],
    [-0.3033, 0.0816, 0.2217]])

通过和示例的输出对比, 发现两者是一样的

以上这篇PyTorch的SoftMax交叉熵损失和梯度用法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中常见的数据类型小结
Aug 29 Python
Python使用自带的ConfigParser模块读写ini配置文件
Jun 26 Python
Win7下Python与Tensorflow-CPU版开发环境的安装与配置过程
Jan 04 Python
Python获取本机所有网卡ip,掩码和广播地址实例代码
Jan 22 Python
Python中循环后使用list.append()数据被覆盖问题的解决
Jul 01 Python
python 实现读取一个excel多个sheet表并合并的方法
Feb 12 Python
基于Python的PIL库学习详解
May 10 Python
解决Pycharm后台indexing导致不能run的问题
Jun 27 Python
python 画函数曲线示例
Dec 04 Python
如何基于python实现归一化处理
Jan 20 Python
Tensorflow 使用pb文件保存(恢复)模型计算图和参数实例详解
Feb 11 Python
Python实现名片管理系统
Feb 14 Python
pytorch方法测试——激活函数(ReLU)详解
Jan 15 #Python
pytorch的batch normalize使用详解
Jan 15 #Python
pytorch方法测试详解——归一化(BatchNorm2d)
Jan 15 #Python
Python 中@property的用法详解
Jan 15 #Python
Python字符串中删除特定字符的方法
Jan 15 #Python
计算pytorch标准化(Normalize)所需要数据集的均值和方差实例
Jan 15 #Python
pytorch 图像中的数据预处理和批标准化实例
Jan 15 #Python
You might like
VOLVO车载收音机
2021/03/02 无线电
PHP调用三种数据库的方法(3)
2006/10/09 PHP
PHP的Laravel框架中使用消息队列queue及异步队列的方法
2016/03/21 PHP
静态html文件执行php语句的方法(推荐)
2016/11/21 PHP
VSCode+PHPstudy配置PHP开发环境的步骤详解
2020/08/20 PHP
漂亮的提示信息(带箭头)
2007/03/21 Javascript
用js实现的页面关键字密度查询代码
2007/12/27 Javascript
js querySelector和getElementById通过id获取元素的区别
2012/04/20 Javascript
JS 获取浏览器和屏幕宽高等信息的实现思路及代码
2013/07/31 Javascript
JavaScript获取图片的原始尺寸以宽度为例
2014/05/04 Javascript
解决jQuery使用JSONP时产生的错误
2015/12/02 Javascript
CodeMirror js代码加亮使用总结
2017/03/25 Javascript
vue项目中jsonp跨域获取qq音乐首页推荐问题
2018/05/30 Javascript
redux.js详解及基本使用
2019/05/24 Javascript
深入了解JavaScript 私有化
2019/05/30 Javascript
python实现数组插入新元素的方法
2015/05/22 Python
PyQt5实现拖放功能
2018/04/25 Python
numpy中矩阵合并的实例
2018/06/15 Python
python 字段拆分详解
2019/12/17 Python
python3中sorted函数里cmp参数改变详解
2020/03/12 Python
Django 允许局域网中的机器访问你的主机操作
2020/05/13 Python
Pytorch实验常用代码段汇总
2020/11/19 Python
python 用Matplotlib作图中有多个Y轴
2020/11/28 Python
python中time tzset()函数实例用法
2021/02/18 Python
详解CSS3+JS完美实现放大镜模式
2020/12/03 HTML / CSS
KELLER SPORTS荷兰:在线订购最好的运动产品
2020/10/13 全球购物
毕业生实习鉴定
2013/12/11 职场文书
春节请假条
2014/04/11 职场文书
五水共治捐款倡议书
2014/05/14 职场文书
中小学校园安全广播稿
2014/09/29 职场文书
工作收入证明模板
2014/10/10 职场文书
海南召开党的群众路线教育实践活动总结大会新闻稿
2014/10/21 职场文书
学院党委班子四风问题自查报告及整改措施
2014/10/25 职场文书
2014年材料员工作总结
2014/11/19 职场文书
2015年中学总务处工作总结
2015/07/22 职场文书
《艾尔登法环》Boss腐烂树灵很有可能是《黑暗之魂3》的一个废案
2022/04/11 其他游戏