小批量随机梯度下降(SGD)
通过SGD训练的步骤
W \mathbf{W} W | 模型参数,包括了偏移量 |
---|---|
b b b | 超参,批量的大小 |
η t \eta_t ηt | 超参,在时间 t t t的学习率 |
- 在时刻1,随机初始化 W 1 \mathbf{W}_1 W1
- 在每一步 t = 1 , 2 , . . . t=1, 2, ... t=1,2,...重复以下步骤直至收敛:
- 随机从 n n n个样本里采样 I t ⊂ { 1 , … , n } I_t \subset\{1, \ldots, n\} It⊂{ 1,…,n}, I t I_t It就是采样的 n n n个样本, ∣ I t ∣ = b \left|I_t\right|=b ∣It∣=b
- 更新 w t + 1 = w t − η t ∇ w t ℓ ( X I t , y I t , w t ) \mathbf{w}_{t+1}=\mathbf{w}_t-\eta_t \nabla_{\mathbf{w}_t} \ell\left(\mathbf{X}_{I_t}, \mathbf{y}_{I_t}, \mathbf{w}_t\right) wt+1=wt−ηt∇wtℓ(XIt,yIt,wt)
优点:能够求解除了决策树以外几乎所有的模型
缺点:对于超参数 b b b和 η t \eta_t ηt比较敏感
代码实现
以下示例在线性回归模型中使用SGD。
超参包括batch_size,learning rate,num_epochs。
import random
import torch
# `features` shape is (n, p), `labels` shape is (p, 1)
def data_iter(batch_size, features, labels):
num_examples = len(features)
indices = list(range(num_examples))
random.shuffle(indices) # 打乱标号的顺序,目的是随机采样
for i in range(0, num_examples, batch_size):
batch_indices = torch.tensor(
indices[i:min(i+batch_size, num_examples)]
)
yield features[batch_indices], labels[batch_indices]
w = torch.normal(0, 0.01, size=(p, 1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)
for epoch in range(num_epochs):
for X, y in data_iter(batch_size, features, labels):
y_hat = X @ w + b
loss = ((y_hat - y)**2 / 2).mean() # MSE
loss.backward() # 参数求导
# 更新参数
for param in [w, b]:
param -= learning_rate * param.grad
param.grad.zero_() # 导数清零
总结
- 线性模型就是把输入通过线性加权和得到预测
- 在线性模型中,我们使用平均均方误差(MSE)来作为损失函数
- 在Softmax回归中,我们使用交叉熵(Cross Entropy)作为损失函数,一般用来做多分类问题
- Softmax操作子可以将预测数值变成概率
- 小批量随机梯度下降(Mini-batch SGD)对几乎所有的神经网络都可以求解