机器学习与深度学习
把工程中"用数据拟合规律"的经验翻译成机器学习的语言:线性回归就是加了自动微分的最小二乘法,神经网络就是多层可学习的函数复合。
1. 线性回归:从最小二乘到梯度下降
你已经知道的
实验数据处理中你用最小二乘法拟合过直线。线性回归就是它的多维推广——只不过把手工求解换成了自动微分。
$\hat{y} = \mathbf{w}^T\mathbf{x} + b \qquad \mathcal{L} = \frac{1}{N}\sum (\hat{y}_i - y_i)^2$
闭式解 $\mathbf{w}^* = (X^TX)^{-1}X^T\mathbf{y}$,等价于你熟悉的法方程。当特征维度超过几千时,改用梯度下降。
import numpy as np
from sklearn.linear_model import LinearRegression
# 任务:从 (角度, 速度, 负载) → 预测关节力矩
angles = np.random.uniform(-np.pi/2, np.pi/2, 200)
vels = np.random.uniform(-1, 1, 200)
loads = np.random.uniform(0, 5, 200)
torque = 15*angles + 2.5*vels + 8*loads*np.cos(angles) + 0.5*np.random.randn(200)
X = np.column_stack([angles, vels, loads, loads*np.cos(angles)])
model = LinearRegression().fit(X, torque)
print(f"R² = {model.score(X, torque):.4f}")
🔧 工程连接:关节摩擦补偿、传感器标定、力控前馈——都可以用线性回归从实验数据学一个比理论模型更准的映射。
2. 逻辑回归与分类
$P(y=1|\mathbf{x}) = \sigma(\mathbf{w}^T\mathbf{x}+b) = \frac{1}{1+e^{-(\mathbf{w}^T\mathbf{x}+b)}}$
把线性输出映射到 [0,1] 的概率区间。决策边界 $\mathbf{w}^T\mathbf{x}+b=0$ 是一条超平面。
from sklearn.linear_model import LogisticRegression
# 6维力传感器数据 → 接触检测 (接触=1, 悬空=0)
X_force = np.random.randn(500, 6)
y = (np.linalg.norm(X_force, axis=1) > 2).astype(int)
model = LogisticRegression().fit(X_force, y)
print(f"准确率: {model.score(X_force, y):.2%}")
3. 神经网络:从线性到非线性
为什么需要
线性回归只能学平面,逻辑回归只能画直线。真实机器人系统是非线性的——关节摩擦(Stribeck)、末端力的三角函数依赖、图像特征——都需要非线性表达能力。
import torch; import torch.nn as nn
class DynamicsNet(nn.Module):
"""从关节状态预测力矩的MLP"""
def __init__(self):
super().__init__()
self.net = nn.Sequential(
nn.Linear(14, 128), nn.ReLU(), # 7角度+7速度→128
nn.Linear(128, 256), nn.ReLU(),
nn.Linear(256, 128), nn.ReLU(),
nn.Linear(128, 7) # → 预测7个关节力矩
)
def forward(self, x): return self.net(x)
| 激活函数 | 公式 | 特点 |
|---|---|---|
| ReLU | $\max(0,x)$ | 最常用,计算简单,梯度不消失 |
| Sigmoid | $\frac{1}{1+e^{-x}}$ | 输出[0,1],适合概率输出层 |
| Tanh | $\frac{e^x-e^{-x}}{e^x+e^{-x}}$ | 输出[-1,1],适合归一化输入 |
4. CNN:让网络"看见"图像
全连接处理 224×224×3=150528 维输入,参数量爆炸。CNN 用共享参数的核(kernel)在图像上滑动检测特征——就像用一个特征模板扫描整张图。
class SimpleCNN(nn.Module):
def __init__(self, n_classes=10):
super().__init__()
self.features = nn.Sequential(
nn.Conv2d(3,32,3,padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(32,64,3,padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(64,128,3,padding=1), nn.ReLU(), nn.MaxPool2d(2),
)
self.head = nn.Sequential(nn.AdaptiveAvgPool2d((1,1)), nn.Flatten(), nn.Linear(128,n_classes))
核心操作:卷积(特征提取)、池化(降采样、平移不变)、步长(控制滑动密度)。
5. 训练实践:过拟合与调参
过拟合诊断
| 信号 | 含义 | 对策 |
|---|---|---|
| 训练loss↓ 验证loss↑ | 过拟合 | Dropout、Weight Decay、数据增强 |
| 训练loss和验证loss都高 | 欠拟合 | 增大模型、减小正则化 |
# 训练循环模板
model.train()
for epoch in range(epochs):
for x, y in train_loader:
opt.zero_grad(); loss = criterion(model(x), y)
loss.backward(); opt.step()
# 每个epoch验证一次
with torch.no_grad():
val_loss = sum(criterion(model(x),y) for x,y in val_loader)
print(f"Epoch {epoch}: train={loss:.4f} val={val_loss:.4f}")
验收实验
- 用线性回归从关节数据预测力矩,RMSE < 5% 满量程
- 用逻辑回归做6维力传感器接触检测,F1 > 0.95
- 训练 CNN 在 MNIST 上达到 > 98% 准确率
- 用 MLP 学习动力学模型,对比 RBDL 的刚体动力学计算结果
- 写一份调参报告:对比不同优化器、学习率、正则化对训练的影响