三种梯度下降方法与代码实现(二)

简介: 本文属于 线性回归算法【AIoT阶段三】(尚未更新),这里截取自其中一段内容,方便读者理解和根据需求快速阅读。本文通过公式推导+代码两个方面同时进行,因为涉及到代码的编译运行,如果你没有NumPy,Pandas,Matplotlib的基础,建议先修文章:数据分析三剑客【AIoT阶段一(下)】(十万字博文 保姆级讲解),本文是梯度下降的第二部分,学之前需先修:梯度下降【无约束最优化问题】,后续还会有:梯度下降优化,梯度下降优化进阶 (暂未更新)

2.代码实现梯度下降

2.1 批量梯度下降BGD

2.1.1 一元一次线性回归

import numpy as np
# 创建数据
X = np.random.rand(100, 1)
w, b = np.random.randint(1, 10, size = 2)
# 增加噪声,也被称为"加盐"
y = w * X + b + np.random.rand(100, 1)
# 把b作为偏置项,截距对应系数 x_0 = 1, 更新 X
X = np.concatenate([X, np.full(shape = (100, 1), 
                               fill_value = 1)], axis = 1)
# 循环次数
epoches = 10000
# 学习率
eta = 0.01
# 要求解的系数,"瞎蒙的"
theta = np.random.randn(2, 1)
for i in range(epoches):
    # 批量梯度下降,X为矩阵,包含所有的数据
    g = X.T.dot(X.dot(theta) - y)  # 根据公式计算的梯度
    theta = theta - eta * g
print('真实的斜率、截距:', w, b)
print('使用BGD求的斜率、截距:', theta[0], theta[1])

19.png

可以看出,我们求出的数据和真实的数据还是有一定的差距的,这就是加了 噪声(加盐) 的作用结果,但这样的计算数据才是更加真实的,因为现实生活中的数据是不可能完美的。

下图是梯度下降的示意图:

image.png

image.png

import numpy as np
# 创建数据
X = np.random.rand(100, 1)
w, b = np.random.randint(1, 10, size = 2)
# 增加噪声,也被称为"加盐"
y = w * X + b + np.random.rand(100, 1)
# 把b作为偏置项,截距对应系数 x_0 = 1, 更新 X
X = np.concatenate([X, np.full(shape = (100, 1), 
                               fill_value = 1)], axis = 1)
# 循环次数
epoches = 10000
# 学习率
t0, t1 = 5, 1000
# t 是梯度下降的次数,逆时衰减,随着梯度下降次数增加,学习率变小
def learning_rate_shedule(t):
    return t0 / (t + t1)
# 要求解的系数,"瞎蒙的"
theta = np.random.randn(2, 1)
for i in range(epoches):
    # 批量梯度下降,X为矩阵,包含所有的数据
    g = X.T.dot(X.dot(theta) - y)  # 根据公式计算的梯度
    eta = learning_rate_shedule(i)
    theta = theta - eta * g
print('真实的斜率、截距:', w, b)
print('使用BGD求的斜率、截距:', theta[0], theta[1])

20.png

2.1.2 八元一次线性回归

import numpy as np
# 创建数据
X = np.random.rand(100, 8)
w = np.random.randint(1, 10, size = (8, 1))
b = np.random.randint(1, 10, size = 1)
# 增加噪声,也被称为"加盐"
y = X.dot(w) + b + np.random.rand(100, 1)
# 把b作为偏置项,截距对应系数 x_0 = 1, 更新 X
X = np.concatenate([X, np.full(shape = (100, 1), 
                               fill_value = 1)], axis = 1)
# 循环次数
epoches = 10000
# 学习率
t0, t1 = 5, 1000
# t 是梯度下降的次数,逆时衰减,随着梯度下降次数增加,学习率变小
def learning_rate_shedule(t):
    return t0 / (t + t1)
# 要求解的系数,"瞎蒙的"
theta = np.random.randn(9, 1)
for i in range(epoches):
    # 批量梯度下降,X为矩阵,包含所有的数据
    g = X.T.dot(X.dot(theta) - y)  # 根据公式计算的梯度
    eta = learning_rate_shedule(i)
    theta = theta - eta * g
print('真实的斜率、截距:', w, b)
print('使用BGD求的斜率、截距:', theta)

21.png

2.2 随机梯度下降SGD

2.2.1 一元一次线性回归

import numpy as np
# 创建数据
X = np.random.rand(100, 1)
w, b = np.random.randint(1, 10, size = 2)
# 增加噪声,也被称为"加盐"
y = w * X + b + np.random.rand(100, 1)
# 把b作为偏置项,截距对应系数 x_0 = 1, 更新 X
X = np.concatenate([X, np.full_like(X, fill_value = 1)], axis = 1)
# 循环次数
epoches = 100
# 学习率
t0, t1 = 5, 1000
# t 是梯度下降的次数,逆时衰减,随着梯度下降次数增加,学习率变小
def learning_rate_shedule(t):
    return t0 / (t + t1)
