我在随机梯度下降中更新theta时有一个问题。我有两种更新theta的方法:
1) 使用之前的theta,获取所有样本的假设,然后通过每个样本更新theta。比如:
hypothese = np.dot(X, theta)for i in range(0, m): theta = theta + alpha * (y[i] - hypothese[i]) * X[i]
2) 另一种方法:在扫描样本时,使用最新的theta更新hypothese[i]。比如:
for i in range(0, m): h = np.dot(X[i], theta) theta = theta + alpha * (y[i] - h) * X[i]
我检查了SGD代码,似乎第二种方法是正确的。但是在我的编码过程中,第一种方法收敛得更快,结果也比第二种好。为什么错误的方法表现得比正确的方法更好呢?
我还附上了完整的代码如下:
def SGD_method1():maxIter = 100 # 最大迭代次数alpha = 1e4 # 学习率m, n = np.shape(X) # X[m,n], m:样本数, n:特征数theta = np.zeros(n) # 初始thetafor iter in range(0, maxIter): hypothese = np.dot(X, theta) # 使用相同的theta更新所有假设 for i in range(0, m): theta = theta + alpha * (y[i] - hypothese[i]) * X[i]return theta
def SGD_method2():maxIter = 100 # 最大迭代次数alpha = 1e4 # 学习率m, n = np.shape(X) # X[m,n], m:样本数, n:特征数theta = np.zeros(n) # 初始thetafor iter in range(0, maxIter): for i in range(0, m): h = np.dot(X[i], theta) # 使用最新的theta更新假设 theta = theta + alpha * (y[i] -h) * X[i]return theta
回答:
第一个代码不是随机梯度下降。它是“传统的”(批量)梯度下降。随机性来自于基于一个样本(或小批量,称为小批量SGD)计算的梯度更新。显然,这不是误差函数的正确梯度(误差函数是所有训练样本误差的总和),但可以证明,在合理条件下,这种过程会收敛到局部最优解。随机更新在许多应用中更受欢迎,因为它们简单且(在许多情况下)计算成本更低。两种算法都是正确的(在合理假设下,两者都保证收敛到局部最优解),具体策略的选择取决于具体问题(特别是其规模和其他要求)。