梯度下降
梯度下降是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以)。在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient
Descent)是最常采用的方法之一,另一种常用的方法是最小二乘法。在求解损失函数的最小值时,可以通过梯度下降法来一步步的迭代求解,得到最小化的损失函数和模型参数值。反过来,如果我们需要求解损失函数的最大值,这时就需要用梯度上升法来迭代了。
举一个非常简单的例子,如求函数f(x)=x^2 的最小值。
利用梯度下降的方法解题步骤如下:
1、求梯度, gradient=2x
2、向梯度相反的方向移动 ,如下:
x=x - gradient *learning_rate
其中, learning_rate为步长。如果步长足够小,则可以保证每一次迭代都在减小,但可能导致收敛太慢,如果步长太大,则不能保证每一次迭代都减少,也不能保证收敛。
3、循环迭代步骤2,直到x的值变化到使得f(x)在两次迭代之间的差值足够小,比如0.00000001,也就是说,直到两次迭代计算出来的f(x)基本没有变化,则说明此时f(x)已经达到局部最小值了。
4、此时,输出 x,这个x就是使得函数f(x)最小的取值 。
linear regression
y=wx+b,文件data.csv中给出大量x,y的值,使用梯度下降算法预估w和b的值
要想预估w和b的近似值,算出所有x,y对应的 (wx+b-y)^2 之和最小值即可
总体误差
def compute_error_for_line_given_points(b, w, points):
totalerror = 0
N = len(points)
for i in range(N):
x = points[i, 0]
y = points[i, 1]
totalerror += (w * x + b - y) ** 2
return totalerror / float(N)
计算每一次的梯度值,并进行迭代
def step_gradient(b_current, w_current, points, learningRate):
N = float(len(points))
b_gradient = 0
w_gradient = 0
for i in range(len(points)):
x = points[i, 0]
y = points[i, 1]
b_gradient += 2 / N * (w_current * x + b_current - y)
w_gradient += 2 / N * x * (w_current * x + b_current - y)
new_b = b_current - b_gradient * learningRate
new_w = w_current - w_gradient * learningRate
return new_b, new_w
梯度下降
def gradient_descent_runner(points, starting_b, starting_w,
learning_rate, num_iterations):
b_current = starting_b
w_current = starting_w
for i in range(num_iterations): # 迭代num_iterations次,每次步长为learning_rate
b_current, w_current = step_gradient(b_current, w_current, points, learning_rate)
return b_current, w_current
运行
def run():
points = np.genfromtxt("data.csv", delimiter=',')
b = 0
w = 0
learning_rate = 0.0001
num_iterations = 1000
print("start b={0},w={1},error={2}"
.format(b, w, compute_error_for_line_given_points(b, w, points)))
b, w = gradient_descent_runner(points, b, w, learning_rate, num_iterations)
print("end b={0},w={1},error={2}"
.format(b, w, compute_error_for_line_given_points(b, w, points)))
if __name__ == "__main__":
run()
经过1000次,步长为0.0001的迭代之后,得出结果
误差已从5565左右下降至112左右,得到了近似的w和b