numpy 向量、梯度学习

学习目标——微积分 → 向量/矩阵 → 梯度 → 梯度下降 → 神经网络 → PyTorch——不建议你去找一本“泛数据分析型”的 NumPy 教程。那类资料会花大量篇幅讲 CSV、DataFrame、数据清洗,而你现在真正需要的是:

把数学对象直接映射成 NumPy 对象,并理解每个运算背后的数学含义。

我最推荐你把 《NumPy 2.2 User Guide》官方文档作为主教材,而且要按你现在的数学路线选择性学习,而不是从头到尾读。NumPy 官方的 2.2 文档与我们前面确定的 NumPy 2.2.6 属于同一 2.2 系列;官方文档同时提供 User Guide 和 API Reference。(NumPy)

第一推荐:NumPy 2.2 User Guide

在线版:

NumPy 2.2 User Guide

PDF 版:

NumPy 2.2 User Guide PDF

这份资料的好处是,它不是某个作者基于旧版 NumPy 写的教程,而是 NumPy 官方 2.2 文档;2.2 版的 User Guide 本身覆盖 array、broadcasting、ufunc、数据类型、线性代数等核心概念。(NumPy)

不过你不要按 PDF 的目录顺序学习。按照你现在正在学的“梯度下降 + 向量”,我建议压缩成下面这条路线。


你真正需要掌握的 NumPy 20%

第一阶段:把“向量”变成 NumPy 数组

先学:

import numpy as np

x = np.array([1, 2, 3])

重点不是记 np.array(),而是理解:

\[\mathbf{x}= \begin{bmatrix} x_1\\ x_2\\ x_3 \end{bmatrix} \]

对应:

x.shape
x.ndim
x.dtype

你必须彻底理解:

scalar   → 0-D
vector   → 1-D
matrix   → 2-D
tensor   → 3-D / 4-D / ...

这一部分对应官方文档的 The N-dimensional array (ndarray)、Array creation、Data types。(NumPy)

建议你做一个非常重要的实验:

x = np.array([1, 2, 3])

print(x)
print(x.shape)
print(x.ndim)
print(x.dtype)

然后:

x = np.array([[1, 2, 3],
              [4, 5, 6]])

print(x.shape)
print(x.ndim)

你以后学习 Transformer,实际上仍然是在不断回答:

这个对象到底是什么形状?


第二阶段:重点学习“向量运算”

这是你现在最重要的一层。

例如:

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

a + b
a - b
a * b
a / b

注意:

a * b

不是数学意义上的矩阵乘法,而是:

\[(a_1b_1,\;a_2b_2,\;a_3b_3) \]

这叫 element-wise operation(逐元素运算)。

而:

np.dot(a, b)

才是:

\[a\cdot b = a_1b_1+a_2b_2+a_3b_3 \]

这一步与你前面正在研究的点积、余弦相似度、向量夹角直接连接起来。


第三阶段:必须重点攻克 Broadcasting

对于你以后学习深度学习而言,broadcasting 的重要性仅次于 ndarray 本身。

例如:

x = np.array([1, 2, 3])
x + 10

实际上相当于:

\[(1,2,3)+(10,10,10) \]

但 NumPy 不需要真的复制出一个新的 (10,10,10) 数组,而是按照 broadcasting 规则完成计算。NumPy 官方把 broadcasting 作为核心数组运算机制之一。(Pythonic Perambulations)

尤其要学会:

x.shape
x[:, None].shape
x[None, :].shape

例如:

x = np.array([1, 2, 3])

print(x.shape)
print(x[:, None].shape)
print(x[None, :].shape)

得到:

(3,)
(3, 1)
(1, 3)

这个东西看起来只是 NumPy 技巧,实际上它背后就是你正在学的:

向量空间 + 维度 + 坐标表示

以后 PyTorch 的 Tensor 广播基本就是同一个思想。


第四阶段:ufunc——理解 NumPy 为什么“快”

你需要认真学习 NumPy 的 Universal Functions(ufunc)。

例如:

np.exp(x)
np.log(x)
np.sqrt(x)
np.sin(x)
np.cos(x)

这些函数都是逐元素作用于数组。

例如:

x = np.array([1.0, 2.0, 3.0])
np.exp(x)

数学上就是:

\[e^{x} = (e^{x_1},e^{x_2},e^{x_3}) \]

这和以后神经网络中的:

\[\sigma(x)=\frac{1}{1+e^{-x}} \]

直接连接。

NumPy 官方文档明确把 ufunc 和 vectorized computation 作为核心机制;它们让大量数组运算可以在底层高效执行,而不是让 Python 层逐个元素循环。(Pythonic Perambulations)


第五阶段:Linear Algebra——这是你当前的核心

然后直接进入:

np.linalg

重点学习:

np.dot()
np.matmul()
np.linalg.norm()
np.linalg.solve()
np.linalg.inv()
np.linalg.det()

其中你当前最应该掌握的是:

① 向量长度

\[\|\mathbf{x}\| = \sqrt{x_1^2+x_2^2+\cdots+x_n^2} \]

