Pytorch ——基础指北_贰

软件环境:

– pytorch 1.10
– pycharm

支持代码下载地址:

gitee-pytorch

基础知识:

要训​​练网络,必须了解梯度。我们先介绍一些渐变的基本概念。

1、多元函数求偏导

一元函数,即只有一个参数。类似于f%28x%29

一个多元函数,即有多个自变量。类似于f%28x%2Cy%2Cz%29%2C%E4%B8%89%E4%B8%AA%E8%87%AA%E5%8F%98%E9%87%8Fx%2Cy%2Cz

在求多元函数偏导的过程中:取一个自变量的导数,把其他自变量当作常数。

例1:
f%28x%2Cy%2Cz%29%20%3D%20ax%2Bby%2Bcz%20%5C%5C%20%5C%5Cans%3A%5C%5C%20%5Cfrac%7Bdf%28x%2Cy%2Cz%29%7D%7Bdx%7D%20%3D%20a%20%5C%5C%20%5Cfrac%7Bdf%28x%2Cy%2Cz%29%7D%7Bdy%7D%20%3D%20b%20%5C%5C%20%5Cfrac%7Bdf%28x%2Cy%2Cz%29%7D%7Bdz%7D%20%3D%20c

例2:
f%28x%2Cy%29%20%3D%20xy%20%5C%5C%20%5C%5Cans%3A%5C%5C%20%5Cfrac%7Bdf%28x%2Cy%29%7D%7Bdx%7D%20%3D%20y%5C%5C%20%5Cfrac%7Bdf%28x%2Cy%29%7D%7Bdy%7D%20%3D%20x

实践:

已知J%28a%2Cb%2Cc%29%20%3D%203%28a%2Bbc%29%2C%E4%BB%A4u%3Da%2Bv%2Cv%20%3D%20bc,求a,b,c各自的偏导数。
%E4%BB%A4%3AJ%28a%2Cb%2Cc%29%20%3D%203u%5C%5C%20%5Cfrac%7BdJ%7D%7Bda%7D%20%3D%5Cfrac%7BdJ%7D%7Bdu%7D%20%5Ctimes%20%5Cfrac%7Bdu%7D%7Bda%7D%20%3D%203%5Ctimes1%20%5C%5C%20%5Cfrac%7BdJ%7D%7Bdb%7D%20%3D%5Cfrac%7BdJ%7D%7Bdu%7D%20%5Ctimes%20%5Cfrac%7Bdu%7D%7Bdv%7D%20%5Ctimes%20%5Cfrac%7Bdv%7D%7Bdb%7D%20%3D%203%5Ctimes1%5Ctimes%20c%20%5C%5C%20%5Cfrac%7BdJ%7D%7Bdc%7D%20%3D%5Cfrac%7BdJ%7D%7Bdu%7D%20%5Ctimes%20%5Cfrac%7Bdu%7D%7Bdv%7D%20%5Ctimes%20%5Cfrac%7Bdv%7D%7Bdc%7D%20%3D%203%5Ctimes1%5Ctimes%20b%20%5C%5C

2、方向导数:

简单地说方向导数形容的是满足某个关系下(Y=KX+B),对于各个方向上本关系数值变化率(Y的变化率)的量化表达式。

数学推导:

你可以参考:

方向导数1 第一章

方向导数2

设L是XOY平面(笛卡尔坐标系)上以P%28X_0%2CY_0%29为始点的一条射线,e_l%20%3D%20%28%20%5Ccos%20%5Calpha%20%2C%20%5Ccos%20%5Cbeta%29是与 L 同方向的单位向量。

Pytorch ——基础指北_贰

射线L的参数方程为
%5Cleft%5C%7B%5Cbegin%7Barray%7D%7Bl%7Dx%3Dx_%7B0%7D%2Bt%20%5Ccos%20%5Calpha%20%5C%5C%20y%3Dy_%7B0%7D%2Bt%20%5Ccos%20%5Cbeta%28t%20%5Cgeq%200%29%5Cend%7Barray%7D%5Cright.
假设t沿l方向增加,函数增量为
%5CDelta%20z%20%3Df%5Cleft%28x_%7B0%7D%2Bt%20%5Ccos%20%5Calpha%2C%20y_%7B0%7D%2Bt%20%5Ccos%20%5Cbeta%5Cright%20%29-f%5Cleft%28x_%7B0%7D%2C%20y_%7B0%7D%5Cright%29%5C%5C%20%28%5CDelta%20x%20%3D%20t%20%5Ccos%20%5Calpha%2C%5CDelta%20y%20%3D%20t%20%5Ccos%20%5Cbeta%29
所以方向导数有如下定义:
%5Cleft.%20%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20l%7D%5Cright%7C_%7B%5Cleft%28x_%7B0%7D%2C%20y_%7B0%7D%5Cright%29%7D%3D%5Clim%20_%7Bt%20%5Crightarrow%200%5E%7B%2B%7D%7D%20%5Cfrac%7Bf%5Cleft%28x_%7B0%7D%2Bt%20%5Ccos%20%5Calpha%2C%20y_%7B0%7D%2Bt%20%5Ccos%20%5Cbeta%5Cright%29-f%5Cleft%28x_%7B0%7D%2C%20y_%7B0%7D%5Cright%29%7D%7Bt%7D

