欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > PyTorch基础4

PyTorch基础4

2025/2/21 3:22:48 来源:https://blog.csdn.net/adc_abc123/article/details/144038630  浏览:    关键词:PyTorch基础4

目录

1.手动构建模型实战

1.0 模型训练基础概念

1.1 数据处理

1.1.1 构建数据集

1.1.2 构建数据加载器

1.2 模型函数

1.3 损失函数

1.4 优化器

1.5 参数初始化

1.6 训练函数

1.7 完整代码

2.模型定义组件

2.1 基本组件认知

2.1.1 损失函数组件

2.1.2 线性层组件

2.1.3 优化器方法

2.2 数据加载器

2.2.1 构建数据类

2.2.2 数据加载器

2.3 数据集加载案例

2.3.1 加载Excel数据集

2.3.2 加载图片数据集


1.手动构建模型实战

1.0 模型训练基础概念

名词定义
Epoch使用训练集的全部数据对模型进行一次完整训练,被称为“一代训练”
Batch使用训练集中的一小部分样本对模型权重进行一次反向传播的参数更新,这一小部分样本被称为“一批数据”
Iteration使用一个Batch数据对模型进行一次参数更新的过程,被称为“一次训练”

1.1 数据处理

1.1.1 构建数据集

# 构建数据集
def 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, 5)bias = 14.5x, y, coef = make_regression(n_samples=1000,n_features=5,bias=14.5,noise=noise,coef=True,random_state=666)# 将数据转换为张量x = torch.tensor(x, dtype=torch.float32)y = torch.tensor(y, dtype=torch.float32)coef = torch.tensor(coef, dtype=torch.float32)return x, y, coef, bias

1.1.2 构建数据加载器

数据需要分批次加载到模型进行训练

def 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

1.2 模型函数

'''
构建模型:权重参数和偏置参数
'''def linear_regression(x, w, b):return torch.matmul(x, w) + b

1.3 损失函数

# 构建模型函数:损失函数和优化器
def mean_squared_error(y_pred, y_true):return torch.mean((y_pred - y_true) ** 2)

1.4 优化器

使用梯度下降对参数进行调整。

# 优化器: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

1.5 参数初始化

# 初始化参数
def initialize_params(n_features):# 随机初始化权重w,将偏置初始化为:0w = torch.randn(n_features, requires_grad=True, dtype=torch.float32)b = torch.tensor(0.0, requires_grad=True, dtype=torch.float32)return w, b

1.6 训练函数

训练函数完成对数据的训练和参数调整等。

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 epochs in range(epochs):epochs_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)# 梯度清零if w.grad is not None:w.grad.data.zero_()if b.grad is not None:b.grad.data.zero_()# 反向传播loss.backward()# 更新参数w, b = sgd(w, b, w.grad, b.grad, learning_rate, batch_size)# 训练批次及损失率epochs_loss += loss.item()print(f'Epoch:{epochs},Loss:{epochs_loss / num_batches}')return coef, bias, w, b

1.7 完整代码

import math
import random
import torch
import numpy as np
from sklearn.datasets import make_regression
import pandas as pd# 构建数据集
def build_dataset():noise = random.randint(1, 5)bias = 14.5x, y, coef = make_regression(n_samples=1000,n_features=5,bias=14.5,noise=noise,coef=True,random_state=666)# 将数据转换为张量x = torch.tensor(x, dtype=torch.float32)y = torch.tensor(y, dtype=torch.float32)coef = torch.tensor(coef, 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,将偏置初始化为:0w = torch.randn(n_features, requires_grad=True, dtype=torch.float32)b = torch.tensor(0.0, requires_grad=True, dtype=torch.float32)return w, b# ??
def 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, bdef 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 epochs in range(epochs):epochs_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)# 梯度清零if w.grad is not None:w.grad.data.zero_()if b.grad is not None:b.grad.data.zero_()# 反向传播loss.backward()# 更新参数w, b = sgd(w, b, w.grad, b.grad, learning_rate, batch_size)# 训练批次及损失率epochs_loss += loss.item()print(f'Epoch:{epochs},Loss:{epochs_loss / num_batches}')return coef, bias, w, bif __name__ == '__main__':coef, bias, w, b = train()print('真实系数:', coef)print('预测系数:', w)print('真实偏置:', bias)print('预测偏置:', b)

2.模型定义组件

模型(神经网络,深度神经网络,深度学习)定义组件帮助我们在 PyTorch 中定义、训练和评估模型等。

2.1 基本组件认知

官方文档:torch.nn — PyTorch 2.5 documentation

2.1.1 损失函数组件

PyTorch已内置多种损失函数

import torch.nn as nn
import torchcriterion = nn.MSELoss()
y_true =  torch.randn(5,3,)
y_pred = torch.randn(5,3,requires_grad=True)
print(y_true)
print(criterion(y_true,y_pred))

2.1.2 线性层组件

构建一个简单的线性层,后续还有卷积层、池化层、激活、归一化等需要学习和使用。

model = nn.Linear(in_features=20,out_features=60)
input = torch.randn(128,20)
output = model(input)
print(output.size())

2.1.3 优化器方法

官方文档:torch.optim — PyTorch 2.5 documentation

这里牵涉到的API有:

import torch.optim as optim

  • params=model.parameters():模型参数获取;

  • optimizer=optim.SGD(params):优化器方法;

  • optimizer.zero_grad():梯度清零;

  • optimizer.step():参数更新;

