backward:自动求梯度。计算小批量随机梯度。

当模型和损失函数形式较为简单时,上面的误差最小化问题的解可以直接用公式表达出来。这类解 叫作解析解(analytical solution)。本节使用的线性回归和平方误差刚好属于这个范畴。然而,大多数 深度学习模型并没有解析解,只能通过优化算法有限次迭代模型参数来尽可能降低损失函数的值。这类解叫作数值解(numerical solution)

在求数值解的优化算法中,小批量随机梯度下降(mini-batch stochastic gradient descent)在深度学习中被广泛使用。它的算法很简单:1.先选取一组模型参数的初始值,如随机选取;2.接下来对参数进行多次迭代,使每次迭代都可能降低损失函数的值。

在每次迭代中,先随机均匀采样一个由固定数目训练数据样本所组成的小批量(mini-batch)B,然后求小批量中数据样本的平均损失有关模型参数的导 数(梯度),最后用此结果与预先设定的一个正数的乘积作为模型参数在本次迭代的减小量。

在上式中,|B| 代表每个小批量中的样本个数(批量大小,batch size),η 称作学习率(learning rate)并取正数。需要强调的是,这里的批量大小和学习率的值是人为设定的,并不是通过模型训练学 出的,因此叫作超参数(hyperparameter)。我们通常所说的“调参”指的正是调节超参数,例如通过反复试错来找到超参数合适的值。在少数情况下,超参数也可以通过模型训练学出。

梯度累积

所谓梯度累积,其实很简单,我们梯度下降所用的梯度,实际上是多个样本算出来的梯度的平均值,以 batch_size=128 为例,你可以一次性算出 128 个样本的梯度然后平均,我也可以每次算 16 个样本的平均梯度,然后缓存累加起来,算够了 8 次之后,然后把总梯度除以 8,然后才执行参数更新。当然,必须累积到了 8 次之后,用 8 次的平均梯度才去更新参数,不能每算 16 个就去更新一次,不然就是 batch_size=16 了。

定义优化函数

以下的 sgd 函数实现了上一节中介绍的小批量随机梯度下降算法。它通过不断迭代模型参数来优化 损失函数。这里自动求梯度模块计算得来的梯度是一个批量样本的梯度和。我们将它除以批量大小来得到平均值。

def sgd(params, lr, batch_size):'''小批量随机梯度下降params: 权重lr: 学习率batch_size: 批大小'''for param in params:param.data -= lr * param.grad / batch_size

在训练中,我们将多次迭代模型参数。在每次迭代中,我们根据当前读取的小批量数据样本(特征 X 和标签 y ),通过调用反向函数 backward 计算小批量随机梯度,并调用优化算法 sgd 迭代模型参数。由于我们之前设批量大小 batch_size 为10,每个小批量的损失 l 的形状为(10, 1)。回忆一下自动 求梯度一节。由于变量 l 并不是一个标量,所以我们可以调用 .sum() 将其求和得到一个标量,再运行 l.backward() 得到该变量有关模型参数的梯度。注意在每次更新完参数后不要忘了将参数的梯度清零。(如果不清零,PyTorch默认会对梯度进行累加)

对于这种我们自己定义的变量,我们称之为叶子节点(leaf nodes),而基于叶子节点得到的中间或最终变量则可称之为结果节点

x = torch.tensor(1.0, requires_grad=True)
y = torch.tensor(2.0, requires_grad=True)
z = x**2+y
z.backward()
print(z, x.grad, y.grad)>>> tensor(3., grad_fn=<AddBackward0>) tensor(2.) tensor(1.)

z对x求导为:2,z对y求导为:1

可以z是一个标量,当调用它的backward方法后会根据链式法则自动计算出叶子节点的梯度值

求一个矩阵对另一矩阵的导数束手无策。

对矩阵求和不就是等价于z点乘一个一样维度的全为1的矩阵吗?即  ,而这个I也就是我们需要传入的grad_tensors参数。(点乘只是相对于一维向量而言的,对于矩阵或更高为的张量,可以看做是对每一个维度做点乘)

【点乘:对两个向量执行点乘运算,就是对这两个向量对应位一一相乘之后求和的操作】

如:

x = torch.tensor([2., 1.], requires_grad=True)
y = torch.tensor([[1., 2.], [3., 4.]], requires_grad=True)z = torch.mm(x.view(1, 2), y)
print(f"z:{z}")
z.backward(torch.Tensor([[1., 0]]), retain_graph=True)
print(f"x.grad: {x.grad}")
print(f"y.grad: {y.grad}")>>> z:tensor([[5., 8.]], grad_fn=<MmBackward>)
x.grad: tensor([[1., 3.]])
y.grad: tensor([[2., 0.],[1., 0.]])

结果解释如下:

查看梯度以及参数更新的问题

