Torch自定义求导

一、近似求导

def f(x):
    return 3. * x ** 2 + 2. * x - 1 # 加点是为了浮点数的目的
#近视求导,x移动eps单位,也就是离自己很近的一个点的切线
def approximate_derivative(f, x, eps=1e-6): #函数 f, 变量 x, 步长 eps
    return (f(x + eps) - f(x - eps)) / (2. * eps) # 近似导数公式

print(approximate_derivative(f, 1.))

偏导:

#求偏导数,其中一个数不动,对另外一个变量求导
def g(x1, x2):
    return (x1 + 5) * (x2 ** 2)

def approximate_gradient(g, x1, x2, eps=1e-3):
    dg_x1 = approximate_derivative(lambda x: g(x, x2), x1, eps)
    dg_x2 = approximate_derivative(lambda x: g(x1, x), x2, eps)
    return dg_x1, dg_x2

print(approximate_gradient(g, 2., 3.))
    

torch的近似求导,retain_graph就是保留计算图的意思,这样同一个图就可以进行多次反向传播:

# 声明两个tensor x1 和 x2,允许梯度计算,使用torch的自动求导上下文计算两个tensor的梯度
# 使用 torch.autograd.grad 计算 y = g(x1, x2) 的偏导数

x1 = torch.tensor([2.], requires_grad=True)
x2 = torch.tensor([3.], requires_grad=True)
y = g(x1, x2)
    
(dy_dx1,) = torch.autograd.grad(y, x1,retain_graph=True) # 近似求导,只求x1的偏导数
print(dy_dx1)
# 同时求导

x1 = torch.tensor([2.], requires_grad=True)
x2 = torch.tensor([3.], requires_grad=True)
y = g(x1, x2)

# 求偏导数
dy_dx1, dy_dx2 = torch.autograd.grad(y, [x1, x2])


print(dy_dx1, dy_dx2)

# 当然我们一般直接用 backward

x1 = torch.tensor([2.], requires_grad=True)
x2 = torch.tensor([3.], requires_grad=True)
y = g(x1, x2)

# 求偏导数,求梯度
y.backward()
print(x1.grad, x2.grad)

模拟梯度下降,更新w:

#模拟梯度下降算法 SGD
import torch
learning_rate = 0.3
x = torch.tensor(2.0, requires_grad=True)
for _ in range(100):
    z = f(x)
    z.backward()
    x.data.sub_(learning_rate * x.grad) # x -= learning_rate * x.grad,这里就等价于optimizer.step()
    x.grad.zero_() # x.grad -= x.grad, x.grad = 0,梯度清零
print(x)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何仙鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值