python 中从头开始的梯度下降不起作用
Gradient descent from scratch in python not working
我正在尝试在 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 )
但它看起来确实不对,实际值相差甚远(数组([[-8.92647663e+148],
[-5.92079000e+150]]))
)
我猜你是被广播击中了。变量 y 的形状是 (100,)。当从 X.T@X@theta 的结果中减去 y 时。 Theta 是列向量,所以我猜结果是列向量。变量 y 被广播到形状为 (1,100) 的 row 向量。减法的结果是(100,100)。使用 y.reshape(-1,1)
将此重塑 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,算法将会收敛。
祝你好运!
我正在尝试在 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 ) 但它看起来确实不对,实际值相差甚远(数组([[-8.92647663e+148], [-5.92079000e+150]])) )
我猜你是被广播击中了。变量 y 的形状是 (100,)。当从 X.T@X@theta 的结果中减去 y 时。 Theta 是列向量,所以我猜结果是列向量。变量 y 被广播到形状为 (1,100) 的 row 向量。减法的结果是(100,100)。使用 y.reshape(-1,1)
将此重塑 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,算法将会收敛。 祝你好运!