从0开始的机器学习——梯度下降法

Posted xiyoushumu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从0开始的机器学习——梯度下降法相关的知识,希望对你有一定的参考价值。

在解决问题中,θ可能不是一个值,可能是一个向量,所以在求导的时候可以写成求梯度的形式,求函数在每个方向上的偏导数。

技术图片

其实和上一节处理的问题也相似,只不过这个处理的不是一个数,是一个向量。

技术图片

这是一个三元函数的曲线图。图中的红色圈圈就是函数曲线。假如起始点从左上角那个点出发,一直到数值最低的点,其实这个路径选择有无数条,但是我们要找的就是下降速度最快的那个。

下面看梯度下降法的目标:

技术图片

但是这样的向量有一个弊端:因为m的值可能会很大,可能导致向量的值很大,在计算中出现问题。所以要对最后的向量形式进行改进,比如在外面乘1/m,减少m对向量的影响。

技术图片

有时候取外面乘1/2的,和向量外面的2约去,但是一个常数影响是很小的,也可以不约去2。

 

代码实现:

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(666)
x = 2 * np.random.random(size=100)  #100个只有一个特征的数据点
y = x * 3. + 4. + np.random.normal(size=100)

X = x.reshape(-1,1)

plt.scatter(x,y)
plt.show()

技术图片

得到这样的散点图

def J(theta, X_b, y):
    try:
        return np.sum((y - X_b.dot(theta))**2) / len(X_b)
    except:
        return float(‘inf‘)
   

def dJ(theta, X_b, y):
    res = np.empty(len(theta))
    res[0] = np.sum(X_b.dot(theta) - y)
    for i in range(1, len(theta)):
        res[i] = (X_b.dot(theta) - y).dot(X_b[:,i])
    return res * 2 / len(X_b)


def gradient_descent(X_b, y, initial_theta, eta, n_iters = 1e4, epsilon=1e-8):
    
    theta = initial_theta
    cur_iter = 0

    while cur_iter < n_iters:
        gradient = dJ(theta, X_b, y)
        last_theta = theta
        theta = theta - eta * gradient
        if(abs(J(theta, X_b, y) - J(last_theta, X_b, y)) < epsilon):
            break
            
        cur_iter += 1

    return theta

 

X_b = np.hstack([np.ones((len(x), 1)), x.reshape(-1,1)])
initial_theta = np.zeros(X_b.shape[1])
eta = 0.01

theta = gradient_descent(X_b, y, initial_theta, eta)

技术图片

获得斜率和截距,和最开始动手设置的基本吻合,证明梯度下降是成功的。

以上是关于从0开始的机器学习——梯度下降法的主要内容,如果未能解决你的问题,请参考以下文章

(TODO)机器学习与深度学习核心知识点总结

梯度下降法是啥?

[机器学习]—梯度下降法

机器学习梯度下降法(超详解)

机器学习 | 梯度下降种类及对比

机器学习 | 梯度下降种类及对比