简短答案:
- 在许多大数据设置中(例如数百万个数据点),计算成本或梯度需要很长时间,因为我们需要对所有数据点求和。
- 我们不需要精确的梯度来降低给定迭代的成本。梯度的一些近似值可以正常工作。
- 随机梯度体面(SGD)仅使用一个数据点近似梯度。因此,与对所有数据求和相比,评估梯度可节省大量时间。
- 通过“合理的”迭代次数(该数目可能是几千,并且远小于数据点的数目(可能是数百万)),随机梯度样例可能会得到一个合理的好的解决方案。
长答案:
我的记法遵循NG Andrew的机器学习Coursera课程。如果您不熟悉它,可以在这里查看讲座系列。
假设损失平方回归,成本函数为
Ĵ(θ )= 12 米∑我= 1米(小时θ(x(我))- ÿ(我))2
梯度是
dĴ(θ )dθ= 1米∑我= 1米(小时θ(x(我))- ÿ(我))x(我)
对于梯度像样(GD),我们将参数更新为
θñ Ë W ^= θÒ 升d- α 1米∑我= 1米(小时θ(x(我))- ÿ(我))x(我)
1 /米X(我),ÿ(我)节省了时间。
θñ Ë W ^= θÒ 升d- α ·& (ħθ(x(我))- ÿ(我))x(我)
这就是我们节省时间的原因:
假设我们有10亿个数据点。
诀窍在于,在SGD中,您不需要进行10亿次迭代/更新,而无需进行多次迭代/更新,比如说进行100万次迭代,就可以使用“足够好”的模型。
我正在编写代码来演示这个想法。我们首先通过正规方程求解线性系统,然后使用SGD对其进行求解。然后,我们根据参数值和最终目标函数值比较结果。为了稍后可视化,我们将有2个参数需要调整。
set.seed(0);n_data=1e3;n_feature=2;
A=matrix(runif(n_data*n_feature),ncol=n_feature)
b=runif(n_data)
res1=solve(t(A) %*% A, t(A) %*% b)
sq_loss<-function(A,b,x){
e=A %*% x -b
v=crossprod(e)
return(v[1])
}
sq_loss_gr_approx<-function(A,b,x){
# note, in GD, we need to sum over all data
# here i is just one random index sample
i=sample(1:n_data, 1)
gr=2*(crossprod(A[i,],x)-b[i])*A[i,]
return(gr)
}
x=runif(n_feature)
alpha=0.01
N_iter=300
loss=rep(0,N_iter)
for (i in 1:N_iter){
x=x-alpha*sq_loss_gr_approx(A,b,x)
loss[i]=sq_loss(A,b,x)
}
结果:
as.vector(res1)
[1] 0.4368427 0.3991028
x
[1] 0.3580121 0.4782659
124.1343123.0355
这是迭代中的成本函数值,我们可以看到它可以有效地减少损失,这说明了这一想法:我们可以使用数据子集来近似梯度并获得“足够好”的结果。
1000sq_loss_gr_approx
3001000