对应:

np.linalg.norm(x)

② 点积

\[\mathbf{x}\cdot\mathbf{y} = \sum_i x_i y_i \]

对应:

np.dot(x, y)

③ 矩阵乘法

\[C=AB \]

对应:

A @ B

④ 矩阵与向量

\[\mathbf y=A\mathbf x \]

对应:

y = A @ x

这一行代码其实特别值得你现在好好理解,因为:

线性代数中的“线性变换” → NumPy 中的 @ → 神经网络中的 Linear Layer

是一条非常直接的路线。

NumPy 2.2 的 Reference 中专门有 numpy.linalg 以及 vector/matrix norm、determinant、rank 等线性代数内容。(NumPy)


第六阶段:你现在可以立刻用 NumPy 实现“梯度下降”

这才是我认为最适合你目前学习阶段的 NumPy 练习。

例如函数:

\[f(x)=x^2 \]

导数:

\[f'(x)=2x \]

梯度下降:

\[x_{t+1}=x_t-\eta\,2x_t \]

直接写:

x = 10.0
learning_rate = 0.1

for i in range(20):
    gradient = 2 * x
    x = x - learning_rate * gradient
    print(x)

你会看到:

8.0
6.4
5.12
...

最后:

\[x\rightarrow0 \]

然后把它升级成:

\[f(x,y)=x^2+y^2 \]

梯度:

\[\nabla f= \begin{bmatrix} 2x\\ 2y \end{bmatrix} \]

NumPy:

x = np.array([10.0, 5.0])

lr = 0.1

for i in range(20):
    gradient = 2 * x
    x = x - lr * gradient
    print(x)

这里你就第一次真正把:

\[\boxed{\text{微积分}} \rightarrow \boxed{\text{梯度}} \rightarrow \boxed{\text{向量}} \rightarrow \boxed{\text{NumPy}} \rightarrow \boxed{\text{梯度下降}} \]

连起来了。


一个特别重要的地方:不要把 np.gradient() 当成“梯度下降的梯度”

NumPy 确实存在:

np.gradient()

它用于计算 N 维数组的数值梯度,官方数学函数文档也明确列出了这个函数。(NumPy)

但你现在学习梯度下降时,不要依赖它来理解梯度。

你应该先手推:

\[f(x)=x^2 \]

\[f'(x)=2x \]

再手写:

gradient = 2 * x

然后:

x -= lr * gradient

之后再学:

\[f(x_1,x_2,\ldots,x_n) \]

以及:

\[\nabla f= \begin{bmatrix} \frac{\partial f}{\partial x_1}\\ \frac{\partial f}{\partial x_2}\\ \vdots\\ \frac{\partial f}{\partial x_n} \end{bmatrix} \]

最后才进入 PyTorch:

x = torch.tensor(..., requires_grad=True)

loss.backward()

这样你会真正理解 PyTorch 自动微分到底在替你做什么,而不是把 backward() 当成一个黑盒函数。


所以,你现在只需要学 NumPy 这几个模块

可以把 NumPy 2.2 官方 User Guide 压缩成下面这张“学习地图”:

NumPy
│
├── ndarray
│   ├── shape
│   ├── ndim
│   ├── dtype
│   └── axis
│
├── Array creation
│
├── Indexing / slicing
│
├── Broadcasting          ★★★★★
│
├── ufunc                 ★★★★
│
├── Aggregation
│   ├── sum
│   ├── mean
│   └── max/min
│
├── reshape / transpose    ★★★★★
│
├── Linear Algebra         ★★★★★
│   ├── dot
│   ├── @
│   ├── norm
│   └── solve
│
└── Random

暂时不用学:

文件 I/O
结构化数组
字符串数组
C API
F2PY
NumPy 内部开发

这些现在对你的“微积分 → 梯度下降 → AI”路线收益很低。


还有一本资料值得你以后看,但现在不要把它当主教材

Nicolas P. Rougier 的《From Python to NumPy》非常适合你理解 vectorization(向量化)。NumPy 官方 Learn 页面也把它列为推荐学习资源;它的核心思想就是“从 Python 的循环思维转向 NumPy 的向量化思维”。(NumPy)

但它是 2017 年的资料,示例基于 NumPy 1.12,因此不适合当你的版本基准。(GitHub)

所以我的建议非常明确:

主教材:NumPy 2.2 官方 User Guide

学习重点:ndarray → shape/axis → indexing → broadcasting → ufunc → reshape → dot/@ → norm → linear algebra

训练方式:每学一个 NumPy 操作,马上用它表达一个数学公式。

这比单纯背 numpy 函数有效得多。

对于你现在的阶段,最值得做的下一步其实是建立一份 “微积分/线性代数公式 → NumPy 代码”对照表,例如把「标量、向量、范数、点积、矩阵乘法、偏导、梯度、方向导数、梯度下降」全部对应到 NumPy,一边学数学一边写代码。

posted @ 2026-09-10 13:46  立体风  阅读(39)  评论(0)    收藏  举报