dl_1-extra

深度学习笔记(一)补充:深刻理解梯度下降

在《Deep learning》一书中关于方向导数如何求导的部分被简略带过了,在进行深入思考以后进行了推导如下:

重新回到问题:

给定方向函数 $f(x+\alpha u)$,其中 $x$ 是一个 $m \times 1$ 的列向量,$\alpha $ 是一个 $m \times n$ 的矩阵,$u$ 是一个 $n \times 1$ 的方向向量,求在 $\alpha=0$ 的时候关于 $\alpha$ 的方向导数.

使用链式法则,我们可以得到:

$\frac{\partial f}{\partial \alpha}=\frac{\partial (\alpha u)}{\partial \alpha}\nabla_x f(x)$

如果要计算 $ y = Ax $ 关于矩阵 $ A $ 的梯度,也就是 $ \frac{\partial y}{\partial A} $,我们需要考虑 $ y $ 中每个元素相对于矩阵 $ A $ 中每个元素的偏导数。

设 $ y $ 是一个 $ m \times 1 $ 的列向量,$ A $ 是一个 $ m \times n $ 的矩阵,$ x $ 是一个 $ n \times 1 $ 的列向量。那么,$ y $ 的每个元素 $ y_i $ 可以表示为:

$ y_i = \sum_{j=1}^{n} A_{ij}x_j $

现在,我们来计算 $ y_i $ 关于 $ A_{pq} $ 的偏导数 $ \frac{\partial y_i}{\partial A_{pq}} $。当 $ p = i $ 时,有:

$ \frac{\partial y_i}{\partial A_{pq}} = x_q $

否则, $ \frac{\partial y_i}{\partial A_{pq}} = 0 $。

因此, $ \frac{\partial y}{\partial A} $ 是一个 $ m \times n $ 的矩阵,其中第 $ i $ 行第 $ j $ 列的元素是 $ x_j $(即输入向量 $ x $ 的第 $ j $ 个元素),如果 $ i = p $ 且 $ j = q $,否则为 0。

换句话说, $ \frac{\partial y}{\partial A} $ 中的每个元素都与输入向量 $ x $ 的对应元素相对应。

不完全正确。虽然在某些情况下, $ \frac{dy}{dA} $ 可以简化为 $ x $ 的转置,但并不总是如此。

在上面的计算中,我们得到了 $ \frac{dy}{dA} $ 的表达式,其中每个元素都与输入向量 $ x $ 的对应元素相对应。这意味着 $ \frac{dy}{dA} $ 的每一列都与 $ x $ 的对应元素相同,但并不是 $ x $ 的转置。

只有当输入向量 $ x $ 是一个单位向量时, $ \frac{dy}{dA} $ 才等于 $ x $ 的转置。因为在这种情况下, $ y $ 是 $ A $ 的列向量之和, $ \frac{dy}{dA} $ 的每列只有一个非零元素,即 $ x $ 的对应元素。

因此$\frac{\partial f}{\partial \alpha}=\frac{\partial (\alpha u)}{\partial \alpha}\nabla_x f(x)=u^T\nabla_x f(x)$

dl_1

深度学习笔记(一)数学&编程基础

在本节中,将《Deep learning》一书的数学基础与机器学习基础知识与d2l.ai的相关章节结合,辅以相关的python编程来讲解。

1 数据处理&预处理

1.1 数据处理

==(这是一个预先介绍的概念)==

张量:一个可能有很多维的数组

torch.arange():创建一个均匀间隔值的向量

1
2
x = torch.arange(10, dtype=torch.float32)
# tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])

x.shape:查看张量的形状

x.reshape():改变张量的形状

1
2
x.reshape(2,5)
# tensor([[0., 1., 2., 3., 4.], [5., 6., 7., 8., 9.]])

torch.zeros/ones:创建全0/1张量

torch.randn:从给定的概率分布中随机且独立地采样

1
2
torch.randn(3,4)
# tensor([[-0.7169, 0.0324, 0.2994, 0.7737], [ 1.2839, 1.6757, 1.1220, 0.8856], [ 0.4812, 0.5082, 0.2196, 1.3963]])

同样大小的张量可以直接进行四则运算与乘方运算

x.sum():张量内元素求和

索引:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
a = torch.rand(4,3,28,28)
a[0].shape # 第0张图片 torch.Size([3,28,28])

a[0,0].shape #取第0张图片的第0个通道 torch.Size([28,28])

a[0,0,2,4].shape #取第0张图片的第0个通道的第2行第4列的像素点 tensor(0.8082)

a[:2].shape #取前两张图片 torch.Size([2,3,28,28])

a[:2,:1,:,:].shape #取前两张图片第一个通道上的所有数据 torch.Size([2,1,28,28])

a[:2,1:,:,:].shape #取前两张图片后两个通道上的所有数据 torch.Size([2,2,28,28])

a[:2,-1:,:,:].shape #取前两张图片最后一个通道上的所有数据 torch.Size([2,1,28,28])

a[:,:,0:28:2,0:28:2].shape #对所有图片所有通道的长和宽隔行采样 torch.Size([4,3,14,14])

a[:,:,::2,::2].shape #对所有图片所有通道的长和宽隔行采样 torch.Size([4,3,14,14])

a.index_select(0,torch.tensor([0,2])).shape # 选第0张和第2张图片的所有通道所有长宽torch.Size([2,3,28,28])

a.index_select((1,torch.tensor([1,2])).shape # 选G,B通道所有图片所有长宽 torch.Size([4,2,28,28])

a.index_select((2,torch.arange(8)).shape #所有图片所有通道8行所有宽 torch.Size([4,3,8,28])

a[...].shape # torch.Size([4,3,28,28])

a[0,...].shape # torch.Size([3,28,28])

a[:,1,...].shape # torch.Size([4,28,28])

a[...,:2].shape # torch.Size([4,3,28,2])

1.2 数据预处理

数据集读取:

1
2
3
import pandas as pd

data=pd.read_csv(file) # 一个csv文件

数据准备:如果带有NaN,那么一种常见的启发方法是将其替换为相应列的均值

1
inputs = inputs.fillna(inputs.mean())

转换为张量:

1
2
3
import torch

x = torch.tensor(imputs.to_numpy(dtype=float))

2 线性代数

2.1 标量、向量、矩阵和张量

标量:单独的数

向量:一列有序排列的数

矩阵:一个二维数组

张量:一个数组中的元素分布在若干维坐标的规则网格中

在深度学习中通常利用张量进行计算,张量可以在GPU上进行加速。

1
2
3
4
5
x = torch.tensor(1.0) # 标量
x = torch.arange(3) # 向量
x = torch.arange(6).reshape(3,2) # 矩阵
x.T # 逆矩阵
x = torch.tensor(24).reshape(2,3,4) # 张量

2.2 矩阵和向量乘法

矩阵哈达玛积:C = A*B $res_{ij}=A_{ij}B_{ij}$

标量+张量:张量的每个元素与标量相加

标量*张量:张量的每个元素与标量相乘

向量点积:torch.dot(x, y)

矩阵乘法:C = A@B

2.3 范数

$l_1$范数:torch.abs(u).sum()

$l_2$范数:torch.norm(u)

2.4 微积分

pytorch具有自动微分功能,x.grad

值得注意的是,这个grad是累积的,因此在进行反向传播前需要进行梯度清零