IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> PyTorch深度学习实践——反向传播 -> 正文阅读

[人工智能]PyTorch深度学习实践——反向传播

总结:

? ? ?在这一节的学习中,学习到反向传播相关知识,对于反向传播算法,同样也是通过三个方面来进行总结:反向传播算法是什么?为什么需要反向传播?如何实现反向传播?

反向传播算法是什么?

给出官方定义:

? ? ?BP算法由信号的正向传播和误差的反向传播两个过程组成。

? ? ? ?正向传播时,输入样本从输入层进入网络,经隐层逐层传递至输出层,如果输出层的实际输出与期望输出(导师信号)不同,则转至误差反向传播;如果输出层的实际输出与期望输出(导师信号)相同,结束学习算法。

? ? ? 反向传播时,将输出误差(期望输出与实际输出之差)按原通路反传计算,通过隐层反向,直至输入层,在反传过程中将误差分摊给各层的各个单元,获得各层各单元的误差信号,并将其作为修正各单元权值的根据。这一计算过程使用梯度下降法完成,在不停地调整各层神经元的权值和阈值后,使误差信号减小到最低限度。

为什么需要反向传播?

? ? 回顾之前学习的简易的线性模型,我们拿到相应的输入x,然后通过权重值w和x相乘得到对应的输出y_hat,最后通过真实值y与y_hat作损失,通过梯度下降或者穷举的方法找到loss的最小值,然后对w进行更新,将线性模型使用简单的神经网络(Neurn)表示得到以下图:

? ? ?然而我们知道,深度学习模型不都是简单的线性模型,对于复杂的模型而言,权重与输入更为复杂:

? ? ?对于上图的解释,首先要提到的概念便是"输入维度",什么是输入的维度?对此我是这样理解的:我们知道空间中的维度分别对应点,线,面,体。

? ? ?对于维度我们也可以从这个角度来理解:维度是指一个属性(方向),那么什么是属性(方向)呢?举个例子,对于一个男生而言,拥有以下属性:

? ? ? 当财富是第一个属性时,那么穷-富这一方向便是这个属性所独有的,依次类推,身高,性别,好坏就是第二个属性,第三个属性,第四个属性.....但我们会发现,当对于一个男生而言,属性越多,这个男生也就更加的 "具体"了,也就是越来越有真实感(饱满),因此对于这里的数据维度输入,也是同样,不同的x1,x2,x3可以理解为对于一个模型不同方向的 "属性"输入,而这些属性来使得越复杂的模型越为饱满。

? ? ?再回归到上图:

?d

? ? ?当一个模型输入是多维的,在这里是5维,对于隐藏层h1而言,隐藏层的输出是6维度,而需要使得输入能与h1(h1是hide的简写也就是隐藏层1)的输出对应起来,那就涉及到维度转换,这里可以通过w权重矩阵进行转换,线性代数高数我们当权重矩阵w是6*5的向量时,输入的5维可以转换 为输出6维,因此在输入x-h1的权重矩阵需要6*5也就是30维w,依次类推h1-h2需要6*7=42维w,h2-h3中需要49维w,对于这种复杂的模型,函数之间是一个嵌套非常多的复杂结构,因此想写出loss的解析式变得几乎不可能实现,因此对于w的梯度也无法得到

? ? ?因此对于这种复杂的网络,我们考虑能不能将这种网络变成一个计算"图",使用某种方法将网络中的梯度进行传播,再利用链式法将最终的梯度求得,而不是直接求出loss函数再求得最终梯度,这种方法便是Backpropagation反向传播法

如何实现反向传播?

假定两层结构的神经网络:

? ? 构造出基本的计算图:

? ???对于第一次层结构,输入n维向量,输出m维向量,权重矩阵就该为m*n维矩阵,对于输入的m维向量加入的bias偏置值,我们同样也应该是m*1维的矩阵(每一个hide层单元都需要单独加上b值)。当x与y_hat都是多维输入和输出时,也就与上文神经网络图一一对应起来

