PyTorch深度学习-04反向传播(快速入门)

在这里插入图片描述

“山高路远,只看自己”


1.Back Propagation (反向传播)

在图上进行梯度的传播,建立更具有弹性的模型结构

1.1 Computer gradient in simple network (简单神经网络)

在这里插入图片描述

1.2 Complicated network (复杂神经网络)

1.2.1 Backing Propagation Algorithm (反向传播算法)

面对复杂网络时,把网络看成一个图,在图上传播梯度,最后根据链式法则求出梯度,这种算法叫反向传播算法。
在这里插入图片描述

H = 权重矩阵 * 输入的x,其中x是5行1列矩阵(x属于5维矩阵),H是6行1列矩阵,所以权重矩阵是6行5列矩阵,因此有30个不同权重。

1.2.2 Computational Graph (计算图)

以两层神经网络为例
在这里插入图片描述
在这里插入图片描述设输入矩阵x的维度为n,隐层维度为m,则权重维度为m * n

经矩阵乘法H(1)=W1X,可得到中间隐层的输出。

计算图全过程如下
在这里插入图片描述

所有绿色模块为计算模块,不同的计算模块求局部偏导的计算方法不同

扫描二维码关注公众号,回复: 14623942 查看本文章

矩阵计算公式可参考matrix cookbook
http://faculty.bicmr.pku.edu.cn/~wenzw/bigdata/matrix-cook-book.pdf

不管一共有多少层,都可以统一为以下形式
在这里插入图片描述

为了提高模型复杂度,不能像上图一样将模型化简,否则增加的权重就没有意义了,所以要对每一层最终的输出加一个非线性的变化函数,对张量里的每一个值都应用一个非线性函数。
在这里插入图片描述

当加了非线性函数做变换后,式子就没办法展开了,才能做成真正的神经网络。

1.3 Backing Propagation算法步骤

Chain Rule (链式法则)
在这里插入图片描述

  1. Create Computation Graph(Forward)(创建计算图)
    在这里插入图片描述

  2. Local Gradient (局部求偏导)
    在这里插入图片描述

  3. Given gradient from successive node (连续节点梯度)
    在这里插入图片描述

  4. Use chain rule to compute the gradient (Backward)(使用链式法则计算梯度)
    在这里插入图片描述

Example:f = x * w
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.4 Computational Graph of Linear Model

在这里插入图片描述
r为残差,loss=r的平方

  • Exercise 1:Compute the gradient with Computational Graph
    在这里插入图片描述

解答:
在这里插入图片描述

  • Exercise 2:Compute gradient of Affine model
    在这里插入图片描述

解答:
在这里插入图片描述

2.Tensor in PyTorch

在PyTorch中进行前馈和反馈运算
在这里插入图片描述

3.Implementation of linear model with PyTorch

PyTorch实现线性模型

3.1 代码实现

import torch

x_data = [1.0, 2.0, 3.0, 4.0]
y_data = [2.0, 4.0, 6.0, 8.0]

w = torch.Tensor([1.0])
w.requires_grad = True  # 需要计算梯度


def forward(x):
    return x * w   # 其中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): # 训练100轮
    for x, y in zip(x_data, y_data):  # 将x_data,y_data zip成数据
        l = loss(x, y)   # 前馈,计算loss
        l.backward()     # 反馈,并会释放计算图。每进行一次反向传播就会释放计算图,并准备下一次的图
        print('\tgrad:', x, y, w.grad.item())  # 取w的data不会建立计算图
        w.data -= w.data - 0.01 * w.grad.data  # 张量的计算会构建计算图

        w.grad.data.zero_()  # 把权重里面梯度的数据全都清零

    print("progress:", epoch, l.item())

print("predict (after training)", 4, forward(4).item())

3.2 计算图

在这里插入图片描述

3.3 结果截图

在这里插入图片描述

3.4 Exercise

在这里插入图片描述

3.4.1 计算图

在这里插入图片描述

3.4.2 代码实现

import torch

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

w1 = torch.Tensor([1.0])  # 初始权值
w1.requires_grad = True  # 计算梯度,默认是不计算的
w2 = torch.Tensor([1.0])
w2.requires_grad = True
b = torch.Tensor([1.0])
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 (before training)', 4, forward(4))

for epoch in range(100):
    l = loss(1, 2)  # 为了在for循环之前定义l,以便之后的输出,无实际意义
    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  # 注意这里的grad是一个tensor,所以要取他的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())

print('Predict (after training)', 4, forward(4).item())

3.4.3 结果截图

在这里插入图片描述
本文参考:《PyTorch深度学习实践》


At the end of my article

我是璞玉牧之,持续输出优质文章,希望和你一起学习进步!!!原创不易,如果本文对你有帮助,可以 点赞+收藏+评论 支持一下哦!我们下期见~~
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_62307289/article/details/128826084