当前位置: 首页 > news >正文

DL 2 自动微分模块

自动微分模块

1. 自动微分模块=对损失函数求导,结合反向传播,更新权重参数w,b

pytorch不支持向量张量对向量张量的求导,只支持标量张量对向量张量的求导
import torch# 定义参数,requires_grad默认为false
w = torch.tensor(10, requires_grad=True, dtype=torch.float32)# 定义损失函数
loss = w ** 2 + 20
print(f'梯度函数类型:{type(loss.grad_fn)}')
print(f'权重初始值w:{w}, loss:{loss}')for i in range(0, 10):# 计算损失loss = w ** 2 + 20# 梯度清零 w.grad.zero_(), 默认梯度会累加# 至此(第一次的时候),还没有计算梯度, 所以w.grad = Node,要做非空判断if w.grad is not None:w.grad.zero_()# 反向传播,计算梯度,梯度 = 损失函数的倒数,计算完毕后,会记录到w.grad属性中# loss是一个标量,若非标量可通过loss.sum().backward()来保证loss是1个标量loss.backward()  # 更新参数# .data 返回一个与原始张量共享相同数据存储的新张量,但不共享计算历史和梯度信息。# w.data = w.data - w.grad * 0.01# 不推荐使用data,推荐使用以下# 注意:w = w - 0.01 * w.grad 错误,因为当你执行 w = w - 0.01 * w.grad 时,# 实际上创建了一个新的张量,这个新张量不再需要梯度(因为在 torch.no_grad() 上下文中创建),所以后续的循环迭代中无法计算梯度。with torch.no_grad():w -= 0.01 * w.grad # 使用 -= 进行原地更新print(f'第{i}次,更新后的权重w:{w}, loss:{loss}')

2.detach()

若张量允许自动微分则不能转换为numpy,需要使用detach拷贝一份
另外,detach后与原变量共享同一块空间

import torch
import numpy as npt1 = torch.tensor([10, 20], requires_grad=True, dtype=torch.float)
print(f't1:{t1}, type:{type(t1)}') # t1:tensor([10., 20.], requires_grad=True), type:<class 'torch.Tensor'># 通过 detach(),拷贝一份张量,然后转换
# t2 = t1.detach().numpy()
# 注意: t1 和 t2 和 t3 共享同一块空间
t2 = t1.detach()
t3 = t2.numpy()
# 测试 共享同一块空间
t1.data[0] = 1
print(f't1:{t1}, type:{type(t1)}') # t1:tensor([ 1., 20.], requires_grad=True), type:<class 'torch.Tensor'>
print(f't2:{t2}, type:{type(t2)}') # t2:tensor([ 1., 20.]), type:<class 'torch.Tensor'>
print(f't3:{t3}, type:{type(t3)}') # t3:[ 1. 20.], type:<class 'numpy.ndarray'>
#测试 detach
print(f't1:{t1.requires_grad}') # True
print(f't2:{t2.requires_grad}') # False

3. PyTorch构建线性回归模型

