《PyTorch 深度学习实践》第4讲--反向传播算法

《PyTorch 深度学习实践》第4讲–反向传播算法

@《PyTorch 深度学习实践》第4讲–反向传播算法

1. 张量预备知识

Tensor 中重要的两个成员,data 用于保存权重本身的值 ω \omega ω, grad 用于保存损失函数对权重的导数 ∂ l o s s ∂ ω \frac{\partial loss}{\partial \omega} ωloss,grad 本身也是个张量。对张量进行的计算操作,都是建立计算图的过程。

# 测试tensor 中的data和grad
import torch
b=torch.Tensor([1.0])
print('b的类型是:',type(b))
print('b中的data=',b.data)
print('b中的data类型是:',type(b.data))
print('b中的grad=',b.grad)
print('b中的grad类型是:',type(b.grad))
b的类型是: <class 'torch.Tensor'>
b中的data= tensor([1.])
b中的data类型是: <class 'torch.Tensor'>
b中的grad= None
b中的grad类型是: <class 'NoneType'>

2. 实现线性模型 y=wx

# 反向传播算法实现
import torch 
import matplotlib.pyplot as plt
# step1 准备数据集
x_data=[1.0,2.0,3.0]
y_data=[2.0,4.0,6.0]
x_num=len(x_data) #样本个数
# 定义w为tensor类型,需要计算梯度
w=torch.Tensor([1.0])
w.requires_grad=True

# step2 选择模型 y=wx
# 正向传播
def forward(x):
    return w*x
# 计算损失,构建计算图
def loss(x,y):
    y_pred=forward(x)
    return (y_pred-y)**2

# 模型训练前 预测
print('Predict (before training)',4,forward(4).item())
# step3 训练模型
epoch_list=[]
cost_list=[]
for epoch in range(100):
    for x_val,y_val in zip(x_data,y_data):
        # 计算损失  lost 是一个张量,tensor 主要是在建立计算图 forward, compute the loss
        lost=loss(x_val,y_val)
        # 反向传播计算需要计算的梯度
        lost.backward()
        print('\t grad:',x_val,y_val,w.grad.item())
        # 权重更新时,需要用到标量,注意 grad 也是一个张量
        w.data-=0.01*w.grad.data
        # 释放之前计算的梯度
        w.grad.data.zero_()
    cost_list.append(lost.item())
    epoch_list.append(epoch+1)
    print('Epoch: ',epoch+1,'cost: ',lost.item())
# 模型训练后 预测
print('Predict (after training)',4,forward(4).item())
# 绘制损失图
plt.plot(epoch_list,cost_list)
plt.xlabel('epoch')
plt.ylabel('cost')
plt.show()

在这里插入图片描述
代码说明

  • w是 Tensor 数据类型, forward() 的返回值是 Tensor 数据类型,loss() 的返回值也是 Tensor数据类型.
  • 反向传播实现代码是调用 backward(),调用该函数后 w.grad 由 None 更新为 Tensor 数据类型,且 w.grad.data 的值用于后续 w.data 的更新。
  • backward() 会把计算图中所有需要梯度 grad 的地方都会求出来,然后把梯度都存在对应的待求的参数中,最终通过调用 grad.data.zero_() 将梯度清零,释放计算图。
  • 取 tensor 中的 data 是不会构建计算图的。

3. 实现模型 y=w1x^2+w2x+b

# 接下来实现对模型 y=w1*x**2+w2*x+b 的反向传播
import matplotlib.pyplot as plt
import torch
# step1 准备数据
x_data=[1.0,2.0,3.0]
y_data=[2.0,4.0,6.0]

# 初始化参数 定义w1,w2,b为tensor类型,需要计算梯度
w1=torch.Tensor([1.0])
# 是否需要计算梯度?——True
w1.requires_grad=True 
w2=torch.Tensor([1.0])
w2.requires_grad=True
b=torch.Tensor([0.0])
b.requires_grad=True

# step2 选择模型 y=w1*x**2+w2*x+b
# 正向传播
def forward(x):
    return w1*x**2+w2*x+b
#定义损失函数 构建计算图
def loss(x,y):
    y_pred=forward(x)
    return (y_pred-y)**2
# 训练前 预测
# .item()的作用主要是把数据从tensor取出来,变成python的数据类型
print('Predit (before training)',4,forward(4).item())

