视频地址: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
之前提出的线性模型 = wx,如果以神经网络的视角代入来看,即x为输入层,w为权重,为输出层。在神经网络中,通常将w以及*计算的部分看作一个神经元(层),而神经元的训练过程即为更新w的过程,其更新的情况依赖于loss对w的偏导而并非 对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, = wx,loss=(-y)2=(x·w-y)2
前馈过程可求
=1;r=-1
对w的导数为1
r对的导数为1
r方对r的导数为-1
loss=1
反馈过程
loss对r的导数为-2
loss对的导数为-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())