import torch
from torch.utils.data import TensorDataset  # 创建x和y张量数据集对象
from torch.utils.data import DataLoader  # 创建数据集加载器
import torch.nn as nn  # 损失函数和回归函数
from torch.optim import SGD  # 随机梯度下降函数, 取一个训练样本算梯度值
from sklearn.datasets import make_regression  # 创建随机样本, 工作中不使用
import matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号# 1-创建线性回归样本 x y coef(w) b
# numpy对象 ->张量Tensor ->数据集对象TensorDataset ->数据加载器DataLoader
def create_datasets():x, y, coef = make_regression(n_samples=100,  # 样本数n_features=1,  # 特征数noise=10,  # 标准差, 噪声, 样本离散程度coef=True,  # 返回系数, wbias=14.5,  # 截距 brandom_state=0)# 将数组转换成张量x = torch.tensor(data=x)y = torch.tensor(data=y)# print('x->', x)# print('y->', y)# print('coef->', coef)return x, y, coef# 2-模型训练
def train(x, y, coef):# 创建张量数据集对象datasets = TensorDataset(x, y)print('datasets->', datasets)# 创建数据加载器对象# dataset: 张量数据集对象# batch_size: 每个batch的样本数# shuffle: 是否打乱样本dataloader = DataLoader(dataset=datasets, batch_size=16, shuffle=True)print('dataloader->', dataloader)# for batch in dataloader:  # 每次遍历取每个batch样本# 	print('batch->', batch)  # [x张量对象, y张量对象]# 	break# 创建初始回归模型对象, 随机生成w和b, 元素类型为float32# in_features: 输入特征数 1个# out_features: 输出特征数 1个model = nn.Linear(in_features=1, out_features=1)print('model->', model)# 获取模型对象的w和b参数print('model.weight->', model.weight)print('model.bias->', model.bias)print('model.parameters()->', list(model.parameters()))# 创建损失函数对象, 计算损失值criterion = nn.MSELoss()# 创建SGD优化器对象, 更新w和boptimizer = SGD(params=model.parameters(), lr=0.01)# 定义变量, 接收训练次数, 损失值, 训练样本数epochs = 100loss_list = []  # 存储每次训练的平均损失值total_loss = 0.0train_samples = 0for epoch in range(epochs):  # 训练100次# 借助循环实现 mini-batch SGD 模型训练for train_x, train_y in dataloader:# 模型预测# train_x->float64# w->float32y_pred = model(train_x.type(dtype=torch.float32))  # y=w*x+bprint('y_pred->', y_pred)# 计算损失值, 调用损失函数对象# print('train_y->', train_y)# y_pred: 二维张量# train_y: 一维张量, 修改成二维张量, n行1列# 可能发生报错, 修改形状# 修改train_y元素类型, 和y_pred类型一致, 否则发生报错loss = criterion(y_pred, train_y.reshape(shape=(-1, 1)).type(dtype=torch.float32))print('loss->', loss)# 获取loss标量张量的数值 item()# 统计n次batch的总MSE值total_loss += loss.item()# 统计batch次数train_samples += 1# 梯度清零optimizer.zero_grad()# 计算梯度值loss.backward()# 梯度更新 w和b更新# step()等同 w=w-lr*gradoptimizer.step()# 每次训练的平均损失值保存到loss列表中loss_list.append(total_loss / train_samples)print('每次训练的平均损失值->', total_loss / train_samples)print('loss_list->', loss_list)print('w->', model.weight)print('b->', model.bias)# 绘制每次训练损失值曲线变化图plt.plot(range(epochs), loss_list)plt.title('损失值曲线变化图')plt.grid()plt.show()# 绘制预测值和真实值对比图# 绘制样本点分布plt.scatter(x, y)# 获取1000个样本点# x = torch.linspace(start=x.min(), end=x.max(), steps=1000)# 计算训练模型的预测值y1 = torch.tensor(data=[v * model.weight + model.bias for v in x])# 计算真实值y2 = torch.tensor(data=[v * coef + 14.5 for v in x])plt.plot(x, y1, label='训练')plt.plot(x, y2, label='真实')plt.legend()plt.grid()plt.show()x, y, coef = create_datasets()
train(x, y, coef)
http://www.gsyq.cn/news/53528.html

相关文章:

  • 《计算机网络》学习心得
  • 2025防晒品牌TOP8精准推荐:按肤质与场景科学选择
  • 黑马程序员SpringCloud微服务开发与实战- Docker基础-02
  • 老友记第一季人物表
  • make指定安装目录
  • 【转载】银河麒麟(Kylin)操作系统上移植Qt 5.6.3与QtCreator 4.2.0的完整指南
  • wsl 与 docker相关内容
  • 2025.11.18模拟赛
  • 游戏联运模式与统一包模式
  • 日总结 28
  • 实用指南:AI: 生成Android自我学习路线规划与实战
  • 《算法设计与分析》第三章学习记录
  • #题解#洛谷 P3029 Cow Lineup S #双指针#离散化#
  • 如何创建你的百Google度!!(实现双搜索引擎页面)
  • P7152 [USACO20DEC] Bovine Genetics G
  • CF1592E Bored Bakry
  • 如何在ISA-95体系中采用Apache Camel + MQTT Broker衔接L3与L4 Legacy应用
  • 11月18日日记
  • 一文讲清:数据清洗、数据中台、数据仓库、数据治理 - 智慧园区
  • 人工智能之编程进阶 Python高级:第四章 数学类模块
  • Solon AI 开发学习 - 1导引
  • 2025 年 11 月滚珠丝杆厂家推荐排行榜,高负载滚珠丝杆,耐磨滚珠丝杆,检测仪器高速滚珠丝杆,螺母滚珠丝杆,医用自动化滚珠丝杆公司推荐
  • UE4/UE5反射系统动态注册机制解析 - 实践
  • 做题随笔:P3403
  • 《从纪律委员到AI元人文开放者》
  • 「Solution」AGC008F Black Radius
  • 人工智能之编程进阶 Python高级:第二章 面向对象
  • OI vs Group Theory, Do You Guys Know?
  • 2025年11月穿戴式吸奶器,电动吸奶器,百元吸奶器品牌测评排名,高性价比选购指南!
  • 2025年11月百元吸奶器,静音吸奶器,便携吸奶器品牌测评排名,高性价比选购指南!