当数据量达到百万、千万甚至亿级规模时,传统的机器学习算法面临巨大挑战。批量梯度下降需要在每次迭代中遍历所有数据,计算量和内存需求都可能超出单机的承受能力。但恰恰是这些海量数据中蕴含着巨大的价值——更多的数据意味着更准确的模型。
大规模机器学习(Large Scale Machine Learning)研究如何在海量数据上高效地训练模型。
“数据越多,模型越好”——这在很多情况下是成立的。研究表明,对于复杂任务,简单算法配上海量数据常常能超过复杂算法配上少量数据。

但大数据带来大挑战:
在开始大规模学习前,我们应该问:真的需要这么多数据吗?
诊断方法:画学习曲线
如果学习曲线显示训练误差和验证误差都还在下降,说明更多数据可能有帮助。如果曲线已经平稳(高偏差),更多数据不会带来显著提升,应该改进模型而不是增加数据。
import numpy as np
import matplotlib.pyplot as plt
def plotLearningCurve(X, y, X_val, y_val, model):
"""
画学习曲线
"""
m = X.shape[0]
train_errors = []
val_errors = []
# 逐步增加训练样本数量
m_samples = np.linspace(100, m, 10).astype(int)
for m_i in m_samples:
# 用前m_i个样本训练
model.fit(X[:m_i], y[:m_i])
# 计算误差
train_errors.append(computeError(X[:m_i], y[:m_i], model))
val_errors.append(computeError(X_val, y_val, model))
plt.plot(m_samples, train_errors, label='训练误差')
plt.plot(m_samples, val_errors, label='验证误差')
plt.xlabel('训练样本数量')
plt.ylabel('误差')
plt.legend()
plt.title('学习曲线')
plt.show()不要盲目追求大数据。首先确认更多数据确实能带来提升,然后再投入资源处理大规模数据。有时候,清洗现有数据或改进特征工程比获取更多数据更有效。
批量梯度下降(Batch Gradient Descent)在每次迭代中使用所有 个样本:
当 很大(比如1亿)时,每次迭代都极其耗时。
随机梯度下降(Stochastic Gradient Descent, SGD) 每次只用一个样本更新:
def stochasticGradientDescent(X, y, theta, alpha, num_epochs):
"""
随机梯度下降
"""
m = len(y)
cost_history = []
for epoch in range(num_epochs):
# 随机打乱数据
indices = np.random.permutation(m)
X_shuffled = X[indices]
y_shuffled = y[indices]
# 对每个样本更新一次
for i in range(m):
SGD的特点:
优点:
缺点:
学习率调整:
为了让SGD更好地收敛,可以使用递减的学习率:
开始时学习率大,快速接近最优;后期学习率小,减少震荡。
def sgdWithDecayingLearningRate(X, y, theta, alpha0, num_epochs):
"""
带学习率衰减的SGD
"""
m = len(y)
for epoch in range(num_epochs):
indices = np.random.permutation(m)
for i in range(m):
# 学习率衰减
alpha = alpha0 / (1 + epoch * m + i)
Mini-Batch梯度下降是批量GD和随机GD的折衷:每次使用一小批(比如10-1000个)样本更新。
def miniBatchGradientDescent(X, y, theta, alpha, batch_size, num_epochs):
"""
Mini-Batch梯度下降
"""
m = len(y)
for epoch in range(num_epochs):
# 打乱数据
indices = np.random.permutation(m)
X_shuffled = X[indices]
y_shuffled = y[indices]
# 分批处理
for i in range(0, m, batch_size):
Mini-Batch的优势:
Batch size的选择:
实践中,batch size常取2的幂次(32, 64, 128, 256),因为硬件对这些大小优化得更好。
对于大数据集,我们不能每次迭代都计算整个训练集的代价(太慢了)。如何监控收敛?
方法:每处理N个样本,计算这N个样本的平均代价
比如,每1000个样本计算一次平均代价,画出趋势图。如果平均代价在下降,说明算法在收敛。
def sgdWithConvergenceMonitoring(X, y, theta, alpha, num_epochs, plot_interval=1000):
"""
带收敛监控的SGD
"""
m = len(y)
costs = []
iterations = []
temp_cost = 0
iteration = 0
for epoch in range(num_epochs):
indices = np.random.permutation(m)
收敛曲线的形状:
有些应用场景中,数据是持续不断到来的流。比如:
在线学习(Online Learning)能够从这些数据流中持续学习,不断更新模型。
class OnlineLearner:
def __init__(self, num_features, alpha=0.01):
self.theta = np.zeros(num_features)
self.alpha = alpha
self.num_updates = 0
def update(self, x, y):
"""
用单个样本更新模型
"""
# 预测
h = self.predict(x)
# 计算梯度并更新
gradient
在线学习的优势:
应用场景:
当单机无法处理数据时,我们需要分布式计算。Map-Reduce是一个强大的并行计算框架。
核心思想:
机器学习算法中的很多计算可以分解为:
批量梯度下降的Map-Reduce实现:
梯度计算可以分解:
假设有4台机器,数据分成4份:
Map阶段(并行):
Reduce阶段(合并):
然后更新参数:
# 伪代码:Map-Reduce梯度下降
def map_function(data_chunk, theta):
"""
在一台机器上执行,处理数据的一部分
"""
gradient_sum = 0
for (x, y) in data_chunk:
gradient_sum += (predict(x, theta) - y) * x
return gradient_sum
def reduce_function(gradient_sums, m, alpha, theta):
"""
合并所有机器的结果
"""
total_gradient = sum(gradient_sums) / m
适合Map-Reduce的算法:
很多机器学习算法可以并行化:
多核CPU:
即使在单机上,现代CPU有多个核心。可以用类似的思想利用多核并行:
现代深度学习框架(TensorFlow, PyTorch)自动利用多核和GPU并行。
大规模机器学习让我们能够充分利用海量数据的价值。通过随机梯度下降、Mini-Batch、在线学习和分布式计算,我们可以训练在几年前还不可想象的大模型。这些技术是现代AI系统的基础,从搜索引擎到推荐系统,从语音识别到图像理解。
在接下来的最后一节课中,我们将通过一个完整的应用案例,把所学的各种技术串起来,看看如何构建一个端到端的机器学习系统。
问题诊断和解决方案:根据以下情况,诊断问题并提出解决方案。
你训练了一个模型,得到:
这是什么问题?应该如何解决?
答案:
诊断:高方差(过拟合)
判断依据:
解决方案(按优先级):
获取更多训练数据 ✓ 最有效
减少特征数量 ✓
增加正则化参数λ ✓
使用更简单的模型 ✓
不应该做的:
Python诊断代码:
def diagnose_model(train_error, val_error):
gap = val_error - train_error
if train_error > 0.15: # 高偏差
if gap < 0.05:
return "欠拟合(高偏差)"
else:
学习曲线分析:分析以下学习曲线,判断问题类型。
随着训练样本数量增加:
这是什么问题?解决方案是什么?
答案:
诊断:轻度高方差(过拟合),可能混合轻度高偏差
学习曲线特征分析:
训练误差上升(10% → 18%)
验证误差下降(60% → 20%)
曲线趋于平缓
判断:
解决方案:
如果目标误差可接受(如15%):
如果目标误差更低(如5%):
典型学习曲线模式:
高方差(过拟合):
训练误差:很低且平
验证误差:高且有大gap
解决:更多数据有帮助
高偏差(欠拟合):
训练误差:高且平
验证误差:高且gap小
解决:更多数据帮助不大,需要更复杂模型
理想状态:
两条曲线都低且接近
差距很小