%5Ctext%20%7B%20%E4%BB%8E%E6%96%B9%E5%90%91%E5%AF%BC%E6%95%B0%E7%9A%84%E5%AE%9A%E4%B9%89%E5%8F%AF%E7%9F%A5%2C%E6%96%B9%E5%90%91%E5%AF%BC%E6%95%B0%20%7D%5Cleft.%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20l%7D%5Cright%7C_%7B%5Cleft%28x_%7B0%7D%2C%20y_%7B0%7D%5Cright%29%7D%20%5Ctext%20%7B%20%E5%B0%B1%E6%98%AF%E5%87%BD%E6%95%B0%20%7D%20f%28x%2C%20y%29%20%5Ctext%20%7B%20%E5%9C%A8%E7%82%B9%20%7D%20P_%7B0%7D%5Cleft%28x_%7B0%7D%2C%20y_%7B0%7D%5Cright%29%20%5Ctext%20%7B%20%E5%A4%84%E6%B2%BF%E6%96%B9%E5%90%91%20%7D%20l%20%5Ctext%20%7B%20%E7%9A%84%E5%8F%98%E5%8C%96%E7%8E%87.%20%7D

定理:

%5Ctext%20%7B%20%E5%A6%82%E6%9E%9C%E5%87%BD%E6%95%B0%20%7D%20f%28x%2C%20y%29%20%5Ctext%20%7B%20%E5%9C%A8%E7%82%B9%20%7D%20P_%7B0%7D%5Cleft%28x_%7B0%7D%2C%20y_%7B0%7D%5Cright%29%20%5Ctext%20%7B%20%E5%8F%AF%E5%BE%AE%E5%88%86%2C%E9%82%A3%E4%B9%88%E5%87%BD%E6%95%B0%E5%9C%A8%E8%AF%A5%E7%82%B9%E6%B2%BF%E4%BB%BB%E4%B8%80%E6%96%B9%E5%90%91%20%7D%20l%20%5Ctext%20%7B%20%E7%9A%84%E6%96%B9%E5%90%91%E5%AF%BC%E6%95%B0%E5%AD%98%E5%9C%A8%2C%E4%B8%94%E6%9C%89%20%3A%7D

%5Cleft.%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20l%7D%5Cright%7C_%7B%5Cleft%28x_%7B0%7D%2C%20y_%7B0%7D%5Cright%29%7D%3Df_%7Bx%7D%5Cleft%28x_%7B0%7D%2C%20y_%7B0%7D%5Cright%29%20%5Ccos%20%5Calpha%2Bf_%7By%7D%5Cleft%28x_%7B0%7D%2C%20y_%7B0%7D%5Cright%29%20%5Ccos%20%5Cbeta%20%5C%5C%E6%B3%A8%E6%84%8F%E9%87%8C%E9%9D%A2%E4%B8%BA%E5%81%8F%E5%AF%BC%20%E5%AE%9E%E9%99%85%E4%B8%8A%E5%B0%B1%E5%88%86%E8%A7%A3%E6%88%90%E4%BA%86X%20Y%E8%BD%B4%E4%B8%8A%E5%87%BD%E6%95%B0%E5%8F%98%E5%8C%96%E7%8E%87

其中%5Ccos%20%5Calpha%20%5Ctext%20%7B%20%E5%92%8C%20%7D%20%5Ccos%20%5Cbeta是方向I的方向余弦。

3、梯度:

梯度是方向导数的一个特例:
%5Coperatorname%7Bgradf%7D%28x%2C%20y%29%20%3D%20%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20x%7D%20%5Cdot%7Bi%7D%2B%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20y%7D%20%5Cdot%7Bj%7D
已知一点有方向导数,关系如下:
%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20l%7D%3D%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20x%7D%20%5Ccos%20%5Cvarphi%2B%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20y%7D%20%5Csin%20%5Cvarphi%3D%5Cleft%5C%7B%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20x%7D%2C%20%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20y%7D%5Cright%5C%7D%20%5Ccdot%5C%7B%5Ccos%20%5Cvarphi%2C%20%5Csin%20%5Cvarphi%5C%7D

