pytorch学习1.2——求导梯度练习

求导主要用到的方法是.requires_grad() ,将其设置为True则其相关的变量会构成一个求导网,记录其过程,这个方法会追踪记录定义在这个变量上的所有操作,然后调用.backward()就可以自动计算梯度,在这个Tensor上的所有梯度就会加进属性.grad中。代码实现:

构建的函数

y=f(x)=6x^2+2x+4
dy/dx=12x+2
import torch
import numpy as np
from IPython.display import Image
x=torch.tensor(3.,requires_grad=True)
print(x.data)#打印出数据
print(x.grad)#因为没有计算过程内容所以梯度为空
print(x.is_leaf)#是不是叶子节点(不依赖别的)
print(x.requires_grad)#是否需要计算梯度

tensor(3.)
tensor(38.)
True
True

y=6*x**2+2*x+4
##看一下y属性
print(y.data)#打印出数据
print(y.grad)#因为没有求,所以为空
print(y.is_leaf)#是不是叶子节点(有没有别的依赖)y依赖于x所以不是,是一个内部节点
print(y.requires_grad)#是否需要计算梯度(由x过来的所以需要计算)

tensor(64.)
None
False
True

求梯度:

y.backward()
print(x.data)#打印出数据
print(x.grad)#y对x求导38
print(x.is_leaf)#是不是叶子节点(不依赖别的)
print(x.requires_grad)#是否需要计算梯度
##############y对x求导38
######12*3+2=38
print("#########################y#######################")
print(y.data)#打印出数据
print(y.grad)#因为没有求,所以为空y式子里没有y
print(y.is_leaf)#是不是叶子节点(有没有别的依赖)y依赖于x所以不是,是一个内部节点
print(y.requires_grad)#是否需要计算梯度(由x过来的所以需要计算)

tensor(3.)
tensor(38.)
True
True
#########################y#######################
tensor(64.)
None
False
True

2,偏导:

函数式:
f(u,v)=u^3+v^2+4uv
p(f)/p(u)=3u^2+4v
p(f)/p(v)=2v+4u
u=torch.tensor(3.,requires_grad=True)
v=torch.tensor(4.,requires_grad=True)
f = u**3 + v**2+4*u*v
f.backward()
print(u.grad)#27+16=43
print(v.grad)#8+12=20

tensor(43.)
tensor(20.)

构建计算图

连锁求导

l=f(g(h(x)))
import torch
a=torch.randn((3,3),requires_grad=True)

w1=torch.randn((3,3),requires_grad=True)
w2=torch.randn((3,3),requires_grad=True)
w3=torch.randn((3,3),requires_grad=True)
w4=torch.randn((3,3),requires_grad=True)

# b:3*3
b = w1*a
# c:3*3
c=w2*a

d=w3*b+w4*c

L=(10-d)

 

##粉色节点都是叶子节点
print(a.is_leaf)
print(w1.is_leaf)
print(w2.is_leaf)

True
True
True

print("############L的反向传播#############")
print(L)
L.backward()###注意,此处会报错,pytorch计算backward只能是个标量需要使用加和,取均值等操作
############L的反向传播#############
tensor([[10.0803, 10.0628,  7.5192],
        [ 9.2849, 12.1867, 10.0175],
        [10.1017, 11.1517, 12.9821]], grad_fn=<RsubBackward1>)

RuntimeError: grad can be implicitly created only for scalar outputs

因为后向求导仅仅针对标量,因此需要改为:

import torch
a=torch.randn((3,3),requires_grad=True)
print(a)
w1=torch.randn((3,3),requires_grad=True)
w2=torch.randn((3,3),requires_grad=True)
w3=torch.randn((3,3),requires_grad=True)
w4=torch.randn((3,3),requires_grad=True)

# b:3*3
b = w1*a
# c:3*3
c=w2*a

d=w3*b+w4*c
d.retain_grad()

L=(10-d).sum()#使用聚合函数

tensor([[ 0.9240, -0.1135, -0.8534],
        [ 0.1692, -0.1923, -0.9745],
        [ 0.2424,  0.2950, -0.9161]], requires_grad=True)

print("############L的反向传播#############")
print(L)
L.backward()
print(a.grad)

############L的反向传播#############
tensor(88.3535, grad_fn=<SumBackward0>)
tensor([[-2.9321, -0.5816,  1.0495],
        [ 0.2598,  0.2794, -2.0839],
        [-0.8607,  0.2975,  0.0086]])

-w3*w1-w4*w2
##与上式计算结果相同
tensor([[-2.9321, -0.5816,  1.0495],
        [ 0.2598,  0.2794, -2.0839],
        [-0.8607,  0.2975,  0.0086]], grad_fn=<SubBackward0>)

因为数学推导一致。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值