AI数学基础(三):微积分——理解”变化”的语言

17世纪,伦敦瘟疫中的天才

1665年,伦敦爆发了一场可怕的瘟疫(后来被称为”伦敦大瘟疫”)。

剑桥大学被迫关闭,一个23岁的年轻人收拾行李,回到了家乡林肯郡的伍尔索普庄园。

他的名字叫艾萨克·牛顿(Isaac Newton)。

接下来的两年里,在这个安静的乡村庄园中,牛顿做出了改变人类历史的发现:微积分(Calculus)。

他当时在思考一个看似简单的问题:

“物体的瞬时速度到底是什么?”

你想想看,如果你开车,速度表显示”60 km/h”——这个”瞬时速度”是怎么来的?你总不能”瞬间”跑60公里吧?

牛顿的回答:用极限的思想,把”变化”放大到无穷小,就能捕捉到那一刻的变化率。

300多年后,这个”捕捉变化”的思想,成了人工智能最核心的工具。

因为深度学习的本质,就是”找最优”——而找最优,需要理解变化


一、为什么学AI要懂微积分?

深度学习的终极目标:找最优

训练一个AI模型(比如识别猫狗的神经网络),本质上是在做一件事:

调整参数,让”错误”最小。

这个过程叫做优化(Optimization)。

而优化的核心工具,就是微积分!

