使用autograd自动求导拟合三角函数

对于小型的网络而言,手动实施反向传播很简单,但对于大型的复杂网络而言,会变得非常麻烦。

而在pytorch中,我们可以使autograd包自动微分来自动计算神经网络中的反向传播。 使autograd时,网络的正向传递将定义一个计算图; 图中的节点为张量,边为从输入张量产生输出张量的函数。 然后通过该图进行反向传播,可以轻松计算梯度。话不多说,贴代码:

import torch
import math

dtype = torch.float
device = torch.device("cuda:0")  # 指定设备为GPU

# 声明两个张量接收输入和输出
# 默认反向传播不需要保存梯度(requires_grad=False)
x = torch.linspace(-math.pi, math.pi, 2000, device=device, dtype=dtype)
y = torch.sin(x)

# 为四个权重创建张量
# 设置requires_grad=True,因为在反向传播中我们需要计算并保存这些张量的梯度
a = torch.randn((), device=device, dtype=dtype, requires_grad=True)
b = torch.randn((), device=device, dtype=dtype, requires_grad=True)
c = torch.randn((), device=device, dtype=dtype, requires_grad=True)
d = torch.randn((), device=device, dtype=dtype, requires_grad=True)

learning_rate = 1e-6
for t in range(2000):
    y_pred = a + b * x + c * x ** 2 + d * x ** 3

    # 用Tensor计算和打印loss
    # loss是一个一维Tensor,loss.item() 用于获取loss的标量值
    loss = (y_pred - y).pow(2).sum()
    if t % 100 == 100:
        print(t, loss.item())

    # 使用自动求导进行反向传播,调用过程中将会计算所有requires_grad=True的张  量损失梯度在调用过程中a.grad,b.grad,c.grad,d.grad 将保存abcd的损失梯度.
    loss.backward()

    # 对于tensor的计算操作,默认是要进行梯度计算,在这种情况下,可以使用with torch.no_grad():,强制之后的内容不进行梯度计算。
    with torch.no_grad():
        a -= learning_rate * a.grad
        b -= learning_rate * b.grad
        c -= learning_rate * c.grad
        d -= learning_rate * d.grad

        # 在更新权重后手动将梯度置0
        a.grad = None
        b.grad = None
        c.grad = None
        d.grad = None

print(f'Result: y = {a.item()} + {b.item()} x + {c.item()} x^2 + {d.item()} x^3')

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容