这是我的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.cdef 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