import torch
import torch.nn as nn
import numpy as np
import torch.optim as optim
from torchsummary import summary
import os
from torch.utils.data.dataset import Dataset
from torch.utils.data import DataLoader
from tqdm import tqdm# 设置一下数据集   数据集的构成是随机两个整数,形成一个加法的效果 input1 + input2 = label
class TrainDataset(Dataset):def __init__(self):super(TrainDataset, self).__init__()self.data = []for i in range(1,1000):for j in range(1,1000):self.data.append([i,j])def __getitem__(self, index):input_data = self.data[index]label = input_data[0] + input_data[1]return torch.Tensor(input_data),torch.Tensor([label])def __len__(self):return len(self.data)class TestNet(nn.Module):def __init__(self):super(TestNet, self).__init__()self.net1 = nn.Linear(2,1)def forward(self, x):x = self.net1(x)return xdef train():traindataset = TrainDataset()traindataloader = DataLoader(dataset = traindataset,batch_size=1,shuffle=False)testnet = TestNet().cuda()myloss = nn.MSELoss().cuda()optimizer = optim.SGD(testnet.parameters(), lr=0.001 )for epoch in range(100):for data,label in traindataloader :print("\n=====迭代开始=====")data = data.cuda()label = label.cuda()output = testnet(data)print("输入数据:",data)print("输出数据:",output)print("标签:",label)loss = myloss(output,label)optimizer.zero_grad()for name, parms in testnet.named_parameters():   print('-->name:', name)print('-->para:', parms)print('-->grad_requirs:',parms.requires_grad)print('-->grad_value:',parms.grad)print("===")loss.backward()optimizer.step()print("=============更新之后===========")for name, parms in testnet.named_parameters(): print('-->name:', name)print('-->para:', parms)print('-->grad_requirs:',parms.requires_grad)print('-->grad_value:',parms.grad)print("===")print(optimizer)input("=====迭代结束=====")if __name__ == '__main__':os.environ["CUDA_VISIBLE_DEVICES"] = "{}".format(3)train()

参考自:动手学深度学习(Pytorch)第2章深度学习基础-上 - 知乎

Pytorch autograd,backward详解 - 知乎

Pytorch 模型 查看网络参数的梯度以及参数更新是否正确,优化器学习率设置固定的学习率,分层设置学习率_呆呆象呆呆的博客-CSDN博客

backward理解相关推荐

  1. pytorch backward使用解析

    目录 前言 backward函数官方文档 backward理解 Jacobian矩阵 vector-Jacobian product的计算 vector-Jacobian product的例子理解 输 ...

  2. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  3. Pytorch的backward()相关理解

    Pytorch的backward()相关理解 最近一直在用pytorch做GAN相关的实验,pytorch 框架灵活易用,很适合学术界开展研究工作.  这两天遇到了一些模型参数寻优的问题,才发现自己对 ...

  4. 高效理解pytorch的backward需要scalar outputs

    利用backward时 , 可能经常遇到错误 RuntimeError: grad can be implicitly created only for scalar outputs 理解的最好方式就 ...

  5. 理解optimizer.zero_grad(), loss.backward(), optimizer.step()的作用及原理

    在用pytorch训练模型时,通常会在遍历epochs的过程中依次用到optimizer.zero_grad(),loss.backward()和optimizer.step()三个函数,如下所示: ...

  6. Pytorch的backward()与optim.setp()的理解

    @Xia Pytorch的backward()与optim.setp()的理解 backward()与optim.setp()一直对这两个函数他们之间的调用不是很清楚,花点时间应该是搞明白了. 先看最 ...

  7. 深度理解Pytorch中backward()

    转自https://blog.csdn.net/douhaoexia/article/details/78821428 接触pytorch很久了,也自认为对 backward 方法有一定了解,但看了这 ...

  8. Pytorch中的optimizer.zero_grad和loss和net.backward和optimizer.step的理解

    引言 一般训练神经网络,总是逃不开optimizer.zero_grad之后是loss(后面有的时候还会写forward,看你网络怎么写了)之后是是net.backward之后是optimizer.s ...

  9. optimizer.zero_grad(), loss.backward(), optimizer.step()的理解及使用

    optimizer.zero_grad,loss.backward,optimizer.step 用法介绍 optimizer.zero_grad(): loss.backward(): optimi ...

最新文章

  1. python 微信公众号回复图片_Python webpy微信公众号开发之 回复图文消息
  2. 那些到了 30 岁的技术人,后来都去哪了?
  3. linux中三个time:atime、mtime、ctime
  4. 【项目管理】敏捷原则
  5. 在线自动下载最新版本jquery
  6. Docker(二)-在Docker中部署Nginx实现负载均衡(视频)
  7. 在winform上内嵌入其它的程序
  8. android framework资源,Android 添加framework资源包
  9. Java同步组件之Condition,FutureTask
  10. BZOJ3240 NOI2013矩阵游戏(数论)
  11. python实现洗牌算法_【Python】洗牌算法及 random 中 shuffle 方法和 sample 方法浅析...
  12. Merge PDF - Split PDF(PDF合成)
  13. python微博爬虫程序_基于Python的新浪微博爬虫程序设计与研究
  14. https免费泛域名证书申请
  15. 卡耐基梅隆大学计算机科学课本,美国卡耐基梅隆大学计算机科学专业.pdf
  16. 机器学习笔记(四)——正则化
  17. c语言计算10以内之和,求一个C语言程序,随机产生50道10以内的加法算术题
  18. 三角形的几何公式大全_椰岛数学:初中数学公式大全(文末分享PDF)
  19. 【程序设计训练】棋盘
  20. GIT常用命令for QA

热门文章

  1. springboot 关于 Class path contains multiple SLF4J bindings.警告的解决
  2. java 代码 点到线段的最短距离
  3. Navicat工具获取操作数据库和表的SQL语句
  4. 网络服务器最基本的是文件,你可能想知道的15个网络常用基础知识
  5. 怎样设置电脑壁纸_怎样设置电脑的资料定时备份到移动硬盘里
  6. linux的备份命令及其参数,linux cpio命令参数及用法详解--linux备份文件命令
  7. python filter函数_python基础——filter函数
  8. HTML+CSS+JS实现 ❤️卡通湖面上日出动画特效❤️
  9. php time java_java 时间戳和PHP时间戳 的转换 php time()
  10. mysql慢查询日志轮转_MySQL slow log相关参数解释