《动手学深度学习》笔记1.3——矩阵求导

目录

1. 数学概念

1.1 标量导数

1.2 向量求导(梯度)

1.2.1 标量y,关于向量x求导

梯度

1.2.2 向量y,关于标量x求导

分子布局符号

1.2.3 向量y,关于向量x求导

1.2.4 对矩阵求导(拓展)

1.3 QA(拓展)

2. 自动求导

2.1 向量的链式法则

2.2 自动求导 -- 定义

2.3 计算图 -- PyTorch 的内部工作原理

2.4 自动求导的两种模式 -- 正向积累 vs 反向传递 

2.5 反向传递

2.6 复杂度 -- 反向传递vs正向

3. 自动求导(PyTorch 实现)

3.1 案例引入

3.2 非标量变量的反向传播

3.3 分离计算

3.4 Python控制流的梯度计算


李沐老师的讲解思路是先从数学概念引入,讲完以后再到代码实现:

1. 数学概念

1.1 标量导数

1.2 向量求导(梯度)

分为四种情况:

1.2.1 标量y,关于向量x求导

李沐老师这里先讲了y为标量,x为向量的情况,x长度为1的列向量,关于列向量的导数(即梯度)行向量,具体解释如下:

在这个例子里, 𝑦= {x_1{}}^{2}+​ {2x_2{}}^{2} 描述的是一个二维空间中的二次曲面,其在三维空间中的形状是一个椭圆锥面(eccentric cone)。

李沐老师:可以不用记忆这个导数怎么求,但一定要理解 (导数运算的核心概念 -- 梯度)

