吴恩达深度学习复盘(6)神经网络的矢量化原理

发布于:2025-04-08 ⋅ 阅读:(36) ⋅ 点赞:(0)

矢量化基础是线性运算,这里先简单复习一下。线性基本运算基本没什么,大量使用的有点乘和叉乘。

基本例子

 1. 矩阵的基本概念

- 矩阵可以看作是一个块或者二维数组,这是对矩阵的一个在计算机计算的直观描述。

2. 向量的点积(内积)

- 例子:以向量(1, 2)和向量(3, 4)为例

- 计算过程

1×3 + 2×4 = 3 + 8 = 11

- 总结:

对于向量\vec{a}和向量\vec{w}

假设\vec{a}=(a_1, a_2, \cdots, a_n)

\vec{w}=(w_1, w_2, \cdots, w_n)

它们的点积Z的计算方式是Z = a_1×w_1 + a_2×w_2 + \cdots + a_n×w_n,也就是将对应元素相乘后再把所有乘积相加。

- 等价表示:

向量\vec{a}通常可以用列向量表示,通过取\vec{a}的转置(即将列向量变为行向量,记为\vec{a}^T),可以得到点积的另一种等价表示形式。

例如,若\vec{a}是一2x1的列向量,转置后\vec{a}^T是一个1×2的行向量。此时,\vec{a}\vec{w}(\vec{w}为2×1列向量)的点积就等于\vec{a}^T乘以\vec{w},即Z = \vec{a}^T \vec{w}。这种表示方式在理解矩阵乘法时非常有用,因为它将向量的点积与矩阵乘法联系了起来。


3. 向量与矩阵的乘法

- 设定向量和矩阵:

设向量\vec{A} = \begin{bmatrix}2 & 3 & 4\end{bmatrix}
设矩阵W是一个3 \times 2的矩阵,W = \begin{bmatrix}5 & 6 \\ 7 & 8 \\ 9 & 10\end{bmatrix}

- 计算乘积矩阵的元素:

这里n = 3m = 2,我们来计算\vec{A}W