在方向L上满足如下单位向量:
%5Coverrightarrow%7B%5Cboldsymbol%7Be%7D%7D%3D%5Ccos%20%5Cvarphi%20%5Coverrightarrow%20%7B%20%5Cboldsymbol%7Bi%7D%7D%2B%5Csin%20%5Cvarphi%20%5Coverrightarrow%7B%20%5Cvec%7Bj%7D%20%7D

那么方向导数可以转化为:
%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20l%7D%20%3D%20%5Coperatorname%7Bgradf%7D%28x%2C%20y%29
点积相当于一个投影,方向导数与梯度(做点积)保持一定的角度,形成各个方向的方向导数。方向向量何时最大?很容易认为没有夹角的时候可以满足,因为此时的最大点积满足以下条件:
%5Ctext%20%7B%20%E5%8F%AA%E6%9C%89%E5%BD%93%20%7D%20%5Ccos%20%28%5Coperatorname%7Bgrad%7D%20f%28x%2C%20y%29%2C%20%5Cvec%7Be%7D%29%3D1%20%EF%BC%8C%20%5Cfrac%7B%5Cpartial%20f%7D%7B%5Cpartial%20l%7D%20%5Ctext%20%7B%20%E6%89%8D%E6%9C%89%E6%9C%80%E5%A4%A7%E5%80%BC%E3%80%82%20%7D
函数在某一点的梯度是一个向量,其方向与方向导数最大值的方向相同,其大小正好是最大方向导数。

梯度概念理解:如下图所示,在P点放一个热源的等温线,则热源的辐射从里到外为10°、20°、30°、40°,若一个小蚂蚁在o点,要最快逃离热源,应该往OJ方向逃离,若往OM方向逃离则热源的变化率为0,即一直都是20°,也就是说蚂蚁一旦确定了某个逃离方向(0°,90°)方向角逃离,只要一直沿着该方向一直走,就是最快的热源降低的方向

Pytorch ——基础指北_贰
对于一维线性函数其导数就是梯度。

各种函数的梯度与导数的关系:

函数梯度

更详细的解释可以参考参考链接。

Tensor的梯度与反向传播

回顾机器学习

收集数据x,建立机器学习模型f,得到f%28x%2Cw%29%20%3D%20Y_%7Bpredict%7D

如何判断模型的好坏?如何判断模型好坏:
%5Cbegin%7Barray%7D%7Bll%7D%20%5Coperatorname%7Bloss%7D%3D%5Cleft%28Y_%7Bp%20r%20e%20d%20i%20c%20t%7D-Y_%7B%5Ctext%20%7Btrue%20%7D%7D%5Cright%29%5E%7B2%7D%20%26%20%5Ctext%20%7B%20%28%E5%9B%9E%E5%BD%92%E6%8D%9F%E5%A4%B1%29%20%7D%20%5C%5C%20%5Coperatorname%7Bloss%7D%3DY_%7B%5Ctext%20%7Btrue%20%7D%7D%20%5Ccdot%20%5Clog%20%5Cleft%28Y_%7B%5Ctext%20%7Bpredict%20%7D%7D%5Cright%29%20%26%20%5Ctext%20%7B%20%28%E5%88%86%E7%B1%BB%E6%8D%9F%E5%A4%B1%29%20%7D%20%5Cend%7Barray%7D
通过最终loss的输出,利用反向传播计算梯度大小,然后调整参数大小,达到最优解。

如图所示,满足loss

Pytorch ——基础指北_贰

梯度计算后:在梯度变化的方向上操作,随机选择一个起点w_0,调整w_0使loss函数取最小值。

Pytorch ——基础指北_贰

w更新方法:

  1. 计算w的梯度(导数)

%5Cnabla%20w%20%3D%20%5Cfrac%7Bf%28w%2B0.000001%29-f%28w-0.000001%29%7D%7B2%2A0.000001%7D

  1. 更新w
    w%20%3D%20w%20-%20%5Calpha%20%5Cnabla%20w

在:

  1. w%20%3C0,意味着w将增大
  2. w%20%3E0,意味着w将减小

总结:梯度是多元函数的参数变化趋势(参数学习的方向)。当自变量只有一个时,称为导数;当自变量不止一个时,称为偏导数。

反向传播?

计算图

为了描述的方便,功能以图表的方式进行描述。

J%28a%2Cb%2Cc%29%20%3D%203%28a%2Bbc%29%2C%E4%BB%A4u%3Da%2Bv%2Cv%20%3D%20bc,可表示为:
Pytorch ——基础指北_贰