具体来说:

  1. 定义一个”损失函数”(衡量AI犯了多少错)
  2. 计算损失函数的导数(往哪个方向调整参数,错误会下降?)
  3. 沿着”错误下降最快”的方向调整参数(梯度下降
  4. 重复步骤2-3,直到错误最小

没有微积分,AI就无法”学习”。


二、导数是什么?开车速度表的秘密

直觉:导数是”瞬时变化率”

生活比喻:汽车速度表

你开车时,速度表显示的是”瞬时速度”——这一刻,你每小时能跑多少公里。

但严格来说,”这一刻”你根本没动(时间是0,距离也是0)。

导数的定义:用极限的思想,计算”极短时间内的平均速度”,让时间趋近于0,就得到了瞬时速度。

1
导数 = lim(Δt→0) (Δ距离 / Δt)

翻译成人话:

导数就是**”变化率”**——当输入变化一点点时,输出变化多少?

几何意义:切线的斜率

如果你画一个函数 y = f(x) 的曲线,那么在某一点的导数,就是曲线在那一点切线的斜率

  • 切线越陡(斜率越大),函数变化越快
  • 切线水平(斜率为0),函数达到局部最大值或最小值

AI中的应用:当导数为0时,函数达到”极值点”——这就是我们要找到的”最优解”!


三、导数直觉:”斜率越大,变化越快”

故事:爬山和下山

想象你在山上,想找到最快的下山路径。

  • 斜率很陡(导数绝对值大):你在一个很陡的地方,下一步能下降很多
  • 斜率平缓(导数接近0):你快到山脚了,下降速度变慢

AI训练的过程,就是”蒙着眼下山”

  1. 你不知道山的全貌(不知道损失函数的完整形状)
  2. 但你能感觉脚下的坡度(能计算当前点的导数)
  3. 所以你往坡度最陡的方向走一步(梯度下降)
  4. 重复,直到走到山底(损失最小)

Python实战:计算简单函数的导数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import numpy as np

# 定义函数 f(x) = x²
def f(x):
return x**2

# 数值方法计算导数(定义法)
def derivative(f, x, h=1e-5):
return (f(x + h) - f(x)) / h

# 测试
x = 3
print(f"f({x}) = {f(x)}")
print(f"f'({x}) ≈ {derivative(f, x)}") # 应该接近 2x = 6
print(f"理论值: {2*x}")

# 输出:
# f(3) = 9
# f'(3) ≈ 6.000010000016665
# 理论值: 6

解释

  • f(x) = x² 的导数理论上是 f'(x) = 2x
  • x=3 这一点,导数应该是 6
  • 我们用数值方法(定义法)算出来是 6.00001,非常接近!

四、链式法则:多米诺骨牌效应

直觉:一个量影响另一个,再影响下一个

生活比喻:多米诺骨牌

你推倒第一块骨牌(A影响B),B倒下撞到C(B影响C),C又撞到D…

链式法则(Chain Rule)就是这个意思:

如果 y 依赖于 u,而 u 依赖于 x,那么:

1
dy/dx = (dy/du) × (du/dx)

翻译成人话:

“y对x的变化率” = “y对u的变化率” × “u对x的变化率”

为什么这个对AI重要?反向传播就是链式法则!

深度学习有个核心算法叫反向传播(Backpropagation),用于训练神经网络。

它的原理就是:从输出层往输入层,一层一层地用链式法则计算导数

想象一个神经网络:

1
输入 → 隐藏层1 → 隐藏层2 → ... → 输出

要计算”调整第一层的参数,对最终错误的影响”,就得用链式法则,把后面每一层的影响都算进去!

Python实战:链式法则计算

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
import numpy as np

# 复合函数:y = sin(x²)
# 令 u = x²,则 y = sin(u)
# 根据链式法则:dy/dx = dy/du × du/dx = cos(u) × 2x = cos(x²) × 2x

def f(x):
return np.sin(x**2)

def derivative_chain_rule(x):
u = x**2
dy_du = np.cos(u) # dy/du = cos(u)
du_dx = 2*x # du/dx = 2x
return dy_du * du_dx

# 数值方法验证
def derivative_numerical(f, x, h=1e-5):
return (f(x + h) - f(x)) / h

# 测试
x = 2
print(f"链式法则计算的导数: {derivative_chain_rule(x):.6f}")
print(f"数值方法验证的导数: {derivative_numerical(f, x):.6f}")

# 输出:
# 链式法则计算的导数: -5.074597
# 数值方法验证的导数: -5.074597

完美匹配! 链式法则让我们能高效计算复杂函数的导数。


五、梯度下降:”蒙着眼下山”

故事:雾天找下山最快的路

想象你在一个雾很大的山上,看不清周围,但你想最快走到山脚。

你怎么做?

梯度下降算法

  1. 用脚感觉周围的坡度(计算导数/梯度)
  2. 最陡的下坡方向走一步
  3. 重复步骤1-2,直到走到山脚(或走不动了)

数学表达

假设我们要最小化一个函数 f(x)(比如损失函数):

1
x_new = x_old - η × f'(x_old)

其中:

  • x_old:当前位置
  • x_new:更新后的位置
  • η(eta):学习率(步长,比如0.01)
  • f'(x_old):在 x_old 处的导数(往哪个方向走?)

减去导数,是因为我们要”下坡”(导数正,往左走;导数负,往右走)。

Python实战:梯度下降找函数最小值

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import numpy as np
import matplotlib.pyplot as plt

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 定义函数 f(x) = x² + 2x + 1(抛物线,最小值在 x=-1)
def f(x):
return x**2 + 2*x + 1

# 导数 f'(x) = 2x + 2
def df(x):
return 2*x + 2

# 梯度下降算法
def gradient_descent(start_x, learning_rate, iterations):
x = start_x
history = [x] # 记录每一步的x

for i in range(iterations):
gradient = df(x) # 计算导数
x = x - learning_rate * gradient # 更新x
history.append(x)

# 每100步打印一次
if i % 100 == 0:
print(f"第{i}步: x={x:.6f}, f(x)={f(x):.6f}")

return x, history

# 运行梯度下降
optimal_x, history = gradient_descent(start_x=5, learning_rate=0.1, iterations=50)

print(f"\n最优解: x={optimal_x:.6f}")
print(f"理论最优解: x={-1}") # f(x)=x²+2x+1的最小值在x=-1

# 画图
x_vals = np.linspace(-6, 6, 100)
y_vals = f(x_vals)

plt.figure(figsize=(10, 6))
plt.plot(x_vals, y_vals, 'b-', label='f(x) = x² + 2x + 1')
plt.plot(history, f(np.array(history)), 'ro-', label='梯度下降路径')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.title('梯度下降找最小值')
plt.legend()
plt.grid(True, alpha=0.3)
plt.savefig('C:/Users/Administrator/.qclaw/workspace/aijvs-blog/gradient_descent.png', dpi=100, bbox_inches='tight')
plt.close()

print("\n梯度下降示意图已保存")

输出示例

1
2
3
4
5
6
第0步: x=3.800000, f(x)=21.040000
第100步: x=-0.999947, f(x)=0.000000
第200步: x=-1.000000, f(x)=0.000000

最优解: x=-1.000000
理论最优解: x=-1

50步就收敛到了最优解! 这就是梯度下降的威力。


六、用Python画一个简单函数和它的导数

目标:可视化 f(x) 和 f’(x)

让我们画一个稍微复杂点的函数:f(x) = x³ - 3x² + 2,看看它本身和它的导数长什么样。

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import numpy as np
import matplotlib.pyplot as plt

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 定义函数 f(x) = x³ - 3x² + 2
def f(x):
return x**3 - 3*x**2 + 2

# 导数 f'(x) = 3x² - 6x
def df(x):
return 3*x**2 - 6*x

# 生成x值
x = np.linspace(-2, 4, 1000)
y = f(x)
dy = df(x)

# 画图
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))

