Java教程

反向传播

本文主要是介绍反向传播,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

视频地址:https://www.bilibili.com/video/BV1NE41147Nt?spm_id_from=333.880.my_history.page.click

笔记地址:https://blog.csdn.net/Jackydyy/article/details/117233027?spm=1001.2014.3001.5502

  之前提出的线性模型 \widehat{y}= wx,如果以神经网络的视角代入来看,即x为输入层,w为权重,\widehat{y}为输出层。在神经网络中,通常将w以及*计算的部分看作一个神经元(层),而神经元的训练过程即为更新w的过程,其更新的情况依赖于loss对w的偏导而并非 \widehat{y}对w的偏导。

线性模型

 

 

 

 ·随机梯度下降(stochastic gradient descent):

 

  在随机梯度下降算法的过程中我们用一个单独样本的损失对w求导,并使用上面公式进行求导。

·损失函数的导数(derivative of loss function)解析式:

 

对于简单网络可以使用以上模型的解析式进行处理

 -----------------------------------------------------------------------

对于复杂网络

 

 以上图为例

X1、X2、X3、X4、X5为输入,x的维度为5向量;

H(1)为隐层1;

h1(1)为隐层1的第一个神经元,因为该层共有6个神经元所以h1(1)的维度为6

从图片可以看出影响h1(1)的w一共有5个即

X1→h1(1)==w1 1

X2→h1(1)==w2 1

X3→h1(1)==w3 1

.。。。

因为X[5,1]矩阵,h[6,1]矩阵

h=w·X

所以w为[6,5]矩阵

权重数列为30

当数据从隐层1传播到隐层2时2

按前理解可知权重w为[6,7]矩阵数量为42

以此类推权重数量有几百个

类似该中复杂网络如果利用之前学习到的梯度下降算法(解析式求解)的形式去解决非常麻烦不利于实行。

面对如此复杂网络,能否设计一种算法可以把网络看成一副图(计算图),我们可以在图上传播梯度,最终根据链式法则将梯度求出,该种算法我们称之为反向传播算法(Back propagation)

--------------------------------------------------------------------------------

反向传播算法(Back propagation)

1.计算图:

 

图为一个两层神经网络的计算图,W为权重,X为输入,b为偏置与隐层维度一致,

图中MM表示矩阵乘法(Matrix multiplication);

FirstLayer为一个完整的全连接层;

在计算图中,绿色的模块为计算模块,可以在计算过程中求导

(Matrix cook)

在一个网络中,输入X为n维向量,输出H为m维向量,那么权重w一定为m*n维,有些教材中w会加转置,那么w的转载就是n*m维向量。

 

*注意

 

 神经网络可以做图上的化简,导致多层无效

 

 

 为解决多层权重无效的问题,在每层结束后增加一个非线性变化函数

---------------------------------------------------------------------------

2.链式法则

 

 

f(g(x)=fog(x)

3.反向传播的过程:

3.1前馈计算:

在某一神经元处,输入的x与w经过函数f(x,w)计算,可以获得输出值z,并继续向前以得到损失值loss。

在向前计算的过程中,在f(x,w)计算模块中会计算z对x的导数以及z对w的导数,并将其保存下来(在pytorch中,这样的值保存在变量x以及w中)

3.2反向传播:

根据求导的链式法则,求得loss以后,前面的神经元会将loss对z的偏导的值反向传播给原先的神经元,在计算单元f(x,w)中,

将得到的loss对x的偏导与之前存储的导数相乘,就可得到损失值对于权重以及输入层的导数,基于该梯度才能进行权重的调整。

 

 

 

 Pytorch中的前馈与反馈:
利用Pytorch进行深度学习,最重要的是构建计算图。

Tensor(张量):Tensor其实是一个类,里面有两个重要的成员,data用于保存权重本身的值w,grad用于保存损失函数loss对权重w的导数,grad本身十个张量,对张量进行的计算操作,都是建立计算图的过程。
例子

f=x·w

 

 

 按计算图计算,z对x的导数为w,z对w的导数为x

当x=2,w=3时z=6

l对z的导数为5

计算可得L关于x导数为15,L关于w的计算为10,

3.3完整传播流程

已知x=1,w=1,y=2, \widehat{y}= wx,loss=(\widehat{y}-y)2=(x·w-y)2

前馈过程可求

\widehat{y}=1;r=-1

\widehat{y}对w的导数为1

r对\widehat{y}的导数为1

r方对r的导数为-1

loss=1

反馈过程

loss对r的导数为-2

loss对\widehat{y}的导数为-2

loss对w的导数为-2

这个过程中一般对loss进行保存可以查看loss的收敛情况,判断该模型是否可行。

------------------------------------------------------------------

练习1

 

 -----------------------------------------------------------------------------------------

练习2

 

 Pytorch中的前馈与反馈:
利用Pytorch进行深度学习,最重要的是构建计算图。

Tensor(张量):Tensor其实是一个类,里面有两个重要的成员,data用于保存权重本身的值w,grad(导数)用于保存损失函数loss对权重w的导数,grad本身是个张量,对张量进行的计算操作,都是建立计算图的过程。

import torch
 
x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]
 
#赋予tensor中的data
w = torch.Tensor([1.0])
#设定需要计算梯度grad
w.requires_grad = True
 
#模型y=x*w 建立计算图
def forward(x):
    '''
    w为Tensor类型
    x强制转换为Tensor类型
    通过这样的方式建立计算图
    '''
    return x * w
# 每调用一次loss函数,计算图就动态重新构建一次
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 x,y in zip(x_data,y_data):
        # l是最后计算的tensor,可以调用它的成员函数backward()
        l = loss(x,y)
        #loss为一个张量,所以loss可以调用backword函数,
        #该函数会将计算链上所有需要梯度的地方,将梯度求出。
        #将所有的梯度存到变量中
        #该模型中变量为w。
        #当所有梯度存到w后,该计算图被释放,
        #可以理解为只要做backword()函数后,计算图消失,下次进行loss计息会重新生成计算图。
        l.backward()
        #grad.item()取grad中的值变成标量
        print('\tgrad:',x, y, w.grad.item())#打印输出x,y和w的梯度的标量
        #单纯的数值计算要利用data,而不能用张量,否则会在内部创建新的计算图
        w.data = w.data - 0.01 * w.grad.data#权重更新。注意grad属于tensor,该处不需要计算图,w.grad.data后不会重新建立计算图
        w.grad.data.zero_()#将w对loss的导数清零
    print("progress:",epoch, l.item())
print("predict (after training)", 4, forward(4).item())

 

这篇关于反向传播的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!