每个节点的偏导数可以是:
Pytorch ——基础指北_贰
反向传播的过程是一个从右到左的过程,如上图所示。自变量a%2Cb%2Cc各自的偏导数是连接线上的梯度的乘积:

%5Cfrac%7BdJ%7D%7Bda%7D%20%3D%203%20%5Ctimes%201%20%5C%5C%20%5Cfrac%7BdJ%7D%7Bdb%7D%20%3D%203%20%5Ctimes%201%20%5Ctimes%20c%20%5C%5C%20%5Cfrac%7BdJ%7D%7Bdc%7D%20%3D%203%20%5Ctimes%201%20%5Ctimes%20b

为什么要计算反向传播?

因为要计算梯度。

实际演示:

接下来尝试计算一个简单结构的梯度,问题描述如下:

假设我们的基础模型就是y = wx+b,其中w和b均为参数,我们使用y = 3x+0.8来构造数据x、y,所以最后通过模型应该能够得出w和b应该分别接近3和0.8。

简单的来说就是拟合出满足y = 3x+0.8这个曲线。

步骤分为四个步骤:

# 1 构造数据
# 2 设计正向传播 和 反向传播函数 来训练网络
# 3 训练
# 4 画图画出拟合出来的曲线

过程如下:

从左到右是前向传播部分

从右到左是反向传播部分

网络训练过程

对于W和B其计算类似,这里单独说B即可

对于B的梯度满足下式,值得注意的是这里的Loos求取的是平均值实际上出来的是一个标量,对于标量的梯度计算实际上也是一个平均值(这里值得思考一下)。

%5Cfrac%7B%5Cpartial%20Loss%7D%7B%5Cpartial%20B%7D%20%3D%20%5Csum_%7Bi%3D0%7D%5EN%202%2A%28y_i-y_%7Bpi%7D%29/N
反向传播后对B进行梯度下降:

B%20%3D%20B%20-%20rate%20%2A%5Cfrac%7B%5Cpartial%20Loss%7D%7B%5Cpartial%20B%7D
梯度下降以后再次进行正向传播即可,计算出来Y_p,最后计算出来Loss。

前向传播满足以下公式:
Y_%7Bpredict%20%280...N%29%7D%20%3DX_%7Bpredict%20%280...N%29%7D%2A%20W%20%2B%20B
代码显示如下:

import torch
import numpy as np
import matplotlib.pyplot as plt

# 1 构造数据
x_number = 50
x = torch.rand([x_number, 1])
y = 3 * x + 0.8
rate = 0.01
study_time = 3000

# 2 正向传播 和 反向传播
w = torch.rand([1, 1], requires_grad=True, dtype=torch.float32)
b = torch.rand(1, requires_grad=True, dtype=torch.float32)
y_preidct = torch.matmul(x, w) + b


def forward_propagation():
    global x, w, b, y_preidct
    y_preidct = torch.matmul(x, w) + b
    # 计算 loss
    loss = (y - y_preidct).pow(2).mean()
    return loss


def back_propagation():
    global x, w, b, loss, rate, y_preidct
    test = 0.0
    if w.grad is not None:
        w.grad.data.zero_()
    if b.grad is not None:
        b.grad.data.zero_()
    # 反向传播
    loss.backward()
    w.data -= w.grad * rate
    b.data -= b.grad * rate
    #此处为了验证b的梯度进行计算
    # for j in range(x_number):
    #   test += ((y[j] -y_preidct[j].item()) * 2) 
    # print("b:", b.grad)
    # print("b_t:", test/x_number)


# 3 训练部分
for i in range(study_time):
    loss = forward_propagation()
    back_propagation()
    if i % 10 == 0:
        print("w,b,loss", w.item(), b.item(), loss.item())

# 4 画图部分
predict = x * w + b  # 使用训练后的w和b计算预测值
plt.scatter(x.data, y.data, c="r")
plt.plot(x.data.numpy(), predict.data.numpy())
plt.show()

红色是数据集结果,蓝色是训练结果:

训练次数较少时,拟合曲线不正确:

Pytorch ——基础指北_贰

当学习率降低(变化范围缩小)时,增加学习次数可以得到很好的效果:

Pytorch ——基础指北_贰

参考:

国内教程 偏理论 (10 -13 节)

youtobe教程 (第三节)(需要科学上网)有需要搬运联系我

方向导数1

方向导数2

版权声明:本文为博主据说这是zzy原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/qq_20540901/article/details/123157368

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
乘风的头像乘风管理团队
上一篇 2022年2月28日 下午7:57
下一篇 2022年2月28日 下午8:19

相关推荐