BGD:坚定不移地朝损失函数最小的方向移动,一定来到最小值。
SGD:不能保证每次的方向是损失函数减小的方向,更不能保证是减小速度最快的方向,随机路径,不可预知。
最终依然会来的最小值的附近。
梯度改变方向是随机的,不能保证损失函数始终是减小的,损失函数的值是跳跃的
m太多>1000,愿意用一定精度换取一定的时间。
Batch Gradient Descent:某1点的θ的
梯度值,每1项都要对所有的样本进行计算,前面都有
,样本中所有信息批量进行计算。
Batch Gradient Descent样本量,非常大?计算梯度本身非常耗时!
Stochastic Gradient Descent:每一项都对m个
样本进行计算,为了取平均还除以了m。→ 只对1个样本计算,去掉,每次都取固定的1个i
。就是1行
使用上面式子当做
搜索的
方向。已经不是梯度的方向了~
随机梯度学习率的取值
本来已经在最小值附近,eta又是个固定值?又慢慢跳出最小值所在的位置。
- 学习率逐渐递减,
倒数
- 循环次数比较少时, 值下降太快了?前后下降差别比例太大了
- 分子/分母,加个数,缓解这种情况→ 也成为超参数?
- 用经验上比较好的
a=5,b=50
- 参考
模拟退火的思想
:炼钢、温度随时间从高到低冷却 - 不需要调用
J()
函数
def dJ_sgd(theta, X_b_i, y_i):
return X_b_i.T.dot(X_b_i.dot(theta) - y_i) * 2.
def sgd(X_b, y, initial_theta, n_iters):
t0 = 5
t1 = 50
def learning_rate(t):
return t0 / (t + t1)
theta = initial_theta
for cur_iter in range(n_iters):
rand_i = np.random.randint(len(X_b))
gradient = dJ_sgd(theta, X_b[rand_i], y[rand_i])
theta = theta - learning_rate(cur_iter) * gradient
return theta
%%time
X_b = np.hstack([np.ones((len(X), 1)), X])
initial_theta = np.zeros(X_b.shape[1])
theta = sgd(X_b, y, initial_theta, n_iters=len(X_b)//3)
总结
网友评论