梯度
  • 理解1:这个曲面在二维平面上投影为一个椭圆,类似于地理上的“等高线”;它是一个标量函数,因为输出 𝑦 是一个单一的数值,而不是一个向量
  • 理解2:梯度是一个向量,它在多元函数的每一点上指向函数增长最快的方向(极为关键,这也是今后所有机器学习求解的核心思想
  • 理解3:梯度方向就是那个使得方向导数(即变化率)达到最大的方向
  • 理解4:梯度方向与等高线的切线是正交的
  • 理解5:y关于x的梯度”,就是y关于x的求导结果

(补充:“dy/dx” 通常读作 “dee-y over dee-x”,其中 “over” 指分数中的 “之上/之下” 的关系)

李沐老师最后还给出了一些样例:

(最后这里,有个很有意思的点:两个向量的导数是一个矩阵。现在还没讲,后面会讲)

(GPT是我们的好朋友,我有问题都靠他)

1.2.2 向量y,关于标量x求导

李沐老师:关于分子还是分母布局,总得选一个,这样形状才能对上,所以这里一般是用“分子布局符号”

分子布局符号

以下是智谱AI给出的解释:

分子布局(Numerator Layout):

  • 在分子布局中,矩阵的行被视为“分子”,而列被视为“分母”。
  • 当进行矩阵与向量的乘法时,矩阵位于乘法的左侧,向量位于右侧。例如,如果 A 是一个 m×n 的矩阵,b 是一个 n 维列向量,那么它们的乘积 Ab 是一个 m 维列向量
  • 在分子布局中,矩阵的行与向量的列相乘,得到的是向量

分母布局(Denominator Layout):

  • 在分母布局中,矩阵的列与向量的行相乘,得到的是向量

在许多数学和编程环境中,默认的或更常用的约定是分子布局

1.2.3 向量y,关于向量x求导

两个向量之间的求导,可以拆解为m个 “1.2.1 标量y,关于向量x求导” 的问题

这里的加粗大写字母 “I” 通常用来表示单位矩阵(Identity Matrix),大概长这样:

1.2.4 对矩阵求导(拓展)

图形右边括号里的是 求导结果  “形状”

李沐老师:矩阵和矩阵之间的求导大概了解即可,不用 (像前三种那样) 完全弄懂

1.3 QA(拓展)

  • 导数的作用主要是梯度下降,容易陷入局部最优解,只有在凸函数上才有可能避免这个问题(使用李雅普诺夫函数、模拟退火函数等),不幸的是,机器学习中几乎不会处理凸函数
  • 李沐老师答疑说不用纠结最优解这个问题

2. 自动求导

2.1 向量的链式法则

李沐老师:标量的链式法则,拓展到向量,最重要的是把形状搞对

关于“形状”:

  • (1,) 指标量,表示一个包含单个元素的数组,例如 [5] 或者 [x]。
  • (1,n) 指1行n列的行向量,例如 [1, 2, 3] 便是一个 (1,3) 的行向量。
  • (2,5,4) 数组可以理解为有2个5行4列的矩阵组成的

李沐老师还具体举了个例子,来讲清楚两个向量求导具体是怎么计算的:

李沐老师:这其实就是我们以后要讲的,线性回归的一个例子,对线性回归做一次求导

解读:

  1. 假设:和 都是长为 n 的向量,y是一个标量,z 等于 和 w 作点积,减去y做平方
  2. 计算:z 关于 w 的导数,得先分解
  3. 分解:把长式子分解为三个小步骤(一层一层换元),用上链式法则排个序,z在最外层,a 在最里层,随后在分子部分按照 z, b, a 的由外至内的顺序逐个展开
  4. d<x,w>关于dw的求导结果为什么是x的转置,可参考 “1.2.3 向量y,关于向量x求导
  5. 最后是 b 带回去,因为点积的结果是标量,最后输出的结果是 行向量(经过缩放后的 x 的转置)

李沐老师:当然我们可以再往前走一点点,涉及到 矩阵 的例子2:

李沐老师:其实这个跟之前(例子1)一样,都是先分解出中间变量,就不详细讲啦,这样我们就知道矩阵求导,是怎么求出来的了~

2.2 自动求导 -- 定义

2.3 计算图 -- PyTorch 的内部工作原理

李沐老师:

  • 当然我们使用pytorch不需要大家去理解计算图,但我觉得大家有必要去知道一下它的内部的工作原理
  • 计算图等价于我们刚刚用链式法则求导的过程
  • 小圆圈表示输入,或者计算

李沐老师这里做了个 TensorFlow 和 PyTorch 的对比,用的是两种不同的构造方式。

2.4 自动求导的两种模式 -- 正向积累 vs 反向传递 

李沐老师:

  • 正向积累:从x出发,从第一个中间变量u_{1}开始,逐渐向最终的y函数求导
  • 反向传递:y,即最终的函数,关于最后的中间变量u_{n}的导数,来乘以导数第二个,不断往前往前......来算到最前面
  • 反向传递 (反向积累) 在人工智能领域鼎鼎大名

2.5 反向传递

(2)和(3)都要读取,才能计算(4)

2.6 复杂度 -- 反向传递vs正向

李沐老师:

  • 正向和反向,计算复杂度差不多,但是内存复杂度差很多
  • 反向传递需要把所有正向计算中间结果存起来,这也是深度神经网络特别耗GPU资源的最大祸源
  • 正向积累内存复杂度虽然低(不用像反向传递那样存储每次结果),但它的问题是,我们计算每一个变量的梯度,需要多扫一遍
  • 我们通常在神经网络里不会用正向积累,因为我们需要对每一层计算梯度,正向积累的计算复杂度太高

智谱AI:为什么深度学习不用正向传播

  • 如果我们尝试使用一种类似于正向传播的方式来直接计算梯度,那么对于每个参数的梯度计算,我们可能都需要重新执行一次完整的前向传播。这是因为在前向传播中,如果不保存中间层的输出,我们就无法直接从当前层回溯到前面层来计算梯度。
  • 如果我们考虑每个参数都需要单独的前向传播,那么正向积累计算复杂度是标准反向传播n倍

3. 自动求导(PyTorch 实现)

可参考官方课程jupyter文档(我这里直接上放上文档截图):

3.1 案例引入

关键概念:y关于x的梯度”,就是y关于x的求导结果

3.2 非标量变量的反向传播

李沐老师:这就意味着,我们之前大篇幅讲的向量和向量、矩阵和矩阵的求导,在我们深度学习里面用得是很少的

(言外之意:深度学习大都是标量和向量之间求导

3.3 分离计算

3.4 Python控制流的梯度计算

李沐老师:

  • 这个循环计算,是由输入的a, b(主要), c 来控制的
  • 这里pytorch的工作原理:每次计算,torch都会在背后把计算图存下来
  • 把计算图倒回去,算一遍,就能得到它的矩阵
  • 这里的a是生成的随机数,也就是说,不管a是什么数,都能算出控制流的梯度
  • 这就是pytorch(隐式)的好处,控制流也能求导,但会比TensorFlow(显式)慢一些

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值