2024-11-25 学习人工智能的Day30 自动微分与手动构建线性回归模型

devtools/2024/11/28 4:57:17/

自动微分与手动构建模型实战

一、自动微分

1. 基础概念

自动微分模块 torch.autograd 负责自动计算张量操作的梯度,主要特点包括:

  • 张量requires_grad=True 的张量会追踪其所有操作,以便后续计算梯度。
  • 计算图:动态创建计算图,记录操作。
  • 反向传播:通过 .backward() 计算梯度。
  • 梯度访问:通过 .grad 属性访问计算结果。

2. 计算梯度

2.1 标量梯度计算
import torch# 创建一个标量张量
x = torch.tensor(7.0, requires_grad=True)
y = x**2 + 2 * x + 7
# 计算梯度
y.backward()
# 查看梯度
print(x.grad)  # 输出:tensor(16.)

解释

  • requires_grad=True 表示张量需要计算梯度。
  • .backward() 会对标量计算梯度。
  • 结果存储在 x.grad 中。
2.2 向量梯度计算
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = x**2 + 2 * x + 7
z = y.mean()  # 将向量变为标量
z.backward()
print(x.grad)  # 输出向量的梯度

解释

  • 向量梯度需要通过 .mean().sum() 将其变为标量。
  • .backward() 自动传播计算各分量的梯度。
2.3 梯度清零

梯度会累加,清零可以防止影响下一次计算:

if x.grad is not None:x.grad.zero_()

二、手动构建模型实战

1. 数据处理

1.1 构建数据集
from sklearn.datasets import make_regression
import torch# 生成数据
X, y, coef = make_regression(n_samples=1000, n_features=5, noise=5, coef=True, random_state=0
)
X = torch.tensor(X, dtype=torch.float32)
y = torch.tensor(y, dtype=torch.float32)
1.2 数据加载器
import random, mathdef data_loader(x, y, batch_size=16):indices = list(range(x.shape[0]))random.shuffle(indices)num_batches = math.ceil(len(indices) / batch_size)for i in range(num_batches):start = i * batch_sizeend = min(start + batch_size, len(indices))yield x[indices[start:end]], y[indices[start:end]]

2. 模型与损失函数

2.1 模型函数
def linear_regression(x, w, b):return torch.matmul(x, w) + b
2.2 损失函数
def mean_squared_error(y_pred, y_true):return torch.mean((y_pred - y_true)**2)

3. 参数初始化与优化器

3.1 参数初始化
def initialize_params(n_features):w = torch.randn(n_features, requires_grad=True)b = torch.tensor(0.0, requires_grad=True)return w, b
3.2 优化器 (SGD)
def sgd(w, b, dw, db, lr, batch_size):w.data -= lr * dw / batch_sizeb.data -= lr * db / batch_size

4. 训练模型

训练函数
def train():X, y, coef = make_regression_data()w, b = initialize_params(X.shape[1])lr, epochs, batch_size = 0.01, 100, 16for epoch in range(epochs):total_loss = 0for X_batch, y_batch in data_loader(X, y, batch_size):y_pred = linear_regression(X_batch, w, b)loss = mean_squared_error(y_pred, y_batch)total_loss += loss.item()# 反向传播和参数更新loss.backward()w.grad.zero_()b.grad.zero_()sgd(w, b, w.grad, b.grad, lr, batch_size)print(f"Epoch {epoch + 1}, Loss: {total_loss}")

5. 总结

通过以上代码,展示了从数据处理、模型定义、训练过程到结果的完整实现。训练时通过反向传播和优化器不断调整参数,逐步减小误差。

最后是整个手动构建的代码

