导数与偏导数:定义、计算、几何意义
一句话概述
导数描述的是函数在某一点的瞬时变化率——即输出相对于输入的敏感程度。当函数有多个输入变量时,偏导数分别衡量函数对每个单独变量的变化率。导数是梯度下降的灵魂:它告诉你"往哪个方向走、走多大步"才能最快地减小(或增大)函数值。在AI中,损失函数对每个参数的偏导数构成了梯度向量,指导着模型参数在每一次迭代中的更新方向。
💡 核心要点:①导数是差商的极限,描述瞬时变化率 ②导数在几何上对应切线斜率 ③偏导数将导数推广到多元函数 ④梯度是所有偏导数组成的向量,指向函数增长最快的方向
教学与演示
一、导数——变化率
是什么(定义,可选):函数 f(x) 在点 x₀ 处的导数定义为 f'(x₀) = lim_{h→0} [f(x₀+h) - f(x₀)] / h,如果该极限存在,称 f 在 x₀ 处可导。导数也可以记作 df/dx 或 d/dx f(x)。
大白话 想象你在开车,仪表盘上的速度表显示的就是导数——它告诉你"这一刻"速度是多少,而不是过去10秒的平均速度。导数就是函数在某个精确瞬间的变化快慢。
为什么(原理,可选):人类最早研究的是平均变化率(比如两地之间的平均速度),但很多实际问题需要瞬时信息——牛顿研究运动时需要知道瞬时速度,经济学需要知道边际成本和边际收益,物理学需要知道加速度和力。导数通过取极限,把"一段区间内的平均变化"压缩为"一个点上的瞬时变化",完成了从宏观到微观的跨越。 怎么做(实现,可选):
import numpy as np
def derivative_numerical(f, x, h=1e-6):
"""利用导数的定义进行数值求导(中心差分法)"""
# f'(x) ≈ [f(x+h) - f(x-h)] / (2h),二阶精度
return (f(x + h) - f(x - h)) / (2 * h)
def derivative_forward(f, x, h=1e-6):
"""前向差分法(一阶精度)"""
return (f(x + h) - f(x)) / h # 前向差商
# 定义测试函数
def f1(x): return x**3 - 2*x**2 + x # 多项式函数
def f2(x): return np.sin(x) # 正弦函数
def f3(x): return np.exp(x) # 指数函数
# 验证导数计算
print("=== 导数定义与数值计算演示 ===\n")
# 测试多项式:f(x)=x³-2x²+x, f'(x)=3x²-4x+1
x_test = 2.0
true_deriv = 3*x_test**2 - 4*x_test + 1 # 解析导数 = 5
num_center = derivative_numerical(f1, x_test)
num_forward = derivative_forward(f1, x_test)
print(f"函数 f(x) = x³ - 2x² + x,在 x = {x_test} 处:")
print(f" 解析导数 f'(x) = 3x²-4x+1 = {true_deriv}")
print(f" 中心差分法(二阶精度)≈ {num_center:.10f}")
print(f" 前向差分法(一阶精度)≈ {num_forward:.10f}")
print(f" 中心差分误差 = {abs(num_center - true_deriv):.2e}")
print(f" 前向差分误差 = {abs(num_forward - true_deriv):.2e}")
# 测试基本初等函数的导数
print("\n--- 基本初等函数导数验证 ---")
test_points = [0.0, 0.5, 1.0, 2.0]
for x0 in test_points:
print(f"\n x = {x0}:")
print(f" sin'(x) 数值≈{derivative_numerical(f2, x0):.6f}, 解析=cos({x0})={np.cos(x0):.6f}")
print(f" exp'(x) 数值≈{derivative_numerical(f3, x0):.6f}, 解析=exp({x0})={np.exp(x0):.6f}")
# 演示导数作为瞬时变化率
print("\n=== 导数作为瞬时变化率的直观理解 ===\n")
print("考虑一个物体运动的位置函数 s(t) = t²(米):")
print(" t=1秒时,位置 s(1) = 1米")
print(" t=3秒时,位置 s(3) = 9米")
print(" 平均速度 = (9-1)/(3-1) = 4 m/s")
print(f" 瞬时速度 v(2) = s'(2) = 4 m/s(中心差分验证:{derivative_numerical(lambda t: t**2, 2):.6f})")
print("导数告诉我们的是'这一刻'的精确速度,而非一段时间的平均。")
什么用(应用,可选):在AI中,损失函数对参数的一阶导数给出了最陡下降方向,是梯度下降法的核心输入。激活函数的导数决定了反向传播时梯度的流动——Sigmoid的导数最大0.25导致深层网络梯度消失,ReLU的导数为0或1则缓解了这一问题。优化器(Adam、RMSprop)的设计本质上是对一阶导数序列的统计处理。 哪些坑(缺点,可选):导数存在的前提是函数光滑——绝对值函数在尖点处不可导,ReLU在x=0处标准导数不存在(工程中用次梯度)。另外,数值导数受浮点精度影响——h太小会遭遇舍入误差,h太大又损失精度,需要平衡。高阶导数虽然理论上存在,但数值计算会迅速放大误差。
二、导数的几何意义——切线斜率
是什么(定义,可选):导数的几何意义是函数图像在该点处切线的斜率。当h→0时,连接(x₀, f(x₀))和(x₀+h, f(x₀+h))的割线趋近于过(x₀, f(x₀))的切线,割线斜率的极限就是切线斜率。
大白话 想象你站在一条弯曲的山路上,你脚下的"局部坡度"就是导数。你不需要看整座山有多陡,只需要看你脚底下这几厘米的倾斜程度。切线就是那条刚好"吻"在曲线上某一点而不穿透它的直线。
为什么(原理,可选):切线斜率的正负和大小给出了函数局部行为的全部信息。斜率为正表示函数在上升(递增),斜率为负表示在下降(递减),斜率为零表示达到水平——这是极值点的候选位置。绝对值越大,函数变化越剧烈。在优化中,梯度为零的点(临界点)可能是最小值、最大值或鞍点,识别它们的性质依赖二阶导数。 怎么做(实现,可选):
import numpy as np
def tangent_line(f, f_prime, x0):
"""计算函数在点 x0 处的切线方程 y = f'(x0)*(x-x0) + f(x0)"""
slope = f_prime(x0) # 切线斜率 = 导数
intercept = f(x0) - slope * x0 # 切线截距
return lambda x: slope * x + intercept, slope
# 定义函数及其解析导数
def f(x): return x**3 - 4*x**2 + 2*x + 1 # 三次函数
def f_prime(x): return 3*x**2 - 8*x + 2 # 其导数
print("=== 导数的几何意义:切线斜率演示 ===\n")
# 在多个点观察切线
points = [-1.0, 0.0, 1.0, 2.0, 3.0]
for x0 in points:
tan_line, slope = tangent_line(f, f_prime, x0)
print(f"x = {x0:4.1f}: f(x) = {f(x0):7.3f}, 导数(切线斜率)= {slope:7.3f}")
if slope > 0.01:
print(f" → 函数在此处上升(递增),坡度 = {slope:.3f}")
elif slope < -0.01:
print(f" → 函数在此处下降(递减),坡度 = {slope:.3f}")
else:
print(f" → 函数在此处水平(临界点),可能是极值点!")
# 寻找临界点(导数为零的点)
print("\n--- 寻找临界点 ---")
# f'(x) = 3x² - 8x + 2 = 0
# 解:x = (8 ± √(64-24))/6 = (8 ± √40)/6 = (8 ± 2√10)/6
discriminant = 64 - 24 # b² - 4ac = 64 - 24 = 40
sqrt_disc = np.sqrt(discriminant)
critical1 = (8 - sqrt_disc) / 6 # 约 0.279
critical2 = (8 + sqrt_disc) / 6 # 约 2.388
print(f"临界点1: x ≈ {critical1:.4f}, f(x) ≈ {f(critical1):.4f}")
print(f" f''(x) = 6x - 8 = {6*critical1 - 8:.4f} (负 → 局部最大值)")
print(f"临界点2: x ≈ {critical2:.4f}, f(x) ≈ {f(critical2):.4f}")
print(f" f''(x) = 6x - 8 = {6*critical2 - 8:.4f} (正 → 局部最小值)")
# 演示割线逼近切线的过程
print("\n--- 割线逼近切线(导数的几何直观)---")
x0 = 1.0
print(f"在 x₀ = {x0} 处观察割线如何逼近切线:")
h_values = [1.0, 0.5, 0.1, 0.01, 0.001]
for h in h_values:
secant_slope = (f(x0 + h) - f(x0)) / h # 割线斜率(前向差商)
true_slope = f_prime(x0) # 真实切线斜率
error = abs(secant_slope - true_slope)
print(f" h={h:.3f}: 割线斜率={secant_slope:.6f}, 误差={error:.6f}")
print(f" 真实切线斜率 f'({x0}) = {f_prime(x0)}")
print("结论:h 越小,割线越逼近切线,极限即为导数。")
什么用(应用,可选):几何理解让你能可视化地判断训练是否正常——如果损失函数在某个参数维度上的切线斜率始终为正,说明增大该参数会增加损失。切线斜率的大小决定了梯度更新的幅度。在损失函数曲面上,梯度为零的点可能是鞍点(在高维空间中很常见),二阶导数帮助区分最小值点和鞍点。 哪些坑(缺点,可选):切线只是一个"局部"直线近似——离切点稍有距离就可能严重偏离真实函数。在高度非线性的损失曲面中,用切线(一阶近似)指导的梯度下降可能在峡谷中来回震荡。此外,高维空间中切线的直观几何意义失效,只能借助梯度向量来理解。
三、偏导数——多变元函数的导数
是什么(定义,可选):对于多元函数 f(x₁, x₂, ..., xₙ),f 关于变量 xᵢ 的偏导数 ∂f/∂xᵢ 定义为在固定其他所有变量的前提下,f 对 xᵢ 的普通导数:∂f/∂xᵢ = lim_{h→0} [f(..., xᵢ+h, ...) - f(..., xᵢ, ...)] / h。
大白话 偏导数就像医生检查你的身体——不是一次性测全身,而是分别测血压、心率、体温。每次只改变一个指标,看它对整体健康的影响。同样,偏导数一次只改变一个自变量,看函数值对它的反应有多"敏感"。
为什么(原理,可选):现实世界(包括AI)中的函数几乎都是多元的。一个神经网络的损失函数可能依赖数百万个参数,我们需要知道每个参数的独立影响——增大这个参数会让损失上升还是下降?偏导数用"固定其他变量、逐一考察"的策略,将高维问题降维为多个一维求导问题。这是人类认知高维空间的基本策略。 怎么做(实现,可选):
import numpy as np
def partial_derivative(f, x, index, h=1e-6):
"""计算多元函数 f 在点 x 处对第 index 个变量的偏导数"""
x_plus = x.copy() # 创建副本
x_minus = x.copy()
x_plus[index] += h # 仅改变第 index 个变量
x_minus[index] -= h
# 中心差分法:∂f/∂xᵢ ≈ [f(xᵢ+h) - f(xᵢ-h)] / (2h)
return (f(x_plus) - f(x_minus)) / (2 * h)
def gradient(f, x, h=1e-6):
"""计算梯度向量(所有偏导数组成的向量)"""
n = len(x)
grad = np.zeros(n) # 初始化梯度向量
for i in range(n):
grad[i] = partial_derivative(f, x, i, h)
return grad
# 定义一个二元函数:f(x, y) = x² + 3xy + 2y²
def binary_func(point):
x, y = point[0], point[1]
return x**2 + 3*x*y + 2*y**2 # 简单的二次型
# 解析偏导数:∂f/∂x = 2x + 3y, ∂f/∂y = 3x + 4y
def analytical_gradient(point):
x, y = point[0], point[1]
return np.array([2*x + 3*y, 3*x + 4*y])
print("=== 偏导数与梯度计算演示 ===\n")
# 在多个点验证偏导数
test_points = [
np.array([1.0, 0.0]),
np.array([0.0, 1.0]),
np.array([2.0, -1.0]),
np.array([-1.0, 2.0]),
]
for point in test_points:
num_grad = gradient(binary_func, point)
ana_grad = analytical_gradient(point)
print(f"点 ({point[0]:.1f}, {point[1]:.1f}):")
print(f" 数值梯度 [∂f/∂x, ∂f/∂y] = [{num_grad[0]:.6f}, {num_grad[1]:.6f}]")
print(f" 解析梯度 [∂f/∂x, ∂f/∂y] = [{ana_grad[0]:.6f}, {ana_grad[1]:.6f}]")
# 计算范数表示梯度大小
grad_norm = np.sqrt(np.sum(ana_grad**2))
print(f" 梯度模长 ||∇f|| = {grad_norm:.4f}(表示函数在该点局部变化的剧烈程度)")
# 演示偏导数的几何意义
print("\n--- 偏导数的几何含义 ---")
print("∂f/∂x:固定 y,对 x 求导 → 沿 x 轴方向的切线斜率")
print("∂f/∂y:固定 x,对 y 求导 → 沿 y 轴方向的切线斜率")
# 演示梯度方向
print("\n--- 梯度方向与上升/下降 ---")
p = np.array([0.5, 0.5])
g = analytical_gradient(p)
g_norm = np.sqrt(np.sum(g**2)) # 梯度模长
if g_norm > 0:
g_dir = g / g_norm # 梯度方向单位向量
else:
g_dir = g
print(f"在点 ({p[0]:.1f}, {p[1]:.1f}):")
print(f" 梯度向量 ∇f = [{g[0]:.4f}, {g[1]:.4f}]")
print(f" 梯度方向单位向量 = [{g_dir[0]:.4f}, {g_dir[1]:.4f}]")
print(f" 沿此方向函数增长最快,沿反方向减少最快")
什么用(应用,可选):偏导数是反向传播的计算基础——神经网络中每个参数的更新量就是损失函数对该参数的偏导数乘以学习率。理解偏导数才能理解为什么训练时每个参数的更新量不同:它们各自对最终损失的"贡献"不同。在参数调优中,偏导数的相对大小揭示了哪些参数更重要(梯度大的参数对输出影响大)。 哪些坑(缺点,可选):偏导数互相之间是独立的——但它们只是各自"孤立"的影响。在实际系统中,多个参数之间存在交互效应(交叉偏导数描述这种效应)。只关注偏导数而忽略交叉项可能导致对系统行为的片面理解。另外,即使每个偏导数都存在,多元函数也可能不可微(需要更强的条件)。
四、梯度——偏导数的向量
是什么(定义,可选):梯度 ∇f 是所有偏导数组成的向量:∇f = (∂f/∂x₁, ∂f/∂x₂, ..., ∂f/∂xₙ)。梯度的方向是函数值增长最快的方向,梯度的大小(模长)表示在该方向上的最大变化率。
大白话 想象你站在一座山上,你朝四周看——往哪个方向走一步能上升得最快?梯度就是那个方向,而且它还能告诉你这一步能上升多少。梯度就像是你脚下的"最陡指示箭头",它永远指向最陡的上坡方向。
为什么(原理,可选):在n维空间中,有无限多个方向可以走,我们不可能每个方向都试一遍。梯度提供了最优解:沿梯度方向走,单位步长带来的函数值增长最大。这一性质由方向导数的柯西-施瓦茨不等式保证。反过来,沿负梯度方向走,函数值下降最快——这就是梯度下降法的核心原理。 怎么做(实现,可选):
import numpy as np
def directional_derivative(f, x, direction, h=1e-6):
"""计算沿给定方向的方向导数"""
# 将方向向量归一化
d = direction / np.sqrt(np.sum(direction**2)) # 单位方向向量
# 方向导数 = lim_{t→0} [f(x + t*d) - f(x)] / t
return (f(x + h * d) - f(x - h * d)) / (2 * h)
# 使用二元函数 f(x,y) = x² + 3xy + 2y²
def f(point):
x, y = point[0], point[1]
return x**2 + 3*x*y + 2*y**2
def grad_f(point):
x, y = point[0], point[1]
return np.array([2*x + 3*y, 3*x + 4*y]) # 梯度向量
print("=== 梯度:最陡上升方向 ===\n")
point = np.array([1.0, 1.0])
g = grad_f(point)
g_norm = np.sqrt(np.sum(g**2))
print(f"在点 ({point[0]}, {point[1]}):")
print(f" 梯度 ∇f = [{g[0]}, {g[1]}]")
print(f" 梯度模长 = {g_norm:.4f}")
# 测试多个不同方向的方向导数
print("\n--- 方向导数比较(哪个方向增长最快?)---")
import math
directions = {
"梯度方向": g,
"负梯度方向": -g,
"x轴正方向": np.array([1.0, 0.0]),
"y轴正方向": np.array([0.0, 1.0]),
"45°方向": np.array([1.0, 1.0]),
"任意方向": np.array([2.0, -1.0]),
}
for name, direction in directions.items():
dir_deriv = directional_derivative(f, point, direction)
print(f" {name}: 方向导数 = {dir_deriv:.6f}")
print(f"\n结论:在梯度方向上的方向导数 = {directional_derivative(f, point, g):.6f}(最大值)")
print(f" 梯度模长 = {g_norm:.4f} = 最大方向导数值 ✓")
print(f" 沿负梯度方向走,函数下降最快(方向导数最负)。")
# 曲面上梯度方向的几何验证
print("\n--- 梯度方向的几何理解 ---")
print("f(x,y) = x² + 3xy + 2y² 是一个椭圆抛物面(二次型)")
print("在任意点处,梯度指向使 f 增加最快的方向")
print("这就解释了为什么梯度下降永远沿负梯度方向更新参数。")
什么用(应用,可选):梯度是几乎所有现代优化算法的输入。随机梯度下降(SGD)用批次数据的平均梯度更新参数;动量法在梯度方向的基础上累积历史方向;Adam自适应地调整每个参数的学习率(基于梯度的一阶和二阶动量)。理解梯度的"最优方向"性质,就理解了为什么所有优化算法都围绕梯度来设计。 哪些坑(缺点,可选):梯度的"最优"只在一阶近似的意义上成立——在离当前点稍远处,梯度方向可能不再是好方向。这就是为什么固定学习率的梯度下降可能在狭谷中震荡。另外,梯度为零的点不一定是极值点——高维空间中鞍点比局部极小值更常见,但梯度下降无法区分它们。
五、AI中的应用——梯度下降的方向
是什么(定义,可选):在AI训练中,梯度下降法利用损失函数 L(θ) 关于模型参数 θ 的梯度 ∇_θ L 来更新参数:θ_new = θ_old - η · ∇_θ L,其中 η 是学习率。这个过程反复进行,直到损失函数达到满意的水平。
大白话 训练神经网络就像教一个小孩投篮——每一次投完后,你会告诉他"手腕太靠左了"或"膝盖弯太少了",让他下次调整。梯度就扮演着这个"纠错教练"的角色,精确地告诉你每个参数应该增多还是减少、调整多少。
为什么(原理,可选):现代神经网络可能有数亿个参数——如果没有梯度的方向性指引,在参数空间中随机搜索最优解就像大海捞针。梯度提供了局部最优的搜索方向,使得我们能将优化问题从"盲目搜索"转化为"有方向地行走"。配合链式法则(反向传播),我们可以高效地计算出所有参数层的梯度。 怎么做(实现,可选):
import numpy as np
# 模拟一个简单的线性回归:预测 y = w*x + b
# 损失函数:MSE = (1/n) Σ(y_true - (w*x + b))²
np.random.seed(42)
def generate_data(n=100):
"""生成带噪声的线性数据"""
x = np.linspace(-3, 3, n)
true_w, true_b = 2.0, -1.0 # 真实参数
y = true_w * x + true_b + np.random.normal(0, 0.5, n) # 加高斯噪声
return x, y, true_w, true_b
def mse_loss(params, x, y):
"""均方误差损失函数"""
w, b = params
y_pred = w * x + b # 线性模型预测
return np.mean((y - y_pred)**2) # MSE
def compute_gradient(params, x, y):
"""手动计算 MSE 对 w 和 b 的梯度"""
w, b = params
n = len(x)
y_pred = w * x + b
# ∂L/∂w = -(2/n) Σ x·(y - y_pred)
dw = -(2/n) * np.sum(x * (y - y_pred))
# ∂L/∂b = -(2/n) Σ (y - y_pred)
db = -(2/n) * np.sum(y - y_pred)
return np.array([dw, db])
# 数据生成
x, y, true_w, true_b = generate_data()
print("=== 梯度下降训练线性回归 ===\n")
print(f"真实参数: w = {true_w}, b = {true_b}")
print(f"样本数: {len(x)}")
# 梯度下降训练
params = np.array([0.0, 0.0]) # 初始参数 [w, b]
lr = 0.01 # 学习率
history = []
print(f"\n初始参数: w = {params[0]:.4f}, b = {params[1]:.4f}")
print(f"初始损失: {mse_loss(params, x, y):.6f}")
for epoch in range(500):
grad = compute_gradient(params, x, y) # 计算梯度
params = params - lr * grad # 沿负梯度方向更新
if epoch % 50 == 0:
loss = mse_loss(params, x, y)
history.append((epoch, params.copy(), loss))
print(f"Epoch {epoch:3d}: w={params[0]:.4f}, b={params[1]:.4f}, loss={loss:.6f}")
print(f"\n最终参数: w = {params[0]:.6f}, b = {params[1]:.6f}")
print(f"最终损失: {mse_loss(params, x, y):.6f}")
print(f"与真实值的差距: Δw = {abs(params[0] - true_w):.6f}, Δb = {abs(params[1] - true_b):.6f}")
什么用(应用,可选):梯度是深度学习的"燃油"——没有梯度就没有参数更新。理解梯度还能帮你诊断训练问题:梯度消失意味着参数几乎不更新(常见于深层Sigmoid网络),梯度爆炸意味着参数更新幅度过大导致不收敛。梯度裁剪、Batch Normalization等技术正是为了解决这些梯度问题而设计的。 哪些坑(缺点,可选):梯度的局部性是其根本局限——在非凸损失面上,梯度可能将你引向局部最小值或鞍点而非全局最优。在极小批量(甚至batch size=1)时,梯度的噪声非常大,可能将参数推向随机方向。此外,梯度的数值计算在高维空间中计算量巨大,这也是为什么深度学习依赖自动微分框架(如TensorFlow、PyTorch)。
概念关系图谱
| 概念 | 核心含义 | 与AI的关系 | 关联概念 |
|---|---|---|---|
| 导数 | 单变量函数的瞬时变化率 | 一维参数更新的方向与步长 | 差商、切线、极限 |
| 偏导数 | 多变量函数对单个变量的变化率 | 神经网络中每个参数的独立影响 | 梯度、全微分 |
| 梯度 | 所有偏导数组成的向量 | 参数更新的最陡下降方向 | 方向导数、等值面 |
| 切线斜率 | 导数的几何意义 | 损失函数的局部线性近似 | 割线、极限 |
| 高阶导数 | 变化率的变化率 | 判断临界点性质、曲率信息 | 凹凸性、牛顿法 |
| 方向导数 | 沿任意方向的变化率 | 理解梯度方向的最优性 | 梯度、柯西不等式 |
| 临界点 | 导数为零的点 | 梯度下降的静止点 | 极值、鞍点 |
| 可微性 | 函数局部可线性近似的性质 | 反向传播的前提条件 | 连续性、偏导数存在性 |
| 链式法则 | 复合函数求导规则 | 反向传播的计算引擎 | 复合函数、计算图 |
| 自动微分 | 程序化计算精确导数 | PyTorch/TensorFlow的核心机制 | 计算图、梯度 |
重点答疑
Q1: 导数、偏导数、梯度三者之间的关系是什么?
导数是单变量函数的"变化率",记作 f'(x) 或 df/dx。偏导数是多变量函数对其中一个变量的导数(其他变量视为常数),记作 ∂f/∂xᵢ。梯度是所有偏导数组成的向量 ∇f = (∂f/∂x₁, ..., ∂f/∂xₙ)。如果把函数比作一座山,偏导数是山在南北方向和东西方向各自的坡度,而梯度是综合所有方向的"最陡方向向量"。
Q2: 为什么说"导数是切线斜率"?
从几何上看,割线斜率的极限就是切线斜率。考虑两点 (x, f(x)) 和 (x+h, f(x+h)),它们的连线(割线)斜率为 [f(x+h)-f(x)]/h。当 h→0 时,第二个点无限逼近第一个点,割线就"化"成了切线,其斜率正是导数。这就是微分几何中"切线是割线的极限位置"的直观含义。
Q3: 为什么导数 f'(x)=0 不一定是极值点?
f'(x)=0 的点称为临界点,它可能是局部最小值(如 f(x)=x² 在 x=0 处)、局部最大值(如 f(x)=-x² 在 x=0 处)或鞍点(如 f(x)=x³ 在 x=0 处)。x³ 的导数 3x² 在 x=0 处为 0,但函数在 0 的两侧都上升——这不是极值点。区分这三种情况需要看二阶导数(或更高阶)。
Q4: 偏导数存在是否意味着函数可微?
不是!偏导数只关心坐标轴方向的变化,而可微性要求函数在所有方向上都可以被线性近似。一个经典反例是 f(x,y) = xy/(x²+y²)(补定义 f(0,0)=0),它在 (0,0) 处两个偏导数都存在(均为0),但函数在该点不连续,更谈不上可微。可微性是比偏导数存在更强的条件。
Q5: 梯度方向为什么是函数增长最快的方向?
在给定点附近,函数沿方向向量 d 的方向导数为 ∇f · d(梯度与方向的点积)。根据柯西-施瓦茨不定式,|∇f · d| ≤ ||∇f|| · ||d||,当 d 与 ∇f 同向时等号成立,方向导数取得最大正值。因此沿梯度方向走,单位步长带来的增长最大——这就是梯度方向"最优"的数学证明。
章节单词汇总
| 英文 | 音标 | 术语/释义 |
|---|---|---|
| derivative | /dɪˈrɪvətɪv/ | 导数 |
| partial derivative | /ˈpɑːrʃəl dɪˈrɪvətɪv/ | 偏导数 |
| gradient | /ˈɡreɪdiənt/ | 梯度 |
| tangent line | /ˈtændʒənt laɪn/ | 切线 |
| secant line | /ˈsiːkænt laɪn/ | 割线 |
| slope | /sloʊp/ | 斜率 |
| directional derivative | /dɪˈrekʃənl dɪˈrɪvətɪv/ | 方向导数 |
| critical point | /ˈkrɪtɪkl pɔɪnt/ | 临界点 |
| stationary point | /ˈsteɪʃəneri pɔɪnt/ | 驻点 |
| saddle point | /ˈsædl pɔɪnt/ | 鞍点 |
| convexity | /kənˈveksɪti/ | 凸性 |
| concavity | /kɒnˈkeɪvɪti/ | 凹性 |
| inflection point | /ɪnˈflekʃən pɔɪnt/ | 拐点 |
| second derivative | /ˈsekənd dɪˈrɪvətɪv/ | 二阶导数 |
| higher-order derivative | /haɪər ˈɔːrdər dɪˈrɪvətɪv/ | 高阶导数 |
| differentiability | /ˌdɪfərɛnʃiəˈbɪlɪti/ | 可微性 |
| nabla operator | /ˈnæblə ˈɒpəreɪtər/ | 微分算子 ∇ |
| Jacobian matrix | /dʒəˈkoʊbiən ˈmeɪtrɪks/ | 雅可比矩阵 |
| quotient rule | /ˈkwoʊʃənt ruːl/ | 商的求导法则 |
| power rule | /ˈpaʊər ruːl/ | 幂函数求导法则 |
面试练习
Q1 [单选] 函数 f(x) = x³ - 3x 的临界点有几个?
- A. 0个
- B. 1个
- C. 2个
- D. 3个
解答:f'(x) = 3x² - 3 = 3(x²-1) = 3(x-1)(x+1),令 f'(x)=0 得 x=1 或 x=-1,共两个临界点。
Q2 [单选] 函数 f(x) = x³ - 3x 在 x=1 处是?
- A. 局部最大值
- B. 局部最小值
- C. 鞍点/拐点
- D. 不是临界点
解答:f''(x) = 6x,f''(1) = 6 > 0,故 x=1 处为局部最小值。f(1) = 1-3 = -2。
Q3 [多选] 梯度为零的点可能是?
- A. 局部最小值
- B. 局部最大值
- C. 鞍点
- D. 一定是全局最小值
解答:梯度为零的点统称临界点/驻点,可能是最小值、最大值或鞍点(如 f(x)=x³ 在 x=0)。D错误——全局最小值是局部最小值中"最好"的那个,但梯度为零不保证全局性。
Q4 [单选] 设 f(x,y) = x²y + xy²,则 ∂f/∂x 在点 (1,2) 处的值是?
- A. 6
- B. 6
- C. 8
- D. 10
解答:∂f/∂x = 2xy + y²,代入 (x=1, y=2):2·1·2 + 2² = 4 + 4 = 8。
Q5 [单选] 梯度的模长 ||∇f|| 代表了什么?
- A. 函数的平均值
- B. 函数在梯度方向上的二阶变化率
- C. 函数在该点处的最大方向导数(最陡上升率)
- D. 函数在该点处沿 x 轴的变化率
解答:梯度模长等于沿梯度方向的方向导数,这是所有可能方向中方向导数最大的那个值,即函数在该点处的"最陡上升率"。
Q6 [多选] 以下哪些是导数的正确表示?
- A. f'(x)
- B. df/dx
- C. d/dx f(x)
- D. ∫ f(x) dx
解答:A是拉格朗日记法,B是莱布尼茨记法,C是算子记法。D表示 f 的不定积分(反导数),不是导数。
Q7 [单选] sigmoid 函数的导数 σ'(x) 等于?
- A. σ(x)
- B. σ(x)²
- C. σ(x)(1 - σ(x))
- D. 1 - σ(x)
解答:σ(x) = 1/(1+e⁻ˣ),利用商法则或链式法则求导得 σ'(x) = σ(x)(1-σ(x))。其最大值为 0.25(在 x=0 处),这是深层网络梯度消失的原因之一。
Q8 [多选] 关于偏导数,以下说法正确的是?
- A. 偏导数将其他变量视为常数
- B. 偏导数的存在不能保证函数的可微性
- C. 偏导数用 d 表示而非 ∂
- D. 偏导数的几何意义是坐标轴方向的切线斜率
解答:C错误——偏导数使用 ∂ 符号(圆润的 d)以区别于普通导数 d。A描述计算方式,B是重要警示,D是正确的几何解读。
Q9 [单选] 对于函数 f(x) = |x|,在 x=0 处:
- A. 可导,f'(0) = 0
- B. 可导,f'(0) = 1
- C. 不可导
- D. 导数为无穷大
解答:f(x)=|x| 在 x=0 处左导数 = -1,右导数 = +1,两者不等,故不可导。但该函数在 x=0 处是连续的。这个性质与 ReLU 类似。
Q10 [多选] 梯度下降中,参数的更新方向是:
- A. 负梯度方向
- B. 使损失函数减少最快的方向
- C. 正梯度方向
- D. 与梯度方向相反的局部最优方向
解答:梯度下降沿负梯度方向更新参数,这是局部一阶最优的下降方向。正梯度方向是增长最快的方向,C错误。