为什么线性回归的纯 NumPy 实现的学习率优化如此无效?

问题描述 投票:0回答:1

在numpy中创建简单的线性回归模型后,我发现改变步长/学习率并不能有效提高模型的准确性或收敛速度。请注意给出此标准模型:


%%time

x = np.arange(100)
y = 3 * x + 5
x = np.column_stack((np.ones(100), x))

w = np.zeros((100, 2))
step_size = 10**-4
iterations = 10**5

for i in range(iterations):
    loss = 2 * (np.sum(w * x, axis=1) - y)
    w -= step_size * np.average(x * loss[:, None], axis=0)

print(w[0])

模型提供以下输出:

[4.60820653 3.00590689]
CPU times: user 5.04 s, sys: 19.9 ms, total: 5.06 s
Wall time: 5.07 s

更改step_size变量可以被视为超参数优化,但是当将其更改为大于10-4的任何值时,例如10-3,模型无法收敛并爆炸:

# step_size = 10**-3
[nan nan]
CPU times: user 4.98 s, sys: 38.2 ms, total: 5.02 s
Wall time: 5 s

这种行为在数学上是符合预期的,但遇到这种情况令人沮丧,并引出了一个问题:如何更有效地优化步长?


我尝试更改与梯度相关的系数(我将梯度变量标记为“损失”),而不是更改步长,因为这也会影响每个步骤的戏剧性(据我所知)给定更大或损失更小,因此下降的梯度更陡。令人惊讶的是,将损失系数从 2 更改为 5 显着提高了性能(这正是我所做的,而不是优化步长,但我想这是一个单独的主题)。

# changing loss coefficient from 2 to 5
[4.99998468 3.00000023]
CPU times: user 5.03 s, sys: 42.7 ms, total: 5.07 s
Wall time: 5.08 s
python numpy machine-learning linear-regression loss-function
1个回答
0
投票

将步长从

10**-4
增加到
10**-3
相当于 10 倍的增量。那是1000%。看似很小的数字,但差别却很大。考虑将步数加倍,例如等:

w = np.zeros(2)
step_size = 0.0001
iterations = 10**5

for i in range(iterations):
  direction =  (x @ w - y) @ x/y.size
  w -= step_size * direction
w
array([4.60820653, 3.00590689])

不同的步长

w = np.zeros(2)
step_size = 0.0005
iterations = 10**5

for i in range(iterations):
  direction =  (x @ w - y) @ x/y.size
  w -= step_size * direction
w
array([4.99998468, 3.00000023])

在此示例中,步长不能超过 0.0006。

© www.soinside.com 2019 - 2024. All rights reserved.