Python 中的线性回归会放大 y=mx+c 中较大 x 值的梯度

Linear regression in Python blows up gradients for larger values of x in y=mx+c

这是我的 python 实现梯度下降的代码。如果 y=mx+c 中的 x 值足够小(例如:此代码中的 0-1),它会完美运行。 如果我从 x = np.random.rand(1,500) 更改为 x = np.random.rand(1,500)*100,梯度(dlw 和 dlc)会爆炸,并且在对它们进行几次迭代后我得到 nan 值(因此权重 w 和偏置 c 也是 nan)。这里有什么问题?

class LinearRegression:
 def __init__(self,lr=0.01,iter=2000):
    self.lr = lr
    self.iter = iter

 def gradient_descent(self,y,x):
    for i in range(self.iter):
        yhat = np.dot(self.w.T,x) + self.c
        dlw = (2/self.m)*np.dot(x, (yhat-y).T)
        dlc = (2/self.m)*np.sum(yhat-y)
        self.w = self.w - self.lr*dlw
        self.c = self.c - self.lr*dlc

 def run(self, y, x):
    self.m = x.shape[1]
    self.n = x.shape[0]
    self.w = np.zeros((self.n,1))
    self.c = 0
    self.gradient_descent(y,x)
    return self.w, self.c


def main():
    x = np.random.rand(1,500) #nxm (n = no of features, m = no of examples)
    print (x.shape)
    y = 5*x + 3 +(np.random.randn(1,500)*0.1)

    algorithm = LinearRegression()
    w,c = algorithm.run(y,x)
    print (w,c)

 if __name__ == '__main__':
    main()

没有什么是“错误的”,梯度下降 不会收敛 即使对于线性回归情况也是如此,除非学习率足够小。通过重新缩放数据,您也有效地重新缩放了学习率。

作为对该现象的示例性数学分析: https://www.stat.cmu.edu/~ryantibs/convexopt-F13/scribes/lec6.pdf

如果您在更新 x = np.random.rand(1,500)*100 时遇到以下错误,您的 main() 有一些拼写错误。

RuntimeWarning: invalid value encountered in subtract self.w = self.w

  • self.lr*dlw [[nan]] nan

我只是改变了一些,例如添加一个括号,使用变量引用。收敛 10m,10000m 为 2.9999999999999996.

更新W & C会触发double_scalars溢出,如果你的learning_rate太大(0.1 >)你需要检查这两行代码 [已编辑].

def main():
    # n = features, m = training examples
    x = np.random.randn(10,10000) 
    print(x.shape)
    y = (5 * x ) + 3 + (x * 0.1)
    algorithm = LinearRegression()
    w, c = algorithm.run(y, x)
    print(w, c)