【偷偷卷死小伙伴Pytorch20天】-【day6】-【自动微分机制】

网友投稿 269 2022-08-26


【偷偷卷死小伙伴Pytorch20天】-【day6】-【自动微分机制】

系统教程20天拿下Pytorch​ 最近和中哥、会哥进行一个小打卡活动,20天pytorch,这是第6天。欢迎一键三连。

文章目录

​​一、利用backward方法求导数​​

​​1, 标量的反向传播​​​​2, 非标量的反向传播​​​​3, 非标量的反向传播可以用标量的反向传播实现​​

​​二、利用autograd.grad函数求导数​​​​三、利用自动微分和优化器求最小值​​​​总结​​

神经网络通常依赖反向传播求梯度来更新网络参数,求梯度过程通常是一件非常复杂而容易出错的事情。

而深度学习框架可以帮助我们自动地完成这种求梯度运算。

Pytorch一般通过反向传播 backward 方法 实现这种求梯度计算。该方法求得的梯度将存在对应自变量张量的grad属性下。

除此之外,也能够调用torch.autograd.grad 函数来实现求梯度计算。

这就是Pytorch的自动微分机制。

一、利用backward方法求导数

backward 方法通常在一个标量张量上调用,该方法求得的梯度将存在对应自变量张量的grad属性下。

如果调用的张量非标量,则要传入一个和它同形状 的gradient参数张量。

相当于用该gradient参数张量与调用张量作向量点乘,得到的标量结果再反向传播。

1, 标量的反向传播

import numpy as np import torch # f(x) = a*x**2 + b*x + c的导数x = torch.tensor(0.0,requires_grad = True) # x需要被求导a = torch.tensor(1.0)b = torch.tensor(-2.0)c = torch.tensor(1.0)y = a*torch.pow(x,2) + b*x + c y.backward()dy_dx = x.gradprint(dy_dx)

requires_grad = True可以将其理解为开启自变量

2, 非标量的反向传播

import numpy as np import torch # f(x) = a*x**2 + b*x + cx = torch.tensor([[0.0,0.0],[1.0,2.0]],requires_grad = True) # x需要被求导a = torch.tensor(1.0)b = torch.tensor(-2.0)c = torch.tensor(1.0)y = a*torch.pow(x,2) + b*x + c gradient = torch.tensor([[1.0,1.0],[1.0,1.0]])print("x:\n",x)print("y:\n",y)y.backward(gradient = gradient)x_grad = x.gradprint("x_grad:\n",x_grad)

对于非标量来说,是求点积,到最后出来一个标量才能求导

3, 非标量的反向传播可以用标量的反向传播实现

这里也就是解释了 2, 非标量的反向传播

import numpy as np import torch # f(x) = a*x**2 + b*x + cx = torch.tensor([[0.0,0.0],[1.0,2.0]],requires_grad = True) # x需要被求导a = torch.tensor(1.0)b = torch.tensor(-2.0)c = torch.tensor(1.0)y = a*torch.pow(x,2) + b*x + c gradient = torch.tensor([[1.0,1.0],[1.0,1.0]])z = torch.sum(y*gradient)# y.backward(gradient=gradient)print("x:",x)print("y:",y)z.backward()x_grad = x.gradprint("x_grad:\n",x_grad)

二、利用autograd.grad函数求导数

import numpy as np import torch # f(x) = a*x**2 + b*x + c的导数x = torch.tensor(0.0,requires_grad = True) # x需要被求导a = torch.tensor(1.0,requires_grad = True)b = torch.tensor(-2.0)c = torch.tensor(1.0)y = a*torch.pow(x,2) + b*x + c# create_graph 设置为 True 将允许创建更高阶的导数 dy_dx = torch.autograd.grad(y,x,create_graph=True) # 返回数组print(dy_dx)# 求二阶导数dy2_dx2 = torch.autograd.grad(dy_dx,x)[0] print(dy2_dx2.data)

import numpy as np import torch x1 = torch.tensor(1.0,requires_grad = True) # x需要被求导x2 = torch.tensor(2.0,requires_grad = True)y1 = x1*x2y2 = x1+x2# 允许同时对多个自变量求导数(dy1_dx1,dy1_dx2) = torch.autograd.grad(outputs=y1,inputs = [x1,x2],retain_graph = True)print(dy1_dx1,dy1_dx2)# 如果有多个因变量,相当于把多个因变量的梯度结果求和(dy12_dx1,dy12_dx2) = torch.autograd.grad(outputs=[y1,y2],inputs = [x1,x2])print(dy12_dx1,dy12_dx2)

三、利用自动微分和优化器求最小值

import numpy as np import torch # f(x) = a*x**2 + b*x + c的最小值x = torch.tensor(0.0,requires_grad = True) # x需要被求导a = torch.tensor(1.0)b = torch.tensor(-2.0)c = torch.tensor(1.0)optimizer = torch.optim.SGD(params=[x],lr = 0.01)def f(x): result = a*torch.pow(x,2) + b*x + c return(result)for i in range(500): optimizer.zero_grad() y = f(x) y.backward() optimizer.step() print("y=",f(x).data,";","x=",x.data)

总结

标量求导和非标量求导及其本质(requires_grad=True) autograd.grad函数求导数 torch.autograd.grad(y,x,create_graph=True) # 返回数组 (dy12_dx1,dy12_dx2) = torch.autograd.grad(outputs=[y1,y2],inputs = [x1,x2])如果有多个因变量,相当于对梯度求和 梯度下降算法求最小值(梯度清0,求梯度,梯度更新)


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【偷偷卷死小伙伴Pytorch20天】-【day5】-【张量数据结构】
下一篇:SpringBoot使用JdbcTemplate访问操作数据库基本用法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~