1. 梯度是什么?

梯度 : 一个向量,导数+变化最快的方向

机器学习:

收集数据x, 构建模型f,通过f(x, w) = Ypredict

判断模型质量的方法,计算loss
loss=(Ypredict−Ytrue)2(回归损失)loss=Ytrue⋅log(Ypredict)(分类损失)loss = (Y_{predict} - Y_{true})^2 \quad (回归损失)\\ loss = Y_{true}·log(Y_{predict}) \quad (分类损失) loss=(Ypredict​−Ytrue​)2(回归损失)loss=Ytrue​⋅log(Ypredict​)(分类损失)
通过学习参数w,尽可能降低模型的loss,那我们应该如何调整w呢?

  1. 对w0点进行求导,求得梯度为:
    Δw=f(w+x)−f(w)x(x→0)\Delta w = \frac {f(w+x) - f(w)}{x} \quad (x \rightarrow 0) Δw=xf(w+x)−f(w)​(x→0)

  2. 更新w

w=w−αΔww = w - \alpha \Delta w w=w−αΔw

当Δw\Delta wΔw>0, 意味着w将增大,反之w将减小。

总结:梯度就是函数参数的变化趋势,若只有一个变量时,就是导数

2. 反向传播算法

计算图和反向传播

通过计算图,我们可以轻易通过多个变量计算最后的结果 J(a, b, c),这也称之为向前计算。

其中,通过如图对各部分的导数的计算,我们可以轻易地获得任意变量之间的偏导

如:
dJdb=3×1×cdJdc=3×1×b\frac {dJ} {db} = 3\times 1\times c \quad \frac {dJ}{dc} = 3 \times 1\times b dbdJ​=3×1×cdcdJ​=3×1×b

3. 使用梯度算法实现线性回归

3.1 手动实现线性回归

案例分析:

  1. x为200 ×\times× 1的矩阵,让y = x ×\times× 3 + 0.8
  2. w, b初始化为任意数,用于计算获得原式子中的"3"和"0.8"
  3. 让y_predict赋值为 x ×\times×w+b, 计算出在该参数条件下预测出的y值
  4. 计算loss,并通过loss.backward()计算反向传播,从而获取各个参数的梯度。
  5. 通过公式w=w−αΔww = w - \alpha \Delta ww=w−αΔw 计算出新的参数,并跳回第3步

代码演示:

import torch
import matplotlib.pyplot as plt
#1. y = 4x + 0.3
x = torch.rand([200, 1])
y = x * 3 + 0.8
learning_rate = 0.01;#设置学习率,即公式中的α#2. 通过模型计算y_predict
w = torch.rand([1, 1], requires_grad=True)  #require_grad为要求系统计算梯度,也即是纪录该计算图,才可以后面使用backward()进行反向传播
b = torch.tensor(0, requires_grad=True, dtype=torch.float32)
y_predict = y;
plt.figure(figsize=(20, 8)) #通过plt画图for i in range(1000):  #循环1000次训练y_predict = torch.mm(x, w) + bloss = (y - y_predict).pow(2).mean()if w.grad is not None : #若梯度不空,则必须先对其置零操作,否则无法进行下一步的反向传播w.grad.zero_()if b.grad is not None :b.grad.zero_()loss.backward();w.data = w.data - learning_rate*w.grad;b.data = b.data - learning_rate*b.grad;print("第" , i ,"次 循环: w ,b = ", w, " ", b)if i == 0:  ##画出第一条线,形状为点线,颜色为蓝色plt.plot(x.numpy().reshape(-1), y_predict.detach().numpy().reshape(-1), 'b-.')elif i % 100 == 0:#当为100的整数,画一条形状为虚线,颜色为黑色的线plt.plot(x.numpy().reshape(-1), y_predict.detach().numpy().reshape(-1), 'k--')print("结束时: w ,b = ", w, " ", b)
# print("结束时: y_predict = ", y_predict)
print("结束时: loss = ", loss)
y_predict = torch.mm(x, w) + bplt.scatter(x.numpy().reshape(-1), y.numpy().reshape(-1))#画点,通过点描绘真实y的线
plt.plot(x.numpy().reshape(-1), y_predict.detach().numpy().reshape(-1), "r-") #画出最后一条预测线,颜色为红色,线为实线
plt.show()  ##画线

效果展示:

循环1000次时:

第 999 次 循环: w ,b =  tensor([[2.5627]], requires_grad=True)   tensor(1.0495, requires_grad=True)
结束时: w ,b =  tensor([[2.5627]], requires_grad=True)   tensor(1.0495, requires_grad=True) //跟原来的3x+0.8还是有很大差距的
结束时: loss =  tensor(0.0149, grad_fn=<MeanBackward0>)

其中: 最下面的蓝色点线,为第一次的预测y线;黑色线为第1次到999次的线,蓝色点线为真实值y线,红色线为最后一次的预测线;我们可以看到,随着训练数量的增加,预测y线越来越接近真实值y线

循环5000次时:

