Gradient Descent梯度下降算法代码实现

目录

摘要

梯度下降法原理

使用二次函数简单实现和验证梯度下降

画出梯度下降的过程

学习率对梯度下降快慢的影响

在线性回归模型中使用梯度下降法

Conclusion(总结)


摘要

使用代码实现和验证梯度下降算法

梯度下降法原理

梯度下降,gradient descent(之后将简称GD),是一种通过迭代找最优的方式一步步找到损失函数最小值的算法,基本算法思路可总结为如下几点:

(1) 随机设置一个初始值

(2) 计算损失函数的梯度

(3) 设置步长,步长的长短将会决定梯度下降的速度和准确度

(4) 将初值减去步长乘以梯度,更新初值,然后将这一过程不断迭代

 

使用二次函数简单实现和验证梯度下降

import numpy as np
import matplotlib.pyplot as plt

plot_x = np.linspace(-1,6,141)
plot_y = (plot_x - 2.5)**2 - 1
plt.plot(plot_x,plot_y)
plt.show()

 

def dJ(theta):
    return 2*(theta - 2.5)

def J(theta):
    try:
        return (theta - 2.5)**2-1
    except:
        return float('inf')

实验结果:

theta= 0.5
函数值= 3.0
第0次梯度下降.....
theta= 0.9
函数值= 1.5600000000000005
第1次梯度下降.....
theta= 1.2200000000000002
函数值= 0.6383999999999994
第2次梯度下降.....
theta= 1.4760000000000002
函数值= 0.04857599999999951
第3次梯度下降.....
theta= 1.6808
函数值= -0.3289113600000001
......
第42次梯度下降.....
theta= 2.4998638870532313
函数值= -0.9999999814732657
第43次梯度下降.....
最终theta= 2.499891109642585
最终函数值= -0.99999998814289
 

画出梯度下降的过程

theta = 0.0
theta_history = [theta]
while True:
    gradient = dJ(theta)
    last_theta = theta
    theta = theta - eta * gradient
    theta_history.append(theta)
    if(abs(J(theta) - J(last_theta)) < epsilon):
        break

plt.plot(plot_x,J(plot_x))
plt.plot(np.array(theta_history),J(np.array(theta_history)),color="r",marker="+")
plt.show()

学习率对梯度下降快慢的影响

当学习率eta = 0.001时的图像

initial_theta = 0
eta = 0.001
theta_history = []
gradient_descent(initial_theta,eta)
plot_theta_history()

 

当学习率eta = 0.8时的图像

initial_theta = 0
eta = 0.8
theta_history = []
gradient_descent(initial_theta,eta)
plot_theta_history()

 

当学习率eta = 1.1时的图像

initial_theta = 0
eta = 1.1
theta_history = []
gradient_descent(initial_theta,eta,n_iters=10)
plot_theta_history()

 

 

 

在线性回归模型中使用梯度下降法

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(666)
x = 2 * np.random.random(size=100)
y = x * 3. + 4. + np.random.normal(size=100)
X = x.reshape(-1, 1)
X.shape
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)

实验结果:array([4.02145786, 3.00706277])

即截距 b = 4.02145786 ,斜率 a = 3.00706277  大致满足设置的函数 y = x * 3. + 4. + np.random.normal(size=100)

 

Conclusion(总结)

1.学习率eta取值影响获得最优解的速度

2.学习率eta取值不合适,甚至得不到最优解

3.学习率eta是一个超参数

4.使用梯度下降算法不一定能得到全局最优解,可能是局部最优解

5.可以多次运行,随机化初始点,多次尝试找出最优解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值