import torch.optim as optim#  构建数据集
input_x = torch.randint(1,10,(400,5)).type(torch.float32)
target  = torch.randint(1,10,(400,1)).type(torch.float32)
# 线性层模型
model = nn.Linear(5,1)
# 优化器对象
sgd = optim.SGD(model.parameters(),lr=0.01)
# 预测
y_pred= model(input_x)
# 损失函数
loss_fn = nn.MSELoss()
loss = loss_fn(y_pred,target)
print(loss)
# 梯度清零
sgd.zero_grad()
# 反向传播
loss.backward()
# 梯度更新
sgd.step()

2.2 数据加载器

数据集加载器2个步骤。

2.2.1 构建数据类

在 PyTorch 中,构建自定义数据加载类通常需要继承 torch.utils.data.Dataset 并实现以下几个方法:

  • __init__ 方法 用于初始化数据集对象:通常在这里加载数据,或者定义如何从存储中获取数据的路径和方法。

    def __init__(self, data, labels):self.data = dataself.labels = labels
  • __len__ 方法 返回样本数量:需要实现,以便 Dataloader加载器能够知道数据集的大小。

    def __len__(self):return len(self.data)
  • __getitem__ 方法 根据索引返回样本:将从数据集中提取一个样本,并可能对样本进行预处理或变换。

    def __getitem__(self, index):sample = self.data[index]label = self.labels[index]return sample, label

    如果你需要进行更多的预处理或数据变换,可以在 __getitem__ 方法中添加额外的逻辑。

import torch
from torch.utils.data import Dataset,DataLoader
class CustomDataset(Dataset):def __init__(self,data,labels):self.data = dataself.labels =labelsself.len = len(self.data)def __len__(self):return self.lendef __getitem__(self,index):# 确保取值:# 若index小于数据集的最小索引,取第一个值# 若index大于数据集的最大索引,取最后一个值# 若index在数据集的索引范围内,取index索引的值index = min(max(index,0),self.len-1)sample = self.data[index]label = self.labels[index]return sample,labeldata_x=torch.randn(size=(666,20),requires_grad =True,dtype=torch.float32)
data_y = torch.randn((data_x.shape[0],1),dtype=torch.float32)
dataset = CustomDataset(data_x,data_y)
print(dataset[0])

2.2.2 数据加载器

在训练或者验证的时候,需要用到数据加载器批量的加载样本。

import torch
from torch.utils.data import Dataset,DataLoader
class CustomDataset(Dataset):def __init__(self,data,labels):self.data = dataself.labels =labelsself.len = len(self.data)def __len__(self):return self.lendef __getitem__(self,index):# 确保取值:# 若index小于数据集的最小索引,取第一个值# 若index大于数据集的最大索引,取最后一个值# 若index在数据集的索引范围内,取index索引的值index = min(max(index,0),self.len-1)sample = self.data[index]label = self.labels[index]return sample,labeldata_x=torch.randn(size=(666,20),requires_grad =True,dtype=torch.float32)
data_y = torch.randn((data_x.shape[0],1),dtype=torch.float32)
dataset = CustomDataset(data_x,data_y)
print(dataset[0])

2.3 数据集加载案例

通过一些数据集的加载案例,真正了解数据类及数据加载器。

2.3.1 加载Excel数据集

import torch
from torch.utils.data import Dataset,DataLoader
import pandas as pdclass ExcelDataset(Dataset):def __init__(self,file_path):super(ExcelDataset,self).__init__()data1  =pd.read_excel(file_path)# 删除全是NAN的列data1 = data1.dropna(axis=1,how='all')df = pd.DataFrame(data1)df.columns = ["zubie","student_id","name","expression","ppt","answer","present","defense","comments",]df = df.drop(["zubie","student_id", "name", "comments"],axis=1)# 转换为tensordata = torch.tensor(df.values)self.data =data[:,:-1]self.target  =data[:,-1]self.len =len(self.data)def __len__(self):return self.lendef __getitem__(self,index):index =min(max(index,0),self.len-1)   return self.data[index],self.target[index]excel_path = './test.xlsx'
dataset = ExcelDataset(excel_path)
loader = DataLoader(dataset,batch_size = 4,shuffle =True)for i,(data,target) in enumerate(loader):print(i,data,target)

2.3.2 加载图片数据集

import torch 
from torch.utils.data import Dataset,DataLoader
import os 
import cv2class ImageDataset(Dataset):def __init__(self,folder):self.img_size =(224,224)# 存储路径self.imgs_path_list = []#把类别存储下来self.target = []#把目录存储下来dir_names = []for root,dirs,files in os.walk(folder):if len(dirs)>0:dir_names = dirsprint(dir_names)else:for file in files:file_path = os.path.join(root,file)self.imgs_path_list.append(file_path)# 使用系统路径分隔符对路径经行分割class_name = os.path.split(root)[-1]# 将类别转换为数字class_id = dir_names.index(class_name)self.target.append(class_id)self.len = len(self.imgs_path_list)def __len__(self):return self.lendef __getitem__(self,index):idx = min(max(index,0),self.len-1)file_path = self.imgs_path_list[idx]# 读取文件内容img = cv2.imread(file_path)# 统一图片大小img = cv2.resize(img,self.img_size)# 转换成tensorimg_tensor = torch.from_numpy(img)# 从HWC转换为CHWimg_tensor = img_tensor.permute(2,0,1)# 获取标签target  =self.target[idx]return img_tensor,targetdataset = ImageDataset('.')
loader = DataLoader(dataset,batch_size=4,shuffle=True)
for i,(data,target) in enumerate(loader):print(i,data.shape,target)if i >5:break

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词