? ???这种计算图也存在一个问题,每一层的输入都是上一次输入的线性函数,那么无论有多少隐藏层层我们也可以通过化简得到output与input的线性组合:

? ? 因此我们在每一层的神经网络中需要一个非线性函数单元Nonlinear Function进行处理,例如,将h1得到的x1转换为/1(1+e^-x1),同理对于x2,x3...也同样进行变换换,使得函数无法进行展开

? ? 计算图构建完毕,那么如何利用链式法制进行局部求导(梯度)呢?如下图:

loss对于z的求导可以看作后一层对于前层的返回结果(这里不用纠结),而为什么需要对于x的局部求导结果呢?对于第一层时,x的局部求导的确用处不大,但对于中间结果时候,是需要知道L对于x的导数结果的

给出具体实例:当模型为一层的网络结构并且b值为0时,假定w为1,输入x为1

? ? 因此对于反向传播求梯度可以这样理解,前馈时求得每一步的局部梯数,并且保存相应求导公式与值(y_hat,输入w值等)反向传播时,得到loss值后,然后利用链式法则反向传播消除局部梯度最终得到loss与w的梯度

代码实现:

? ?对于代码实现,需要提到tensor数据成员,类似c语言的结构体,分别存储节点的权重(data部分)和上述提到的局部导数(grad部分,grad其实也是一种tensor)

构建线性模型y=w*x的计算图

import torch
x_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]

w = torch.Tensor([1.0])
print(w)
w.requires_grad = True

def forwrad(x):#这一步会进行数值转换,将两者都转换为tensor变量
    return x*w

def loss(x,y):#理解为动态构建计算图
    y_pred = forwrad(x)
    return (y_pred-y)**2


for epoch in range(100):
    for x,y in zip(x_data,y_data):
        l = loss(x,y)
        l.backward()#将计算链上需要的梯度求出来并梯度结果存到变量中,这里涉及到的变量为w变量
        #调用完计算图会自动释放
        #print(w.grad.item())#把grad里的值变为标量输出
        w.data = w.data-0.01*w.grad.data#不取得grad的data部分会构建出计算图,我们只是对于权重的data部分进行修改
        w.grad.data.zero_()#w的梯度重置为0
    print("Progress",epoch,"%2f"%l.item())
#print(l)
#print(w.data)
#print(w.grad.item())#将梯度转换为标量
#print(w.grad.data)

构建二次模型y = w1*x1^2 + w2*x2 + b

?显然这个二次模型应该为:y=x^2+x+1,对应的结果w1=1,w2 =1,b=1,输入x为4对应预测值该为21

import torch
x_data = [1.0,2.0,3.0]
y_data = [3.0,7.0,13.0]

w1= torch.Tensor([0.3])
w1.requires_grad =True
w2 = torch.Tensor([0.5])
w2.requires_grad =True
b= torch.Tensor([0.8])
b.requires_grad = True


def forward(x):
    return w1*x**2 + w2*x + b
def loss(x,y):
    y_pred = forward(x)
    return (y_pred-y)**2

print("predict after training ", 4, forward(4).item())
for epoch in range(100):
    for x,y in zip(x_data,y_data):
        l = loss(x,y)
        l.backward()
        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
        print(f"Progress:{epoch}  w1.grad={w1.grad.data} w2.grad={w2.grad.data} b.grad={b.grad.data} loss={l.data.item()}")
        w1.grad.data.zero_()
        w2.grad.data.zero_()
        b.grad.data.zero_()
print(f"w1={w1.data.item():.2f}  w2={w2.data.item():.2f}   b={b.data.item():.2f}")
print("predict after training ", 4, forward(4).item())

结果展示:
?

?本人小白一枚,刚入深度学习坑,纯粹自我总结,有问题请大佬指出!不胜感激

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-08-25 12:12:14  更:2021-08-25 12:14:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 18:39:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码