【问题标题】:Gradient descent from scratch in python not workingpython中从头开始的梯度下降不起作用
【发布时间】:2019-11-29 04:45:03
【问题描述】:

我正在尝试在 python 中从头开始实现梯度下降算法,这应该相当容易。但是,我现在一直在摸索我的代码,无法让它工作。

我生成数据如下:

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('darkgrid')

#Defining the x array. 
x=np.array(range(1,100)) 

#Defining the y array. 
y=10+2*x.ravel() 
y=y+np.random.normal(loc=0, scale=70, size=99)

然后定义参数:

alpha = 0.01  # Which will be the learning rate
NbrIter = 100  # Representing the number of iteration
m = len(y)
theta = np.random.randn(2,1)

我的GD如下:

for iter in range(NbrIter):
    theta = theta - (1/m) * alpha * ( X.T @ ((X @ theta) - y) )

我得到的是一个巨大的矩阵,这意味着我对线性代数有一些问题。但是,我真的看不出问题出在哪里。

(玩弄矩阵以尝试使它们匹配,我达到了具有正确形式(2x1)的theta: theta = theta - (1/m) * alpha * ( X.T @ ((X @ theta).T - y).T ) 但它看起来确实是错误的,并且实际值相差甚远(array([[-8.92647663e+148], [-5.92079000e+150]])) )

【问题讨论】:

标签: python numpy optimization gradient-descent


【解决方案1】:

我猜你被广播击中了。变量 y 的形状是 (100,)。当从 X.T@X@theta 的结果中减去 y 时。 Theta 是列向量,所以我猜结果是列向量。变量 y 被广播到形状为 (1,100) 的 row 向量。减法的结果是 (100,100)。用 y.reshape(-1,1) 修复这个 reshape y 作为列向量

现在,进行一些优化:

X.T @ ((X @ theta) - y[:,None])

可以改写为:

(X.T@X) @ theta - (X.T*y[:,None])

最昂贵的计算可以从循环中取出:

XtX = X.T@X
Xty = X.T*y[:,None]

for iter in range(NbrIter):
    theta = theta - (1/m) * alpha * (XtX @ theta - Xty)

现在您对 2x2 矩阵而不是 100x2 进行操作。

让我们来看看收敛。 假设 X 的构造如下:X=np.column_stack((x, np.ones_like(x)) 可以检查矩阵条件:

np.linalg.cond(XtX)

其中产生: 13475.851490419038

这意味着最小和最大特征向量之间的比率约为13k。因此使用大于 1/13k 的 alpha 可能会导致收敛性差。

如果您使用 alpha=1e-5,算法将收敛。 祝你好运!

【讨论】:

  • 是的!谢谢,这绝对是我没看到的广播问题,谢谢!
猜你喜欢
  • 1970-01-01
  • 2023-03-18
  • 2017-06-23
  • 2016-10-31
  • 1970-01-01
  • 1970-01-01
  • 2020-05-12
  • 2021-12-18
相关资源
最近更新 更多