结果矩阵的第一个元素:用向量\vec{A}与矩阵W的第一列向量做点积,即2×5 + 3×7 + 4×9\)\(= 67

结果矩阵的第二个元素:用向量\vec{A}与矩阵W的第二列向量做点积,即2×6 + 3×8 + 4×10\)\(= 76

所以,\vec{A}W = \begin{bmatrix}67 & 76\end{bmatrix}

 - python点乘例子

import numpy as np

# 定义向量 A
A = np.array([[2, 3, 4]])

# 定义矩阵 W
W = np.array([[5, 6],
              [7, 8],
              [9, 10]])

# 计算向量与矩阵的乘积
result = np.dot(A, W)

print("向量与矩阵的乘积结果:", result)

4. 矩阵与矩阵的乘法

设矩阵A = \begin{bmatrix}1 & 2 & 3\\ 4 & 5 & 6\end{bmatrix},这是一个2\times3的矩阵;矩阵B = \begin{bmatrix}7 & 8\\ 9 & 10\\ 11 & 12\end{bmatrix},这是一个3\times2的矩阵。

根据矩阵乘法的规则,因为A的列数(3列)等于B的行数(3行),所以A和B可以相乘,结果矩阵C = AB的行数等于A的行数(2行),列数等于B的列数(2列),即C是一个2\times2的矩阵。

接下来计算C中各个元素的值:

  • c_{11}(C的第一行第一列元素): A的第一行元素与B的第一列元素对应相乘再相加,即c_{11}=1\times7 + 2\times9 + 3\times11\)\(= 58
  • c_{12}(C的第一行第二列元素): A的第一行元素与B的第二列元素对应相乘再相加,即c_{12}=1\times8 + 2\times10 + 3\times12\)\(= 64
  • c_{21}(C的第二行第一列元素): A的第二行元素与B的第一列元素对应相乘再相加,即c_{21}=4\times7 + 5\times9 + 6\times11\)\(= 139
  • c_{22}(C的第二行第二列元素): A的第二行元素与B的第二列元素对应相乘再相加,即c_{22}=4\times8 + 5\times10 + 6\times12\)\(= 154

所以,矩阵C = AB = \begin{bmatrix}58 & 64\\ 139 & 154\end{bmatrix}

NumPy 库来验证:

import numpy as np

A = np.array([[1, 2, 3],
              [4, 5, 6]])
B = np.array([[7, 8],
              [9, 10],
              [11, 12]])

C = np.dot(A, B)
print(C)

转向矩阵\vec{A}^T W通用例子

设向量\vec{A}n\times1的列向量\vec{A}=\begin{bmatrix}a_1 \\ a_2 \\ \vdots \\ a_n\end{bmatrix},矩阵W为n\times m的矩阵

W = \begin{bmatrix}w_{11} & w_{12} & \cdots & w_{1m}\\ w_{21} & w_{22} & \cdots & w_{2m}\\ \vdots & \vdots & \ddots & \vdots\\ w_{n1} & w_{n2} & \cdots & w_{nm}\end{bmatrix}

根据向量与矩阵乘法规则(用向量转置后的行向量与矩阵相乘),\vec{A}^T W得到的结果是一个1\times m的矩阵(行向量)。

计算过程如下:

\vec{A}^T W=

\begin{bmatrix}a_1 & a_2 & \cdots & a_n\end{bmatrix}\begin{bmatrix}w_{11} & w_{12} & \cdots & w_{1m}\\ w_{21} & w_{22} & \cdots & w_{2m}\\ \vdots & \vdots & \ddots & \vdots\\ w_{n1} & w_{n2} & \cdots & w_{nm}\end{bmatrix}

=

\begin{bmatrix}a_1w_{11}+a_2w_{21}+\cdots+a_nw_{n1} & a_1w_{12}+a_2w_{22}+\cdots+a_nw_{n2} & \cdots & a_1w_{1m}+a_2w_{2m}+\cdots+a_nw_{nm}\end{bmatrix}

5. 笔者注:

无论是向量与矩阵相乘,还是矩阵与矩阵相乘,本质上都涉及到很多向量之间的点积运算,并且是按照一定的顺序来构建结果矩阵(如Z)的元素,一次计算一个元素。其实是规则的嵌套,函数的函数。

矢量化展开的原理和例子

 1.简介

- 以矩阵A,说明其转置A^T表示,即把A的列变为行。在NumPy中,除了常规的转置理解方式外,还可以使用A_T = A.T这样的函数来计算转置,该函数会将矩阵的列横向排列。

- 给出矩阵W,通过Z = np.dot(A_T, W)(np指NumPy库)这样的代码计算矩阵Z(Z = A^T W)。python在一些代码中可能会看到Z = AT @ W这种写法,这也是计算矩阵乘法的另一种方式,使用np.dot更清晰。

2.矢量化原理

假设输入特征值为 [2, 17],我们将其看作矩阵 A 的转置 A_T,这是一个 1x2 的矩阵。

设权重矩阵 W 是一个 2x3 的矩阵,偏置矩阵 B 是一个 1x3 的矩阵,具体数值如下:

A_T = [2, 17]
W = [[1, 2, 3],
     [4, 5, 6]]
B = [[10, 20, 30]]

计算 Z = A^T W + B

  • 计算 A^T W
    • A^T W的第一个元素:2\times1 + 17\times4 = 2 + 68 = 70
    • A^T W的第二个元素:2\times2 + 17\times5 = 4 + 85 = 89
    • A^T W的第三个元素:2\times3 + 17\times6 = 6 + 102 = 108
    • 所以 A^T W = [70, 89, 108]
  • 再加上偏置矩阵 B:
    • Z 的第一个元素:70 + 10 = 80
    • Z 的第二个元素:89 + 20 = 109
    • Z 的第三个元素:108 + 30 = 138
    • 所以Z = [80, 109, 138]

应用激活函数 g

假设激活函数 g 是 sigmoid 函数,其公式为g(x)=\frac{1}{1 + e^{-x}}

  • g(80)\approx1
  • g(109)\approx1
  • g(138)\approx1

所以最终的输出矩阵 a = [1, 1, 1]

3.代码例子

import numpy as np

# 定义 sigmoid 激活函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

# 输入特征值矩阵 A 的转置
A_T = np.array([[2, 17]])

# 权重矩阵 W
W = np.array([[1, 2, 3],
              [4, 5, 6]])

# 偏置矩阵 B
B = np.array([[10, 20, 30]])

# 计算 Z = A^T W + B
Z = np.dot(A_T, W) + B

# 应用激活函数 g 得到输出矩阵 a
a = sigmoid(Z)

print("Z 的值:", Z)
print("a 的值:", a)    

4.矢量化实现的优势

只需要几行代码就能在神经网络中实现一个问题,并且能获得巨大的速度提升。原因是现代计算机擅长高效地实现矩阵乘法(如`np.dot`对应的操作),利用快速硬件可以非常有效地完成大规模矩阵乘法运算。

笔者注:用纯cpu集群训练理论是可以的,但是是不现实的。


网站公告

今日签到

点亮在社区的每一天
去签到