Python 梯度下降 - 成本不断增加
Python gradient descent - cost keeps increasing
我正在尝试在 python 中实现梯度下降,而我的 loss/cost 每次迭代都在增加。
我见过一些人post,在这里看到了一个答案:gradient descent using python and numpy
我相信我的实现是相似的,但看不出我做错了什么以获得爆炸式的成本值:
Iteration: 1 | Cost: 697361.660000
Iteration: 2 | Cost: 42325117406694536.000000
Iteration: 3 | Cost: 2582619233752172973298548736.000000
Iteration: 4 | Cost: 157587870187822131053636619678439702528.000000
Iteration: 5 | Cost: 9615794890267613993157742129590663647488278265856.000000
我正在网上找到的数据集(洛杉矶心脏数据)上对此进行测试: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 bias
y = 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
次迭代,您应该会看到它收敛。此数据集上的这种方法似乎对学习率非常敏感。
一般来说,如果你的成本在增加,那么你应该首先检查的是你的学习率是否太大。在这种情况下,速率会导致成本函数跳过最优值并向上增加到无穷大。尝试学习率的不同小值。当我遇到你描述的问题时,我通常会反复尝试 1/10 的学习率,直到找到 J(w) 下降的速率。
另一个问题可能是您的派生实现中的错误。调试的一个好方法是进行梯度检查以比较解析梯度与数值梯度。
我正在尝试在 python 中实现梯度下降,而我的 loss/cost 每次迭代都在增加。
我见过一些人post,在这里看到了一个答案:gradient descent using python and numpy
我相信我的实现是相似的,但看不出我做错了什么以获得爆炸式的成本值:
Iteration: 1 | Cost: 697361.660000
Iteration: 2 | Cost: 42325117406694536.000000
Iteration: 3 | Cost: 2582619233752172973298548736.000000
Iteration: 4 | Cost: 157587870187822131053636619678439702528.000000
Iteration: 5 | Cost: 9615794890267613993157742129590663647488278265856.000000
我正在网上找到的数据集(洛杉矶心脏数据)上对此进行测试: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 bias
y = 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
次迭代,您应该会看到它收敛。此数据集上的这种方法似乎对学习率非常敏感。
一般来说,如果你的成本在增加,那么你应该首先检查的是你的学习率是否太大。在这种情况下,速率会导致成本函数跳过最优值并向上增加到无穷大。尝试学习率的不同小值。当我遇到你描述的问题时,我通常会反复尝试 1/10 的学习率,直到找到 J(w) 下降的速率。
另一个问题可能是您的派生实现中的错误。调试的一个好方法是进行梯度检查以比较解析梯度与数值梯度。