第 4999 次 循环: w ,b =  tensor([[2.9958]], requires_grad=True)   tensor(0.8021, requires_grad=True)
结束时: w ,b =  tensor([[2.9958]], requires_grad=True)   tensor(0.8021, requires_grad=True)  //跟上面的1000次作对比,可以看到这次的参数已经很接近真实值了
结束时: loss =  tensor(1.3419e-06, grad_fn=<MeanBackward0>)

改变学习率为0.1, 循环1000次

第 999 次 循环: w ,b =  tensor([[3.0000]], requires_grad=True)   tensor(0.8000, requires_grad=True)
结束时: w ,b =  tensor([[3.0000]], requires_grad=True)   tensor(0.8000, requires_grad=True) //居然直接找到了精确值,实际上在第826次就找到了
结束时: loss =  tensor(4.9771e-12, grad_fn=<MeanBackward0>)

可以看到,通过增大学习率,使得模型更快地建立起来,只是在其他模型有可能会导致获取精确的模型。

3.2 pytorch的api实现线性回归

代码展示

import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as pltx = torch.rand([200, 1])
y = x*3 + 0.8# 1.定义模型,优化器类实例化,loss实例化
class Ln(nn.Module):def __init__(self):super(Ln, self).__init__()self.linear = nn.Linear(1, 2) #分别为输入和输出的特征数,在本例子中为列数,它会自动为你申请参数def forward(self, x):out = self.linear(x)return outmodel = Ln()
y_pre = 0
optimizer = optim.SGD(model.parameters(), lr=0.01)
lossFun = nn.MSELoss() ##初始化回归损失函数
plt.figure(figsize=(20, 8))
param = 0
print("长度为 : ", len(list(model.parameters())))for i in range(1000):y_pre = model(x) #计算y预测值loss = lossFun(y, y_pre) #计算损失optimizer.zero_grad()   #更新梯度为0loss.backward() #反向传播计算梯度optimizer.step()     #通过梯度更新各个参数param = list(model.parameters())print("第" , i ,"次 循环: w ,b = ", param[0], " ", param[1])if i == 0:plt.plot(x.numpy().reshape(-1), y_pre.detach().numpy().reshape(-1), 'b-.')elif i % 100 == 0:plt.plot(x.numpy().reshape(-1), y_pre.detach().numpy().reshape(-1), 'k--')print("结束时 w ,b = ", param[0], " ", param[1])
print("损失为 : " , lossFun(y, y_pre))
plt.scatter(x.numpy().reshape(-1), y.numpy().reshape(-1))
plt.plot(x.numpy().reshape(-1), y_pre.detach().numpy().reshape(-1), "r-")
plt.show()

效果展示

4. 常见优化算法

1. 梯度下降算法(batch gradient descent BGD)

每次迭代都将所有样本放入,这样每次迭代都顾及所有样本,做的是全局优化。

缺点: 速度慢,需要考虑所有样本

2.随机梯度下降法 (SGD)

从样本随机抽出一组,训练后更新一次,然后再抽取一组再更新一次,在样本量很大的情况下,可能不用训练完就可以获得损失值较小的模型了。

缺点:随机性强,但由于单个样本的训练可能带来很多噪声,往往会出现在开始训练时收敛的很快,训练一段时间之后变得很慢。

torch的api为:

  torch.optim.SGD()

3. 小批量梯度下降(MBGD)

从样本抽取一小批进行训练,而不是一组,平均了速度和效果。

4. 动量法(Momentum)

小批量SGD虽然速度快,但是在最优点时难以精确,而是在最优点附近徘徊。

其次,另一缺点是小批量SGD需要我们挑选一个合适的学习率,当我们采用较小的学习率,会导致训练时收敛太慢;当我们使用较大的,就会导致训练时难以达到最优点。

基于梯度的移动指数加权平均,对网络的梯度进行平滑处理,让梯度的摆动幅度变得更小,更好地进入最优点
g=0.8g+0.2pregw为上一次的梯度w=w−αgα为学习率g = 0.8g + 0.2preg \quad w为上一次的梯度 \\ w = w - \alpha g \quad \alpha为学习率 g=0.8g+0.2pregw为上一次的梯度w=w−αgα为学习率
w变化例子:(w为公式中的g,即为梯度)

5. AdaGrad

AdaGrad可以让梯度自适应学习,让梯度从大变小。
v=v+preV2w=w−α(v+∂)preV∂为小常数,为了数值稳定通常设置为10−7v = v + preV^2 \\ w = w - \frac \alpha {(v + \partial )} preV \quad \partial为小常数,为了数值稳定通常设置为10^{-7} v=v+preV2w=w−(v+∂)α​preV∂为小常数,为了数值稳定通常设置为10−7
由公式我们不难看出梯度(prev)会受到v的受到影响,而v会随着次数增多逐渐变大,梯度会随之逐渐下降,从而实现梯度的自适应。

6. RMSProp

进一步优化函数在更新函数摆动幅度过大的问题,让步长越来越小。

对参数的梯度使用了平方加权平均数。

7. Adam(Adaptive Moment Estimation)

将Momentum算法和RMSP算法结合的一种算法,防止梯度的摆幅过大,也能增快收敛速度。

torch的api为:

torch.optim.Adam()