theta = np.random.randn(2, 1)
cnt = 0  # 表示训练的次数
for t in range(epoches):
    index = np.arange(100)
    np.random.shuffle(index)     # 洗牌,打乱顺序
    # NumPy 花式索引
    X = X[index]
    y = y[index]
    for i in range(100):
        X_i = X[[i]]
        y_i = y[[i]]
        # 根据这一个样本,进行计算梯度
        g = X_i.T.dot(X_i.dot(theta) - y_i)
        eta = learning_rate_shedule(cnt)
        cnt += 1
        theta -= eta * g
print('真实的斜率、截距:', w, b)
print('使用SGD求的斜率、截距:', theta[0], theta[1])

22.png

2.2.2 五元一次线性回归

import numpy as np
# 创建数据
X = np.random.rand(100, 5)
w = np.random.randint(1, 10, size = (5, 1))
b = np.random.randint(1, 10, size = 1)
# 增加噪声,也被称为"加盐"
y = X.dot(w) + b + np.random.rand(100, 1)
# 把b作为偏置项,截距对应系数 x_0 = 1, 更新 X
X = np.concatenate([X, np.full(shape = (100, 1), fill_value = 1)], axis = 1)
# 循环次数
epoches = 100
# 学习率
t0, t1 = 5, 1000
# t 是梯度下降的次数,逆时衰减,随着梯度下降次数增加,学习率变小
def learning_rate_shedule(t):
    return t0 / (t + t1)
theta = np.random.randn(6, 1)
cnt = 0  # 表示训练的次数
for t in range(epoches):
    index = np.arange(100)
    np.random.shuffle(index)     # 洗牌,打乱顺序
    # NumPy 花式索引
    X = X[index]
    y = y[index]
    for i in range(100):
        X_i = X[[i]]   # 两个[]:可以进行矩阵运算
        y_i = y[[i]]
        # 根据这一个样本,进行计算梯度
        g = X_i.T.dot(X_i.dot(theta) - y_i)
        eta = learning_rate_shedule(cnt)
        cnt += 1
        theta -= eta * g
print('真实的斜率、截距:', w, b)
print('使用SGD求的斜率、截距:', theta)

23.png

2.3 小批量梯度下降MBGD

2.3.1 一元一次线性回归

import numpy as np
# 1、创建数据集X,y
X = np.random.rand(100, 1)
w,b = np.random.randint(1, 10,size = 2)
y = w * X + b + np.random.randn(100, 1)
# 2、使用偏置项x_0 = 1,更新X
X = np.c_[X, np.ones((100, 1))]
# 3、定义一个函数来调整学习率
t0, t1 = 5, 500
def learning_rate_schedule(t):
    return t0/(t + t1)
# 4、创建超参数轮次、样本数量、小批量数量
epochs = 100
n = 100
batch_size = 16
num_batches = int(n / batch_size)
# 5、初始化 W0...Wn,标准正太分布创建W
θ = np.random.randn(2, 1)
# 6、多次for循环实现梯度下降,最终结果收敛
for epoch in range(epochs):
    # 在双层for循环之间,每个轮次开始分批次迭代之前打乱数据索引顺序
    index = np.arange(n)
    np.random.shuffle(index)
    X = X[index]
    y = y[index]
    for i in range(num_batches):
        # 一次取一批数据16个样本
        X_batch = X[i * batch_size : (i + 1) * batch_size]
        y_batch = y[i * batch_size : (i + 1) * batch_size]
        g = X_batch.T.dot(X_batch.dot(θ) - y_batch)
        learning_rate = learning_rate_schedule(epoch * n + i)
        θ = θ - learning_rate * g
print('真实斜率和截距是:', w, b)
print('梯度下降计算斜率和截距是:',θ)

24.png

2.3.2 三元一次线性回归

import numpy as np
# 1、创建数据集X,y
X = np.random.rand(100, 3)
w = np.random.randint(1,10,size = (3, 1))
b = np.random.randint(1,10,size = 1)
y = X.dot(w) + b + np.random.randn(100, 1)
# 2、使用偏置项 X_0 = 1,更新X
X = np.c_[X, np.ones((100, 1))]
# 3、定义一个函数来调整学习率
t0, t1 = 5, 500
def learning_rate_schedule(t):
    return t0/(t + t1)
