PyTorch深度学习实践——反向传播

反向传播

课程来源:PyTorch深度学习实践——河北工业大学

《PyTorch深度学习实践》完结合集_哔哩哔哩_bilibili

笔记

在之前课程中介绍的线性模型就是一个最简单的神经网络的结构,其内部参数的更新过程如下:

PyTorch深度学习实践——反向传播

对于简单的模型来说可以直接使用表达式的方式来更新权重,但是如果网络结构比较复杂(如下图),直接使用解析式的方式来更新显然有些复杂且不太可能实现。

PyTorch深度学习实践——反向传播

反向传播就是为了解决这种问题。反向传播的基本思想就是将网络看成一张图,在图上传播梯度,从而使用链式传播来计算梯度。首先介绍两层的网络的计算图的方式表示如下图所示:

PyTorch深度学习实践——反向传播

矩阵求导参考书籍链接如下:https://bicmr.pku.edu.cn/~wenzw/bigdata/matrix-cook-book.pdf

如果把式子展开,将会有如下结果:

PyTorch深度学习实践——反向传播

也就是多层线性模型的叠加是可以用一个线性模型来实现的。因此为了提高模型的复杂程度,对于每一层的输出增加一个非线性的变化函数,如sigmoid等函数,如下图所示:

PyTorch深度学习实践——反向传播

反向传播的链式求导的过程一个实例如下图所示:

PyTorch深度学习实践——反向传播

得到相应导数之后就可以对于权重进行更新,如果x也只是一个中间结果,则可以继续向前传导。

接下来可以看一个完整的线性模型的计算图示例,过程就是先进行前馈过程,在前馈到loss之后进行反向传播,从而完成计算:

PyTorch深度学习实践——反向传播

接下来介绍在PyTorch中如何进行前馈和反馈计算。

首先需要介绍的是Tensor,这是PyTorch中构建动态图的一个重要组成部分,Tensor中主要元素的是Data(数据)和Grad(导数),分别用于保存权重值和损失函数对权重的导数。

使用PyTorch实现上述的线性模型的代码如下:

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

w = torch.tensor([1.0]) #初值为1.0
w.requires_grad = True # 需要计算梯度

def forward(x):
    return x*w  # 返回tensor

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 =loss(x,y) #l是一个张量
        l.backward() #将计算链路上需要梯度的地方计算出梯度,这一步之后计算图释放,每一次更新都创建新的计算图
        print('\tgrad:', x, y, w.grad.item())#item是为了把梯度中的数值取出为标量
        w.data = w.data - 0.01 * w.grad.data   # 权重更新时,使用标量,使用data的时候不会建立新的计算图,注意grad也是一个tensor
        w.grad.data.zero_() # 更新之后将梯度数据清零
    print('progress:', epoch, l.item())
print("predict (after training)", 4, forward(4).item())

作业

1、手动推导线性模型y=w*x,损失函数loss=(ŷ-y)²下,当数据集x=2,y=4的时候,反向传播的过程。

PyTorch深度学习实践——反向传播

2、手动推导线性模型 y=w*x+b,损失函数loss=(ŷ-y)²下,当数据集x=1,y=2的时候,反向传播的过程。

PyTorch深度学习实践——反向传播

3、画出二次模型y=w1 _x²+w2_x+b,损失函数loss=(ŷ-y)²的计算图,并且手动推导反向传播的过程,最后用pytorch的代码实现。

PyTorch深度学习实践——反向传播

代码如下:

import torch
import matplotlib.pyplot as plt
import numpy as np
x_data=[1.0,2.0,3.0]
y_data=[2.0,4.0,6.0]
w1=torch.tensor([1.0],requires_grad=True)
w2=torch.tensor([1.0],requires_grad=True)
b=torch.tensor([1.0],requires_grad=True)
epoch_list=[]
loss_list=[]
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 (befortraining)',4,forward(4))
for epoch in range(100):
    for x,y in zip(x_data,y_data):
        l=loss(x,y)
        l.backward()
        print('\tgrad:',x,y,w1.grad.item(),w2.grad.item(),b.grad.item())
        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
        w1.grad.data.zero_()
        w2.grad.data.zero_()
        b.grad.data.zero_()
        print('Epoch:', epoch, l.item())
        epoch_list.append(epoch)
        loss_list.append(l.data)
print('Predict(after training)', 4, forward(4).item())
print('predict (after training)', 4, forward(4))
plt.plot(epoch_list, loss_list)
plt.ylabel('loss')
plt.xlabel('epoch')
plt.show()

可视化loss如下:

PyTorch深度学习实践——反向传播

Original: https://www.cnblogs.com/Zhengsh123/p/15889625.html
Author: zsh1234
Title: PyTorch深度学习实践——反向传播

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/566058/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球