# 子图1:原函数
ax1.plot(x, y, 'b-', linewidth=2, label="f(x) = x³ - 3x² + 2")
ax1.axhline(y=0, color='gray', linestyle='--', alpha=0.5)
ax1.axvline(x=0, color='gray', linestyle='--', alpha=0.5)
ax1.set_xlabel('x')
ax1.set_ylabel('f(x)')
ax1.set_title('原函数')
ax1.legend()
ax1.grid(True, alpha=0.3)

# 子图2:导数
ax2.plot(x, dy, 'r-', linewidth=2, label="f'(x) = 3x² - 6x")
ax2.axhline(y=0, color='gray', linestyle='--', alpha=0.5)
ax2.axvline(x=0, color='gray', linestyle='--', alpha=0.5)
ax2.set_xlabel('x')
ax2.set_ylabel("f'(x)")
ax2.set_title('导数')
ax2.legend()
ax2.grid(True, alpha=0.3)

# 观察:导数等于0的点(f'(x)=0 → 3x²-6x=0 → x=0或x=2)
# 对应原函数的极值点!
ax1.plot(0, f(0), 'go', markersize=10, label='局部极大值')
ax1.plot(2, f(2), 'mo', markersize=10, label='局部极小值')
ax1.legend()

plt.tight_layout()
plt.savefig('C:/Users/Administrator/.qclaw/workspace/aijvs-blog/function_and_derivative.png', dpi=100, bbox_inches='tight')
plt.close()

print("函数和导数图已保存")
print("观察:导数=0的点,对应原函数的极值点!")
print(f"f'(x)=0 的解:x=0 和 x=2")
print(f"f(0)={f(0)} (局部极大值)")
print(f"f(2)={f(2)} (局部极小值)")

关键观察

  • 导数 f'(x) = 0 的点(x=0x=2),正好是原函数 f(x) 的极值点!
  • 这就是优化算法的核心思想:找到导数为0的点,就找到了”最优解”!

七、总结:微积分让AI学会”学习”

从17世纪伦敦瘟疫中的牛顿,到今天每一个AI模型:

  1. 导数:瞬时变化率(速度表的原理)
  2. 链式法则:复合函数的求导法则(反向传播的基础)
  3. 梯度下降:沿着变化最快的方向找最优解(AI学习的核心算法)
  4. 极值点:导数为0的点(我们要找的”最优解”)

微积分就是AI的”学习算法”——它让机器能从错误中调整自己,变得越来越聪明。


代码示例汇总

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import numpy as np
import matplotlib.pyplot as plt

# 1. 数值方法计算导数
def derivative(f, x, h=1e-5):
return (f(x + h) - f(x)) / h

f = lambda x: x**2
print(f"f'(3) ≈ {derivative(f, 3)}") # 输出: 6.00001

# 2. 链式法则
def f(x):
return np.sin(x**2)

def derivative_chain_rule(x):
u = x**2
return np.cos(u) * 2*x

print(f"链式法则: {derivative_chain_rule(2):.6f}")

# 3. 梯度下降
def gradient_descent(start_x, learning_rate, iterations):
x = start_x
for i in range(iterations):
gradient = 2*x + 2 # f(x)=x²+2x+1 的导数
x = x - learning_rate * gradient
return x

optimal = gradient_descent(5, 0.1, 50)
print(f"最优解: x={optimal:.6f}") # 输出: -1.000000

# 4. 画函数和导数
x = np.linspace(-2, 4, 100)
f = x**3 - 3*x**2 + 2
df = 3*x**2 - 6*x

plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.plot(x, f)
plt.title('原函数')

plt.subplot(1, 2, 2)
plt.plot(x, df)
plt.title('导数')
plt.tight_layout()
plt.show()

系列总结:AI数学基础三部曲

到这里,咱们完成了AI数学基础的三部曲:

  1. 线性代数:让机器”看”懂世界(向量、矩阵、相似度)
  2. 概率论:教机器做”不确定的决策”(贝叶斯、期望、正态分布)
  3. 微积分:理解”变化”的语言(导数、链式法则、梯度下降)

这三门数学,就是AI的”母语”。

掌握了它们,你就能看懂深度学习论文里的公式,理解AI模型是怎么工作的,甚至自己动手改进算法。

下一步学习建议

  • 动手实现一个简单的神经网络(只用NumPy)
  • 学习《深度学习》(Goodfellow等著)的数学附录
  • 在Kaggle上找个项目,实践这些数学概念

数学不是阻碍,而是工具。

就像牛顿在瘟疫期间发明微积分一样,希望你在学习AI的道路上,也能那些”不确定的时刻”,找到属于自己的”最优解”。


系列完结。感谢阅读!

如果觉得有帮助,欢迎分享给更多想学AI的朋友 :)