侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

PyTorch: 梯度下降及反向传播的实例详解

Python  /  管理员 发布于 5年前   363

线性模型

线性模型介绍

线性模型是很常见的机器学习模型,通常通过线性的公式来拟合训练数据集。训练集包括(x,y),x为特征,y为目标。如下图:

将真实值和预测值用于构建损失函数,训练的目标是最小化这个函数,从而更新w。当损失函数达到最小时(理想上,实际情况可能会陷入局部最优),此时的模型为最优模型,线性模型常见的的损失函数:

线性模型例子

下面通过一个例子可以观察不同权重(w)对模型损失函数的影响。

#author:yuquanle#data:2018.2.5#Study of Linear Modelimport numpy as npimport matplotlib.pyplot as pltx_data = [1.0, 2.0, 3.0]y_data = [2.0, 4.0, 6.0]def forward(x):  return x * wdef loss(x, y):  y_pred = forward(x)  return (y_pred - y)*(y_pred - y)w_list = []mse_list = []for w in np.arange(0.0, 4.1, 0.1):  print("w=", w)  l_sum = 0  for x_val, y_val in zip(x_data, y_data):    # error    l = loss(x_val, y_val)    l_sum += l  print("MSE=", l_sum/3)  w_list.append(w)  mse_list.append(l_sum/3)plt.plot(w_list, mse_list)plt.ylabel("Loss")plt.xlabel("w")plt.show()输出结果:w= 0.0MSE= 18.6666666667w= 0.1MSE= 16.8466666667w= 0.2MSE= 15.12w= 0.3MSE= 13.4866666667w= 0.4MSE= 11.9466666667w= 0.5MSE= 10.5w= 0.6MSE= 9.14666666667

调整w,loss变化图:

可以发现当w=2时,loss最小。但是现实中最常见的情况是,我们知道数据集,定义好损失函数之后(loss),我们并不会从0到n去设置w的值,然后求loss,最后选取使得loss最小的w作为最佳模型的参数。更常见的做法是,首先随机初始化w的值,然后根据loss函数定义对w求梯度,然后通过w的梯度来更新w的值,这就是经典的梯度下降法思想。

梯度下降法

梯度的本意是一个向量,表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模)。

梯度下降是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以)。在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient Descent)是最常采用的方法之一,另一种常用的方法是最小二乘法。在求解损失函数的最小值时,可以通过梯度下降法来一步步的迭代求解,得到最小化的损失函数和模型参数值。即每次更新参数w减去其梯度(通常会乘以学习率)。

#author:yuquanle#data:2018.2.5#Study of SGDx_data = [1.0, 2.0, 3.0]y_data = [2.0, 4.0, 6.0]# any random valuew = 1.0# forward passdef forward(x):  return x * wdef loss(x, y):  y_pred = forward(x)  return (y_pred - y)*(y_pred - y)# compute gradient (loss对w求导)def gradient(x, y):  return 2*x*(x*w - y)# Before trainingprint("predict (before training)", 4, forward(4))# Training loopfor epoch in range(20):  for x, y in zip(x_data, y_data):    grad = gradient(x, y)    w = w - 0.01 * grad    print("\t grad: ",x, y, grad)    l = loss(x, y)  print("progress:", epoch, l)# After trainingprint("predict (after training)", 4, forward(4))输出结果:predict (before training) 4 4.0   grad: 1.0 2.0 -2.0   grad: 2.0 4.0 -7.84   grad: 3.0 6.0 -16.2288progress: 0 4.919240100095999   grad: 1.0 2.0 -1.478624   grad: 2.0 4.0 -5.796206079999999   grad: 3.0 6.0 -11.998146585599997progress: 1 2.688769240265834   grad: 1.0 2.0 -1.093164466688   grad: 2.0 4.0 -4.285204709416961   grad: 3.0 6.0 -8.87037374849311progress: 2 1.4696334962911515   grad: 1.0 2.0 -0.8081896081960389   grad: 2.0 4.0 -3.1681032641284723   grad: 3.0 6.0 -6.557973756745939progress: 3 0.8032755585999681   grad: 1.0 2.0 -0.59750427561463   grad: 2.0 4.0 -2.3422167604093502   grad: 3.0 6.0 -4.848388694047353progress: 4 0.43905614881022015   grad: 1.0 2.0 -0.44174208101320334   grad: 2.0 4.0 -1.7316289575717576   grad: 3.0 6.0 -3.584471942173538progress: 5 0.2399802903801062   grad: 1.0 2.0 -0.3265852213980338   grad: 2.0 4.0 -1.2802140678802925   grad: 3.0 6.0 -2.650043120512205progress: 6 0.1311689630744999   grad: 1.0 2.0 -0.241448373202223   grad: 2.0 4.0 -0.946477622952715   grad: 3.0 6.0 -1.9592086795121197progress: 7 0.07169462478267678   grad: 1.0 2.0 -0.17850567968888198   grad: 2.0 4.0 -0.6997422643804168   grad: 3.0 6.0 -1.4484664872674653progress: 8 0.03918700813247573   grad: 1.0 2.0 -0.13197139106214673   grad: 2.0 4.0 -0.5173278529636143   grad: 3.0 6.0 -1.0708686556346834progress: 9 0.021418922423117836predict (after training) 4 7.804863933862125

