实现功能:
1、数据回归:基于多输入单输出数据集
2、代码最后使用matplotlib绘制了 [训练次数-loss值] 折线图进行训练结果展示

注:

  1. 代码亲测可成功运行;
  2. 以下代码通过cuda调用GPU训练,如果cuda报错则需检查GPU训练环境配置,例如pytorch是否为GPU版本、cuda版本是否适配当前显卡驱动版本等。
  3. 数据集:
    本文已提供,名为“air_pollution.csv”。最后一列为label,其他列为输入
本文重点在于介绍算法,该数据集质量不算优质。
算法拟合能力没有问题,但基于此数据集可能存在非凸优化问题,结果有概率呈现局部最优状态,导致收敛效果差,所以读者下一阶段可以尝试学习一些能有效规避局部最优问题的算法。

步骤概述:

  1. 定义数据集类以处理CSV文件。
  2. 创建一个简单的BP神经网络模型。
  3. 定义训练循环,包括数据加载、前向传播、计算损失、反向传播和权重更新。

1 导入必要的库

import torch
from torch.utils.data import Dataset, DataLoader
import pandas as pd
import numpy as np
import torch.nn as nn
import torch.optim as optim

2 定义数据集读取模块

  • 此处使用pytorch提供的 Dataset 读取数据,并对输入数据做归一化处理
    其实pytorch在训练前,输入model.train( ),进入train模式后会自动进行Batch Normalization,个人认为此处的归一化有点重复,可以省略。
    参考:model.train() 和 model.eval() 原理与用法
  • __len__与__getitem__为python内置魔术方法,参考:python常用魔术方法
class CSVDataset(Dataset):
    def __init__(self, file_path):
        self.data = pd.read_csv(file_path)
        self.inputs = self.data.iloc[:, :-1].values  # 将除最后一列外的列的数据作为输入
        self.labels = self.data.iloc[:, -1].values  # 将最后一列作为label
        # 归一化
        self.mean = np.mean(self.inputs, axis=0)
        self.std = np.std(self.inputs, axis=0)
        self.inputs = (self.inputs - self.mean) / self.std

    def __len__(self):
        return len(self.data)

    def __getitem__(self, idx):
        inputs = torch.tensor(self.inputs[idx], dtype=torch.float32)
        labels = torch.tensor(self.labels[idx], dtype=torch.float32)
        return inputs, labels

3 定义BP神经网络模型

这个BP网络模型结构较为简单,特征提取能力较弱,仅作示范。

class BPNeuralNetwork(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(BPNeuralNetwork, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(hidden_size, output_size)

    def forward(self, x):
        out = self.fc1(x)
        out = self.relu(out)
        out = self.fc2(out)
        out = torch.squeeze(out, dim=1)  # 压缩一个维度,从torch([6, 1])压缩到torch([6]),使其与label的维度对应
        return out

4 功能组件定义与模型训练

4.1 读取数据

此处基于Dataset读取数据后,基于Dataloader将数据划分为多个Batch

dataset = CSVDataset('data.csv')
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
4.2 设置设备、定义模型、损失函数和优化器
  • device的含义:在可用的情况下,调用GPU训练
  • 使用了MSE函数计算Loss,并使用Adam优化器进行优化
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

input_size = dataset.inputs.shape[1]
hidden_size = 64  # 可以根据需要调整
output_size = 1  # 假设是一个回归任务

model = BPNeuralNetwork(input_size, hidden_size, output_size)
model.to(device)

loss_function = nn.MSELoss()  # 损失函数
optimizer = optim.Adam(model.parameters(), lr=0.001)  # 优化器

6 训练并保存模型

6.1 训练模型
  • 通过修改num_epochs的数值改变训练的迭代次数
  • 可使用一个list保存每个回合的Loss值,以绘制Loss曲线图像,此处不做赘述。
num_epochs = 20
for epoch in range(num_epochs):
    model.train()
    for inputs, labels in dataloader:
        inputs, labels = inputs.to(device), labels.to(device)

        optimizer.zero_grad()
        outputs = model(inputs)
        loss = loss_function(outputs, labels)
        loss.backward()
        optimizer.step()

    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
6.2 保存模型

等模型跑完所有回合后,即可保存模型。
“BP.pt” 即为保存的模型文件
.pt 为包含所有参数的模型类型,若只想保存权重参数,则改为:“BP.pth

torch.save(model, 'BP.pt')

7 使用训练好的模型

input可以是数据集数组的按行切片

import torch

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
mdoel = torch.load('BP.pt', map_location=lambda storage, loc: storage.cuda(0))

inp = [150,207,69,106,2.01,28]
input = torch.tensor(inp, dtype=torch.float).to(device)
out1 = mdoel(input)
print(out1)

欢迎评论区讨论或提出错误和改进,我们一起进步!
#向全国科技者致敬—为创新和未来而努力#

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