# 4、创建超参数轮次、样本数量、小批量数量
epochs = 10000
n = 100
batch_size = 16
num_batches = int(n / batch_size)
# 5、初始化 W0...Wn,标准正太分布创建W
θ = np.random.randn(4, 1)
# 6、多次for循环实现梯度下降,最终结果收敛
for epoch in range(epochs):
    # 在双层for循环之间,每个轮次开始分批次迭代之前打乱数据索引顺序
    index = np.arange(n)
    np.random.shuffle(index)
    X = X[index]
    y = y[index]
    for i in range(num_batches):
        # 一次取一批数据16个样本
        X_batch = X[i * batch_size : (i + 1) * batch_size]
        y_batch = y[i * batch_size : (i + 1) * batch_size]
        g = X_batch.T.dot(X_batch.dot(θ) - y_batch)
        learning_rate = learning_rate_schedule(epoch * n + i)
        θ = θ - learning_rate * g
print('真实斜率和截距是:', w, b)
print('梯度下降计算斜率和截距是:',θ)

25.png


目录
相关文章
|
人工智能 安全 算法
AI与大数据:智慧城市安全的护航者与变革引擎
AI与大数据:智慧城市安全的护航者与变革引擎
374 1
|
存储 监控 Java
【深度挖掘Java性能调优】「底层技术原理体系」深入探索Java服务器性能监控Metrics框架的实现原理分析(Counter篇)
【深度挖掘Java性能调优】「底层技术原理体系」深入探索Java服务器性能监控Metrics框架的实现原理分析(Counter篇)
327 0
|
安全 前端开发 JavaScript
逆向海淘代购集运系统:sugargoo的技术架构与创新服务解读
逆向海淘代购集运系统整合中国电商资源,为海外用户提供便捷购物及物流服务,降低购物成本。sugargoo系统搭建攻略包括: - **需求分析与规划**: 深入了解目标市场需求,明确服务特色。 - **平台开发**: 选用合适技术栈,开发关键功能模块,集成电商数据。 - **物流合作**: 建立物流合作关系,集成物流API提升自动化。 - **支付解决方案**: 支持多种支付方式,保障支付安全。 - **客户服务**: 提供多语言支持,建设专业客服团队。 - **营销与推广**: 优化SEO,利用社交媒体扩大品牌影响。
|
12月前
|
算法 程序员 开发工具
C语言编程规范
C 语言编程规范有助于提升代码的可读性、可维护性和可移植性。主要包括:命名规范(如 `my_variable`、`MAX_SIZE`)、代码缩进与空格、注释(解释逻辑但不过度)、函数设计(短小精悍、参数不超过三个)、错误处理、避免魔法数字、选择合适数据结构、使用标准库、保持代码格式一致及版本控制。遵循这些规范能显著提高团队开发效率和代码质量。
1055 2
|
数据采集 数据挖掘 Linux
跟着Titanic案例学Seaborn之Barplot
跟着Titanic案例学Seaborn之Barplot
252 0
|
运维 监控 安全
交换机运维监控:保障网络稳定的基石
作为网络连接的核心设备之一,交换机承担着数据转发、流量控制、VLAN划分等重要任务,其稳定运行直接关系到整个网络的性能和可靠性
661 0
|
监控 Java 应用服务中间件
Sentinel原理及实践
Sentinel原理及实践
405 1
|
数据挖掘 索引 Python
数据分析缺失值处理(Missing Values)——删除法、填充法、插值法
数据分析缺失值处理(Missing Values)——删除法、填充法、插值法
1371 2
|
tengine 弹性计算 运维
性能提升一倍!云原生网关支持 TLS 硬件加速
业界在优化 HTTPS 的性能上也做了诸多探索,传统的软件优化方案有 Session 复用、OCSP Stapling、False Start、dynamic record size、TLS1.3、HSTS 等, 但软件层面如何优化也无法满足流量日益增长的速度,加上 CPU 摩尔定律已入暮年,使得专用硬件卸载 CPU 密集型运算成为业界一个通用解决方案。
1984 106
性能提升一倍!云原生网关支持 TLS 硬件加速
|
负载均衡 Java 开发者
细解微服务架构实践:如何使用Spring Cloud进行Java微服务治理
【7月更文挑战第1天】Spring Cloud是Java微服务治理明星框架,整合Eureka(服务发现)、Ribbon(客户端负载均衡)、Hystrix(熔断器)、Zuul(API网关)和Config Server(配置中心),提供完整服务治理解决方案。通过Eureka实现服务注册与发现,Ribbon进行客户端负载均衡,Hystrix确保服务容错,Config Server集中管理配置,Zuul作为API网关简化系统复杂性。理解和使用Spring Cloud是现代Java开发者的关键技能。
319 0