前言:20天吃掉pytorch——学习解读
- 本人将依据《20天吃掉那只pytorch》这个优秀的项目回顾一遍pytorch的基本知识,总结成十个章节
项目地址:https://github.com/lyhue1991/eat_pytorch_in_20_days
思维导图
- 假设转化成tensor数据类型前的数据是data
- 假设转化成tensor数据类型后的数据是tensor_data
一、标量反向传播
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()
# backward()求得的梯度对应在自变量grad属性下
dy_dx = x.grad # 求导之后为2*x-2 代入x==0为-2
print(x.grad)
# 输出
# tensor(-2.)
二、张量反向传播
x = torch.tensor([[0.0,0.0],[1.0,2.0]], requires_grad = True)
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]])
y.backward(gradient)
print(x.grad)
# 另一种表达方法:用标量反向传播表示张量反向传播
# gradient = torch.tensor([[1.0,1.0],[1.0,1.0]])
# z = torch.sum(y*gradient)
# z.backward()
# print(x.grad)
# 输出
# tensor([[-2., -2.],
# [ 0., 2.]])
三、张量反向传播高级用法
1.求二阶微分
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
# create_graph设置为True将允许创建更高阶的导数
dy_dx = torch.autograd.grad(y,x,create_graph=True)[0]
# 求二阶导数
dy2_dx2 = torch.autograd.grad(dy_dx,x)[0]
print(dy2_dx2.data)
# 输出
# tensor(2.)
2.多自变量、因变量求微分
x1 = torch.tensor(1.0, requires_grad=True) # x需要被求导
x2 = torch.tensor(2.0, requires_grad=True)
y1 = x1*x2
y2 = x1+x2
# 允许同时对多个自变量求导数
(dy1_dx1,dy1_dx2) = torch.autograd.grad(outputs=y1, inputs=[x1,x2], retain_graph=True) # retain_graph
print(dy1_dx1, dy1_dx2)
# 如果有多个因变量,相当于把多个因变量的梯度结果求和
(dy12_dx1,dy12_dx2) = torch.autograd.grad(outputs=[y1,y2], inputs = [x1,x2])
print(dy12_dx1, dy12_dx2)
# 输出
# tensor(2.) tensor(1.)
# tensor(3.) tensor(2.)
四、自动反向学习(微分)优化器
x = torch.tensor(0.0, requires_grad=True) # x需要被求导
a = torch.tensor(1.0)
b = torch.tensor(-2.0)
c = torch.tensor(1.0)
def f(x):
result = a*torch.pow(x,2) + b*x + c
return(result)
# 随机梯度下降优化器
optimizer = torch.optim.SGD(params=[x], lr=0.01)
for i in range(500):
# 梯度初始化为0
optimizer.zero_grad()
y = f(x)
y.backward()
# 更新所有参数
optimizer.step()
print("y=",f(x).data,";","x=",x.data)
# 输出
# y= tensor(0.) ; x= tensor(1.0000)
总结
如有错误或不足的地方,请评论区指出,本人认真修改,谢谢~!