pytorch学习——反向传播

本文通过实例演示如何使用PyTorch进行线性回归训练,并展示了如何定义损失函数、执行前向传播及反向传播更新权重的过程。此外还讨论了张量操作及绘图技巧。
部署运行你感兴趣的模型镜像

476fb7f1986543118003f74d26c30abe.png

由上图,前向传播算出loss,再利用链式法则,倒推w012efc4ec17a425880c047f3f8421243.png

 y'=2,r=-2,loss=4

偏导:loss对r=-4,loss-y'=-4,loss-w=-8

41fce7c023c847afac513843b6e24bf6.png

 36f9d9cfc6ff41aabe0360f7a8bd59dd.png

 课上代码:

import numpy.matlib
import torch
import numpy as np

x=[1.0,2.0,3.0]
y=[2.0,4.0,6.0]

#创建张量并允许求导
w=torch.Tensor([1.0])
w.requires_grad=True

def forward(x):
    return x*w

def loss(x,y):
    y_pred=forward(x)
    return(y_pred-y)**2

print("predict(before training)",4,forward(4).item())
for epoch in range(100):
    for i,j in zip (x,y):
        l=loss(i,j)
        l.backward()#进行梯度值运算
        print("\tgrad:",i,j,w.grad.item())  
        w.data=w.data-0.01*w.grad.data
        w.grad.data.zero_()  
    print("progress:",epoch,l.item())

print("predict(after training)",4,forward(4).item())

作业:

import numpy.matlib
import torch
import numpy as np

x=[1.0,2.0,3.0]
y=[11.0,20.0,33.0]

w1=torch.Tensor([1.9])
w1.requires_grad=True
w2=torch.Tensor([2.9])
w2.requires_grad=True
b=torch.Tensor([5.9])
b.requires_grad=True

def forward(x):
    return x*x*w1+x*w2+b

def loss(x,y):
    y_pred=forward(x)
    return(y_pred-y)**2

print("predict(before training)",4,forward(4).item())
for epoch in range(100):
    for i,j in zip (x,y):
        l=loss(i,j)
        l.backward()
        print("\tgrad:",i,j,w1.grad.item(),w2.grad.item(),b.grad.item())  
        w1.data=w1.data-0.01*w1.grad.data
        w2.data=w2.data-0.01*w2.grad.data
        b.data=b.data-0.01*b.grad.data
        w1.grad.data.zero_()
        w2.grad.data.zero_()
        b.grad.data.zero_()  
    print("progress:",epoch,l.item())

print("predict(after training)",4,forward(4).item())

训练后的结果为: 

predict(after training) 4 49.99744415283203

与真实值50相差不大。 

另外画图出现了这个错误Import 'matplotlib.pyplot'

发现是虚拟环境中没有安装matplotlib库,装完尝试画图。

画出来图像很奇怪,怀疑是横纵坐标选取不对。、

重新选取,令x=epoch,y=loss,图像如下

 

另外,将3个权重放到同一张量中可以简化代码,代码如下

import numpy.matlib
import torch
import numpy as np
import matplotlib.pyplot as plt

x=[1.0,2.0,3.0]
y=[11.0,20.0,33.0]

w=torch.tensor([[1.9],[2.9],[5.9]])
w.requires_grad=True

def forward(x):
      return x*x*torch.take(w,torch.tensor([0]))+x*torch.take(w,torch.tensor([1]))+torch.take(w,torch.tensor([2]))

def loss(x,y):
    y_pred=forward(x)
    return(y_pred-y)**2

print("predict(before training)",4,forward(4).item())
l_try=[]
epoch_try=[]
for epoch in range(100):
    for i,j in zip (x,y):
        l=loss(i,j)
        l.backward()
        l_try.append(l.item())
        epoch_try.append(epoch)
        w.data=w.data-0.01*w.grad.data
        w.grad.data.zero_()
    print("progress:",epoch,l.item())

print("predict(after training)",4,forward(4).item())

plt.plot(epoch_try,l_try)
plt.show()

ps:选取tensor的特定值给我看吐了。

参考:

(45条消息) Pytorch基础操作 —— 12. 从张量中选取数据_打码的老程的博客-优快云博客_pytorch 张量取值

torch.index_select(input, dim, index, *, out=None) → Tensor

 

我吐了,为什么不说清楚!!!index这个参数必须是tensor,不然就会报错。 

!!!我吐了!!!居然用索引就可以。。。白查那么久博客