8. 效果演示

本文仅供自己参考学习使用,如有侵权立删

机器学习入门 - 梯度算法相关推荐

  1. 机器学习入门——梯度下降算法详解

    引言 本文介绍机器学习中非常重要的一个优化算法--梯度下降法.它不是一个机器学习算法,但是它是能帮助机器学习算法进行训练的算法.梯度下降法是基于搜索的最优化方法,它的作用是优化一个损失函数. 提示:本 ...

  2. 机器学习入门-kNN算法实现手写数字识别

    实验环境 Python:3.7.0 Anconda:3-5.3.1 64位 操作系统:win10 开发工具:sublime text(非必要) 简介 本次实验中的重点为采用kNN算法进行手写数字识别, ...

  3. 机器学习入门7--KNN算法

    本系列博客基于温州大学黄海广博士的机器学习课程的笔记,小伙伴们想更详细学习黄博士课程请移步到黄博士的Github.或者机器学习初学者公众号,现在在中国慕课也是可以学习的,内容包括机器学习.深度学习及P ...

  4. 机器学习入门-Knn算法

    knn算法不需要进行训练, 耗时,适用于多标签分类情况 1. 将输入的单个测试数据与每一个训练数据依据特征做一个欧式距离. 2. 将求得的欧式距离进行降序排序,取前n_个 3. 计算这前n_个的y值的 ...

  5. 学python的基础-老司机学python篇:第一季(基础速过、机器学习入门)

    本课程正在限时优惠中,请尽快购买 原价:¥350 优惠价:¥999.00 章节导航 课程大纲 第一章:python基础速过篇 开张课.我们直接开门见山,对着文档先把最基本的东西学一下.注意:关键看视频 ...

  6. 机器学习入门系列一(关键词:单变量线性回归,梯度下降法)

    机器学习入门系列一(关键词:单变量线性回归,梯度下降法) 如上图所示,我们的目标是希望通过这些数据得到城市人口数和利润可能的对应关系,并可以通过城市人口数(利润)来预测它的利润(城市人口数),在这里我 ...

  7. 新手入门机器学习十大算法

    新手入门机器学习十大算法 2018年9月17日 磐石 TensorFlowNews, 机器学习 0 在机器学习的世界中,有一种被称为"无免费午餐"的定理. 它意在说明没有哪种算法能 ...

  8. python3入门经典100例-Python3入门机器学习_经典算法与应用-慕课网实战

    建议慕课网可以出一套完整的关于学完之后可以胜任人工智能这份工作的课程,达到就业的目的和转型 亲,您好~目前我们在筹划更多的人工智能的相关课程!后期会逐步的跟大家见面!不过本门课程就是您迈入机器学习领域 ...

  9. 机器学习入门(九):非监督学习:5种聚类算法+2种评估模型

    机器学习入门专栏其他章节: 机器学习入门(一)线性回归 机器学习入门(二)KNN 机器学习入门(三)朴素贝叶斯 机器学习入门(四)决策树 机器学习入门(五)集成学习 机器学习入门(六)支持向量机 机器 ...

最新文章

  1. 参与开源项目,结识技术大牛!CSDN “开源加速器计划”招募志愿者啦!
  2. Centos 7 全网备份Rsync
  3. 阿里云oss 上传图片 python3
  4. python基础指令-python基础语法,python 代码命令大全
  5. hdu3367 Pseudoforest
  6. 实习生解雇_我们解雇了我们的顶尖人才。 我们做出的最佳决定。
  7. asp.net 递归删除文件夹及其子文件夹和所有文件[转]
  8. MySQL学习记录 (二) ----- SQL数据查询语句(DQL)
  9. 在chrome开发者工具中观察函数调用栈、作用域链、闭包
  10. 活动回顾 I 《传奇动物园》项目团队沙盘演练圆满结束!
  11. 搭建ASP环境-win7安装IIS并运行ASP程序
  12. 拼多多搬家上货助手怎么用?方法步骤有?
  13. 迪杰斯特拉算法c语言6,迪杰斯特拉算法C语言实现
  14. 如何封装svg矢量图
  15. bilibili 实时平台的架构与实践
  16. 2022年K1刷第三方固件教程
  17. firnbsp;提交的版本的iphone4amp;nbs…
  18. Kubadem方式安装Kubernetes(1.10.0)集群
  19. paramiko.ssh_exception.SSHexception:Server connection dropped:
  20. python歌词分析_用Python分析周杰伦6.5W字的歌词,原来他是这样的人

热门文章

  1. MATLAB优化函数fmincon的简介
  2. JS:冒泡排序 (思路+代码)详解
  3. FAQ-MT6250/MT6250D平台,FM外放时耳机无声
  4. Linux下basename使用及代码实现
  5. 基于opencv的人脸、眼睛、鼻子、微笑识别
  6. php万国码,如何认识编码
  7. 多线程案例之遍历二叉树
  8. php后台密码 忘记,ZenCart忘记后台密码找回密码
  9. 2021行车记录仪什么牌子质量好
  10. 米家扫地机器人重置网络_米家扫地机器人 怎么清理传感器