import math
import random
import torch
import numpy as np
from sklearn.datasets import make_regression
import pandas as pddef build_dataset():"""使用 sklearn 的 make_regression 方法来构建一个模拟的回归数据集。make_regression 方法的参数解释:- n_samples: 生成的样本数量,决定了数据集的规模。- n_features: 生成的特征数量,决定了数据维度。- noise: 添加到目标变量的噪声标准差,用于模拟真实世界数据的不完美。- coef: 如果为 True, 会返回生成数据的真实系数,用于了解特征与目标变量间的真实关系。- random_state: 随机数生成的种子,确保在多次运行中能够复现相同的结果。返回:- X: 生成的特征矩阵。- y: 生成的目标变量。- coef: 如果在调用时 coef 参数为 True,则还会返回真实系数。"""noise = random.randint(1, 3)bias = 14.5X, y, coef = make_regression(n_samples=1000, n_features=5, bias=bias, noise=noise, coef=True, random_state=0)# 数据转换为张量X = torch.tensor(X, dtype=torch.float32)y = torch.tensor(y, dtype=torch.float32)coef = torch.tensor(coef, dtype=torch.float32)bias = torch.tensor(bias, dtype=torch.float32)return X, y, coef, biasdef data_loader(x, y, batch_size=16):"""将数据集转换为迭代器,以便在训练过程中进行批量处理。"""# 获取样本数量num_samples = x.shape[0]# 构建数据索引indices = list(range(num_samples))# 打乱数据顺序random.shuffle(indices)# 计算总的批次数量:向上取整num_batches = math.ceil(num_samples / batch_size)for i in range(num_batches):start = i * batch_sizeend = min((i + 1) * batch_size, num_samples)# 开始切片数据train_X = x[indices[start:end]]train_y = y[indices[start:end]]# 异步响应数据集yield train_X, train_y# 构建模型函数:权重参数和偏执参数
# 初始化参数
def initialize_params(n_features):# 随机初始化权重w,并将偏置b初始化为0w = torch.randn(n_features, requires_grad=True, dtype=torch.float32)b = torch.tensor(0.0, requires_grad=True, dtype=torch.float32)return w, bdef linear_regression(x, w, b):return torch.matmul(x, w) + b# 构建模型函数:损失函数和优化器
def mean_squared_error(y_pred, y_true):return torch.mean((y_pred - y_true) ** 2)# 优化器(SGD,手动实现)
def sgd(w, b, dw, db, learning_rate, batch_size):w.data -= learning_rate * dw.data / batch_sizeb.data -= learning_rate * db.data / batch_sizereturn w, b# 训练函数
def train():# 1. 构建数据集X, y, coef, bias = build_dataset()# 2. 初始化模型参数w, b = initialize_params(X.shape[1])# 3. 定义训练参数learning_rate = 0.01epochs = 120batch_size = 16# 4. 开始训练for epoch in range(epochs):epoch_loss = 0num_batches = 0for train_X, train_y in data_loader(X, y, batch_size):num_batches += 1# 5. 前向传播y_pred = linear_regression(train_X, w, b)# 6. 计算损失loss = mean_squared_error(y_pred, train_y)# 9. 梯度清零if w.grad is not None:w.grad.zero_()if b.grad is not None:b.grad.zero_()# 7. 反向传播:会自动计算梯度loss.backward()# 8. 更新参数w, b = sgd(w, b, w.grad, b.grad, learning_rate, batch_size)# 10. 训练批次及损失率epoch_loss += loss.item()print(f"Epoch: {epoch}, Loss: {epoch_loss / num_batches}")return coef, bias, w, bif __name__ == "__main__":coef, bias, w, b = train()print(f"真实系数: {coef}")print(f"预测系数: {w}")print(f"真实偏置: {bias}")print(f"预测偏置: {b}")

结果为:

Epoch: 0, Loss: 9141.109053354414
......
Epoch: 9, Loss: 2438.3174680679563
......
Epoch: 18, Loss: 643.4502219548301
......
Epoch: 31, Loss: 100.09944831000433
......
Epoch: 48, Loss: 9.588121845608665
......
Epoch: 64, Loss: 1.8927827449071974
......
Epoch: 119, Loss: 1.006377797278147
真实系数: tensor([41.2059, 66.4995, 10.7145, 60.1951, 25.9615])
预测系数: tensor([41.1517, 66.4983, 10.7523, 60.2103, 25.9089], requires_grad=True)
真实偏置: 14.5
预测偏置: 14.50900650024414

http://www.ppmy.cn/devtools/137571.html

相关文章

Elasticsearch对于大数据量(上亿量级)的聚合如何实现?

大家好,我是锋哥。今天分享关于【Elasticsearch对于大数据量(上亿量级)的聚合如何实现?】面试题。希望对大家有帮助; Elasticsearch对于大数据量(上亿量级)的聚合如何实现? 1000道 …

在 Ubuntu/Debian 上安装 Go

使用官方二进制文件安装(推荐) Go 提供了官方的二进制安装包,适用于大多数 Linux 发行版,包括 Ubuntu 和 Debian。步骤如下: 更新包索引: bash sudo apt update 安装依赖(如果尚未安装&#…

【LeetCode: 3206. 交替组 I + 模拟】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

Spring Boot 动态数据源切换

背景 随着互联网应用的快速发展,多数据源的需求日益增多。Spring Boot 以其简洁的配置和强大的功能,成为实现动态数据源切换的理想选择。本文将通过具体的配置和代码示例,详细介绍如何在 Spring Boot 应用中实现动态数据源切换,帮…

MATLAB中Simulink的基础知识

Simulink是MATLAB中的一种可视化仿真工具, 是一种基于MATLAB的框图设计环境,是实现动态系统建模、仿真和分析的一个软件包,被广泛应用于线性系统、非线性系统、数字控制及数字信号处理的建模和仿真中。 Simulink提供一个动态系统建模、仿真和…

《免费的学习网站推荐3》

《免费的学习网站推荐3》 综合教育类 国家教育资源公共服务平台:教育部主导的平台,汇聚了大量中小学教育资源,包括课件、教案、试题等,为教师教学和学生学习提供了丰富的素材.爱课程网:由高教社的“爱课程网”与网易…

Redis的几种持久化方式

Redis 提供了两种主要的持久化方式,它们分别是: 1. RDB(Redis Database Snapshotting) RDB 是 Redis 的一种数据持久化方式,它会在指定的时间间隔内对 Redis 中的数据进行快照并保存到硬盘上。 特点: 触…

设计模式之 备忘录模式

备忘录模式是一种行为型设计模式,它允许你在不暴露对象实现细节的情况下,捕获和保存对象的内部状态。之后,可以通过保存的状态将对象恢复到原先的状态。备忘录模式的核心思想是“在不暴露对象的内部实现的情况下,保存对象的状态&a…