# step3 开始训练
# 设置一些超参数
epochs=100 # 训练轮次
lr=1e-2 # 学习率
total_cost=[] 
total_epoch=[]
for epoch in range(epochs):
    for x_val,y_val in zip(x_data,y_data):
        # 计算损失 lost 是一个张量,tensor主要是建立计算图 forward,compute the loss
        lost=loss(x_val,y_val)
        # 利用PyTorch的反向传播函数求梯度
        lost.backward()
        print('\t grad:',x_val,y_val,w1.grad.item(),w2.grad.item(),b.grad.item())
        # 更新参数 需要用到标量,注意grad也是一个tensor
        # 这里是数值计算,w一定要取data值,tensor做加法运算会构建运算图,消耗内存
        w1.data-=lr*w1.grad.data
        w2.data-=lr*w2.grad.data
        b.data-=lr*b.grad.data
        total_epoch.append(epoch+1)
        total_cost.append(lost.item())
        # 将之前计算的梯度清零
        w1.grad.data.zero_()
        w2.grad.data.zero_()
        b.grad.data.zero_()
    print('Epoch:',epoch+1,'cost=',lost.item())
# step 4 预测
#模型训练好后  预测
print('Prident (after training)',4,forward(4).item())

# 绘制损失函数图
plt.plot(total_epoch,total_cost)
plt.xlabel('epoch')
plt.ylabel('cost')
plt.show()

在这里插入图片描述
总结:可以看到,训练100轮次后,当x=4时,y=8.3。与正确值8相差比较大,原因可能是使用的模型是二次函数,数据集本身是一次函数的数据,所以导致预测结果和正确值相差比较大的情况。

4. 课后作业

  • 4.1 手动推导线性模型 y=w*x,损失函数 loss=(ŷ-y)² 下,当数据集 x=2, y=4的时候,反向传播的过程。

在这里插入图片描述

  • 4.2 手动推导线性模型 y=w*x+b,损失函数 loss=(ŷ-y)² 下,当数据集x=1, y=2 的时候,反向传播的过程。
    在这里插入图片描述
  • 4.3 画出二次模型 y=w1x²+w2x+b,损失函数 loss=(ŷ-y)² 的计算图,并且手动推导反向传播的过程。

在这里插入图片描述

5. 参考

  1. 《PyTorch 深度学习实践》: https://www.bilibili.com/video/BV1Y7411d7Ys?p=4&vd_source=435453f6c8cc1940667595c415308e92
  2. 《PyTorch 深度学习实践 第5讲笔记》: http://biranda.top/Pytorch%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0005%E2%80%94%E2%80%94%E5%8F%8D%E5%90%91%E4%BC%A0%E6%92%AD%E7%AE%97%E6%B3%95/
  3. PyTorch学习(三)–反向传播: https://blog.csdn.net/weixin_44841652/article/details/105046519
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PyTorch是一个基于Python的开源深度学习框架,它提供了丰富的工具和库,用于构建和训练神经网络模型。以下是PyTorch深度学习的一些重要特点和组成部分: 1. 张量(Tensor):PyTorch使用张量作为数据的基本单位,类似于NumPy的多维数组。张量可以在CPU和GPU上进行计算,并且支持自动求导。 2. 动态计算图:PyTorch使用动态计算图来跟踪和优化神经网络模型的计算过程。这意味着你可以在运行时改变计算图的结构,使得模型的构建更加灵活。 3. 自动求导:PyTorch提供了自动求导的功能,可以根据输入和输出自动计算梯度。这使得反向传播算法可以自动计算模型参数的梯度,从而进行模型的优化。 4. 模型构建:PyTorch提供了丰富的模型构建工具,包括各种层(如全连接层、卷积层、循环神经网络等)、激活函数、损失函数等。你可以使用这些工具来构建各种类型的神经网络模型。 5. 训练与推理:PyTorch提供了灵活的训练和推理接口,可以方便地进行模型的训练和预测。你可以使用内置的优化器(如SGD、Adam等)来优化模型参数,并使用训练数据进行模型的训练。然后,你可以使用训练好的模型进行推理,得到预测结果。 6. 生态系统:PyTorch拥有庞大的生态系统,有大量的社区贡献和第三方库支持。你可以使用这些库来扩展PyTorch的功能,例如图像处理、自然语言处理等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值