我在尝试用Python实现梯度下降算法,但每次迭代我的损失/成本都在增加。
我看到了一些人发布过类似的问题,并且在这里看到一个答案:使用Python和Numpy进行梯度下降
我认为我的实现与之类似,但无法找出导致成本值激增的原因:
Iteration: 1 | Cost: 697361.660000Iteration: 2 | Cost: 42325117406694536.000000Iteration: 3 | Cost: 2582619233752172973298548736.000000Iteration: 4 | Cost: 157587870187822131053636619678439702528.000000Iteration: 5 | Cost: 9615794890267613993157742129590663647488278265856.000000
我在网上找到的一个数据集(LA Heart Data)上进行测试:http://www.umass.edu/statdata/statdata/stat-corr.html
导入代码:
dataset = np.genfromtxt('heart.csv', delimiter=",")x = dataset[:]x = np.insert(x,0,1,axis=1) # Add 1's for biasy = dataset[:,6]y = np.reshape(y, (y.shape[0],1))
梯度下降:
def gradientDescent(weights, X, Y, iterations = 1000, alpha = 0.01): theta = weights m = Y.shape[0] cost_history = [] for i in xrange(iterations): residuals, cost = calculateCost(theta, X, Y) gradient = (float(1)/m) * np.dot(residuals.T, X).T theta = theta - (alpha * gradient) # Store the cost for this iteration cost_history.append(cost) print "Iteration: %d | Cost: %f" % (i+1, cost)
计算成本:
def calculateCost(weights, X, Y): m = Y.shape[0] residuals = h(weights, X) - Y squared_error = np.dot(residuals.T, residuals) return residuals, float(1)/(2*m) * squared_error
计算假设:
def h(weights, X): return np.dot(X, weights)
实际运行代码:
gradientDescent(np.ones((x.shape[1],1)), x, y, 5)
回答:
假设你的梯度计算是正确的,你使用的是=-
,而应该使用的是-=
。你不是在更新theta
,而是将其重新赋值为- (alpha * gradient)
。
编辑(在上述问题修复后):
我运行了代码,相信使用了正确的数据集,通过设置alpha=1e-7
,能够使成本值正常表现。如果你运行1e6
次迭代,应该会看到它收敛。在这个数据集上,这种方法似乎对学习率非常敏感。