def forward(x):
      return x*x*torch.take(w,torch.tensor([0]))+x*torch.take(w,torch.tensor([1]))+torch.take(w,torch.tensor([2]))

可以改为:

w=torch.tensor([1.9,2.9,5.9])

def forward(x):
    return x*x*w[0]+x*w[1]+w[3]

!!!为什么可以这么简单!!!

还有,他喵的,讲torch.gather函数的博客我一篇都没看懂。

直到遇到了它:
https://zhuanlan.zhihu.com/p/462008911

感谢老师,感谢。 

您可能感兴趣的与本文相关的镜像

PyTorch 2.6

PyTorch 2.6

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

### PyTorch反向传播和自动求导的工作原理 #### 什么是反向传播反向传播是一种用于优化神经网络模型参数的重要方法。在这一过程中,通过计算损失函数相对于各个参数的偏导数来调整权重和其他可学习参数。这些导数值随后被用来更新模型参数,从而最小化目标损失函数[^2]。 #### 自动求导的作用 PyTorch 提供了一种强大的工具——自动求导机制,该机制可以自动生成并执行复杂的梯度计算过程。这种能力显著减轻了开发者手动推导复杂导数的任务负担,同时也提高了开发效率和准确性。具体来说,PyTorch 使用动态计算图结构支持前向传播阶段的操作记录,并基于此完成后续的反向传播运算[^1]。 #### 动态计算图的特点 不同于一些静态定义图形系统的框架(如早期版本 TensorFlow),PyTorch 构建了一个动态计算图。这意味着每次运行程序时都会重新创建一个新的计算图,这样就可以更方便地处理具有不同形状的数据或者涉及条件分支逻辑的情况。当我们在代码里执行某些 tensor 运算的时候,实际上就是在构建这张图的一部分节点及其连接关系;而一旦进入 backward() 方法调用,则会沿着已建立好的路径逆序遍历各层操作以累积所需的梯度信息[^4]。 #### 实现细节说明 以下是几个关键概念和技术要点: - **链式法则的应用** 在数学上利用多变量复合函数微分公式即所谓的“链式法则”,逐级累加局部变化率直至得到全局敏感程度指标。这是整个流程的核心理论依据之一[^3]。 - **张量属性 `.grad` 和 `requires_grad=True` 设置** 对于需要追踪历史以便参与梯度下降的学习对象而言,必须显式指定其 requires_grad 属性为 True 。之后每当此类 Tensor 发生改变后,系统便会同步维护关联的历史记录以及相应位置上的瞬时斜率值存储到 .grad 字段当中待查取使用。 - **关闭/开启 Autograd 功能** 如果存在部分中间结果仅作临时用途而不希望额外消耗内存保存冗余数据的话,可以通过上下文管理器 torch.no_grad 或者设置 detach 来暂时屏蔽掉这部分区域内的监控活动。 - **高维情况下的 Jacobian 向量积技巧** 特殊场景下如果只关心特定方向上的投影效果而非完整的 Hessian Matrix 表达形式,那么借助 PyTorch 内置接口可以直接高效获取所需成分组合成果,无需显式展开全部矩阵表达式再做乘法运算,有效节省资源开销[^5]。 ```python import torch # 示例:简单的线性回归模型演示如何运用 autograd 计算梯度 x = torch.tensor([1., 2., 3.], requires_grad=False).unsqueeze(-1) # 输入特征 y_true = torch.tensor([2., 4., 6.]) # 真实标签 w = torch.randn((1,), dtype=torch.float, requires_grad=True) # 初始化随机权值 w b = torch.zeros((1,), dtype=torch.float, requires_grad=True) # 初始偏差 b 设定为零 def model(x): return x @ w.t() + b # 定义预测方程 y_hat=f(x;θ) for epoch in range(10): predictions = model(x) # 正向传播获得估计输出 loss = ((predictions.squeeze()-y_true)**2).mean() # MSE Loss Function if w.grad is not None: # 清除之前的残差积累项以防叠加错误 w.grad.zero_() if b.grad is not None: b.grad.zero_() loss.backward() # 执行误差回传步骤填充 grad 成员变量内容 with torch.no_grad(): # 更新参数时不需继续跟踪新产生的依赖链条 step_size = 0.01 # 学习速率超参调节因子 w -= step_size * w.grad # 参数修正规则应用GD策略 b -= step_size * b.grad print(f'Final weights={w.item()}, bias={b.item()}') ``` 上述脚本展示了基本的一次迭代周期内正向推理、代价评估及反馈校准全过程的具体实现方式。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值