反向传播

但是在定义好模型之后,使用pytorch框架不需要我们手动的求导,我们可以通过反向传播将梯度往回传播。通常有二个过程,forward和backward:

#author:yuquanle#data:2018.2.6#Study of BackPagationimport torchfrom torch import nnfrom torch.autograd import Variablex_data = [1.0, 2.0, 3.0]y_data = [2.0, 4.0, 6.0]# Any random valuew = Variable(torch.Tensor([1.0]), requires_grad=True)# forward passdef forward(x):  return x*w# Before trainingprint("predict (before training)", 4, forward(4))def loss(x, y):  y_pred = forward(x)  return (y_pred-y)*(y_pred-y)# Training: forward, backward and update weight# Training loopfor epoch in range(10):  for x, y in zip(x_data, y_data):    l = loss(x, y)    l.backward()    print("\t grad:", x, y, w.grad.data[0])    w.data = w.data - 0.01 * w.grad.data    # Manually zero the gradients after running the backward pass and update w    w.grad.data.zero_()  print("progress:", epoch, l.data[0])# After trainingprint("predict (after training)", 4, forward(4))输出结果:predict (before training) 4 Variable containing: 4[torch.FloatTensor of size 1]   grad: 1.0 2.0 -2.0   grad: 2.0 4.0 -7.840000152587891   grad: 3.0 6.0 -16.228801727294922progress: 0 7.315943717956543   grad: 1.0 2.0 -1.478623867034912   grad: 2.0 4.0 -5.796205520629883   grad: 3.0 6.0 -11.998146057128906progress: 1 3.9987640380859375   grad: 1.0 2.0 -1.0931644439697266   grad: 2.0 4.0 -4.285204887390137   grad: 3.0 6.0 -8.870372772216797progress: 2 2.1856532096862793   grad: 1.0 2.0 -0.8081896305084229   grad: 2.0 4.0 -3.1681032180786133   grad: 3.0 6.0 -6.557973861694336progress: 3 1.1946394443511963   grad: 1.0 2.0 -0.5975041389465332   grad: 2.0 4.0 -2.3422164916992188   grad: 3.0 6.0 -4.848389625549316progress: 4 0.6529689431190491   grad: 1.0 2.0 -0.4417421817779541   grad: 2.0 4.0 -1.7316293716430664   grad: 3.0 6.0 -3.58447265625progress: 5 0.35690122842788696   grad: 1.0 2.0 -0.3265852928161621   grad: 2.0 4.0 -1.2802143096923828   grad: 3.0 6.0 -2.650045394897461progress: 6 0.195076122879982   grad: 1.0 2.0 -0.24144840240478516   grad: 2.0 4.0 -0.9464778900146484   grad: 3.0 6.0 -1.9592113494873047progress: 7 0.10662525147199631   grad: 1.0 2.0 -0.17850565910339355   grad: 2.0 4.0 -0.699742317199707   grad: 3.0 6.0 -1.4484672546386719progress: 8 0.0582793727517128   grad: 1.0 2.0 -0.1319713592529297   grad: 2.0 4.0 -0.5173273086547852   grad: 3.0 6.0 -1.070866584777832progress: 9 0.03185431286692619predict (after training) 4 Variable containing: 7.8049[torch.FloatTensor of size 1]Process finished with exit code 0

以上这篇PyTorch: 梯度下降及反向传播的实例详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


  • 上一条:
    对pytorch中的梯度更新方法详解
    下一条:
    pytorch 加载(.pth)格式的模型实例
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客