新冠病毒感染人数预测项目

张开发
2026/5/6 1:10:47 15 分钟阅读
新冠病毒感染人数预测项目
问题描述如下一.导入库import torch #张量相关操作 import matplotlib.pyplot as plt #画图的 import numpy as np #矩阵相关操作 import random #生成随机数 import csv #处理csv文件 import pandas #处理csv文件更高级 from torch.utils.data import Dataset,DataLoader #继承类 import torch.nn as nn from torch import optim #optim 优化依次导入张量画图矩阵随机数处理csv文件继承类优化器等库二.数据模块以下为数据模块的通用抽象模板它是自定义数据集的灵魂框架继承类Dataset必须实现__init__、__getitem__、__len__三个方法它们分工明确、缺一不可。1.__init__初始化与数据加载作用在创建数据集实例时一次性完成准备工作读取文件路径、加载数据到内存如 CSV / 图片路径列表保存特征、标签或样本索引做全局预处理如归一化参数计算class CovidDataset(Dataset): #类CovidDataset继承类Dataset def __init__(self,file_path,mode): #类的初始化需要传入数据文件路径file_path和数据类型mode with open(file_path,r) as f: #打开数据文件只读 readercsv.reader(f) #将文件f中数据读出来并赋值给变量reader ori_datalist(reader) #将文件数据转化为列表并赋值给变量ori_data(原始数据 csv_datanp.array(ori_data)[1:,1:].astype(float) #将原始数据ori_data转换为矩阵浮点型不要第一行和第一列 #接下来要根据处理后的数据csv_data来制造出我们需要的X,Y。但是要区分数据类型 Training,Valiation,Testing #假设Valiation数据对Training数据逢5取1 if modetrain: indices[i for i in range(len(csv_data)) if i % 5 ! 0] elif modeval: indices [i for i in range(len(csv_data)) if i % 5 0] #Testing数据必须得按顺序来取 elif modetest: indices[i for i in range(len(csv_data))] Xtorch.tensor(csv_data[indices,:93]) #如果数据类型为Training和Valiation有Y如果数据类型为Testing则没有Y if mode!test self.Ytorch.tensor(csv_data[indices,-1]) #标准化,排除量纲不同的影响 self.X(X-X.mean(dim0,keepdimTrue))/X.std(dim0,keepdimTrue) #标准化方式 self.modemode2.__getitem__取单个样本核心作用根据索引item返回一个样本特征 标签是DataLoader批量打包的基础DataLoader会多次调用__getitem__把多个样本拼成一个 batch可在这一步做实时预处理如图片 resize、文本分词、数据增强def __getitem__(self, item): #item指的是索引根据索引 item 返回一个样本特征 标签 if self.modetest: return self.X[item].float() #数据类型为Testing时返回x else: return self.X[item].float(),self.Y[item].float() #数据类型为Training或Valiation时返回x和y3.__len__返回数据集大小作用告诉 PyTorch 这个数据集有多少个样本决定了for循环遍历的次数是DataLoader计算「总批次数」的依据def __len__(self): return len(self.X) #返回数据集大小三.模型模块以下为模型模块的通用抽象模板它是自定义模型的标准框架继承nn.Module必须实现__init__和forward两个方法是构建神经网络的核心约定。1.__init__定义模型结构与可学习参数作用在模型初始化时定义所有可学习的层和参数需要传入输入数据的维度定义线性层nn.Linear、卷积层nn.Conv2d、激活函数nn.ReLU等这些层会自动维护可训练参数权重w、偏置b后续可被优化器更新必须调用super().__init__()来初始化父类nn.Moduleclass myModel(nn.Module): # myModel继承自nn.Model #在模型初始化时定义所有可学习的层和参数,需要传入输入数据的维度 def __init__(self,inDim): super(myModel,self).__init__() #必须调用 super().__init__() 来初始化父类 nn.Module self.fc1nn.Linear(inDim,128) #定义linear1inDim128 self.relu1nn.ReLU() #定义第1层的激活函数ReLU self.fc2nn.Linear(128,1) #定义Linear212812.forward定义前向传播逻辑作用描述「数据如何流经模型」是模型的核心计算逻辑接收输入x依次通过各层运算最终输出预测值不要直接调用forward(x)而是用model(x)触发def forward(self,x): #需要传入数据x xself.fc1(x) xself.relu1(x) xself.fc2(x) #通过模型计算出估计y if len(x.size())1: xx.squeeze(1) #如果估计y维度大于1就去掉第2个维度 return x四.超参量模块定义除模型中内部参数以外的超参数。一般包括学习率优化器优化算法损失函数等。是监控模型效果、调整超参数的环节绝不更新模型参数1.输入传入各阶段所需数据##传入各阶段所需数据## #传入相关文件路径 train_file rD:\桌面\课程代码\第三节回归实战代码\regression\covid\covid.train.csv test_file rD:\桌面\课程代码\第三节回归实战代码\regression\covid\covid.test.csv save_file rD:\桌面\课程代码\第三节回归实战代\regression\covid\model_save\best_model.pth rel_file rD:\桌面\课程代码\第三节回归实战代码\regression\covid\pred.csv #确定批次数据个数构建本批次所需数据 batch_size16 #每批次取16个数据 train_setCovidDataset(train_file,train) #传入训练数据文件train_file并构建CovidDataset类的实例train_set即构建出Training数据集 val_setCovidDataset(train_file,val) #传入训练数据文件train_file并构建CovidDataset类的实例val_set即构建出Valiation数据集 test_setCovidDataset(test_file,test) #传入测试数据文件test_file并构建CovidDataset类的实例test_set即构建出Test数据集 train_loaderDataLoader(train_set,batch_sizebatch_size,shuffleTrue) #传入Training数据集批次大小并进行乱序排列。获取每批次的Training数据 val_loaderDataLoader(val_set,batch_sizebatch_size,shuffleTrue) #传入Valiation数据集批次大小并进行乱序排列。获取每批次的Valiation数据 test_loaderDataLoader(test_set,batch_size1,shuffleFalse) #传入Testing数据集批次大小为1并进行顺序排列。获取每批次的Testing数据2.定义超参定义各种超参Loss函数运行轮次epochs学习率lr运行设备数据输入维度优化器optimizer并导入模型##定义各种超参## lossnn.MSELoss()#定义Loss函数 epochs20 #运行轮次 lr0.001 #学习率 devicecudaif torch.cuda.is_available() else cpu #确定运行设备 print(device) #打印运行设备 data_dim93 #确定输入数据维度 modelmyModel(data_dim).to(device) #导入模型 optimizeroptim.SGD(paramsmodel.parameters(),lrlr,momentum0.9) #设置优化器优化器SGD随机梯度下降w权重η学习率∇L损失Loss对w的梯度SGD Momentum动量 SGD累积之前的梯度方向像小球下坡一样积累速度减少震荡加速收敛。式1.先更新速度2.再用速度去更新权重γ动量系数一般 0.9v速度梯度累积动量 SGD 在 SGD 基础上引入速度项累积历史梯度方向形成惯性减少梯度震荡加速收敛更容易冲出局部最优。五.训练流程1.配置与初始化设备指定将模型迁移到 GPU如果有或 CPU 上运行。监控指标初始化列表plt_train_loss用于记录训练损失初始化列表plt_val_loss用于记录验证损失min_val_loss初始化一个很大的值用于后续保存最优模型。def train_val(model,train_loader,val_loader,lr,optimizer,device,epochs,save_file): #传入模型训练数据验证数据学习率优化器设备轮次,保存路径 modelmodel.to(device) #把模型放入设备上 plt_train_loss[] #记录训练过程中的loss初始为空列表 plt_val_loss[] #记录验证过程中的loss初始为空列表 min_val_loss9999999999.9 #初始化最小val_loss值2.训练轮次循环Epoch代码执行epochs次完整的数据集遍历。3.训练阶段Train Phase模式切换model.train()启用训练模式启用 Dropout、BatchNorm 等训练特有层。批量迭代遍历train_loader逐个 Batch 计算前向传播model(x)得到预测值y_pred。计算损失对比y_pred与真实标签y。反向传播backward()计算梯度。参数更新optimizer.step()更新参数。损失统计计算一个 Epoch 内的平均损失并记录。for epoch in range(epochs): #发枪指令冲锋的号角模型训练的开始 #训练过程 model.train() #模型转换成train模式 start_timetime.time() train_loss0.0 #浮点形式 for x,y in train_loader: #从训练集中读取数据xy x,yx.to(device),y.to(device) #将数据放入设备上 y_predmodel(x) #x通过模型得到预测值 bat_lossloss(y_pred,y) #预测值和真实值求这一批的loss即bat_loss bat_loss.backward() #梯度回传 optimizer.step() #优化器进行工作 optimizer.zero_grad() #梯度清零 train_lossbat_loss.cpu().item() #计算该批次的loss mean_train_losstrain_loss/train_loader.__len__() #计算该批loss的平均值 plt_train_loss.append(mean_train_loss) #可视化4.验证阶段Val Phase模式切换model.eval()启用验证模式固定 Dropout、BatchNorm。批量迭代遍历 val_loader逐个 Batch 计算前向传播model(x)得到预测值y_pred。计算损失对比y_pred与真实标签y。损失统计计算一个 Epoch 内的平均损失并记录。#验证过程 model.eval() # 模型转换成trval模式 val_loss 0.0 # 浮点形式 with torch.no_grad(): #验证集要经过模型但要求不计算梯度 for val_x, val_y in val_loader: # 从训练集中读取数据xy val_x, val_y val_x.to(device), val_y.to(device) # 将数据放入设备上 val_y_pred model(val_x) # x通过模型得到预测值 val_bat_loss loss(val_y_pred, val_y) # 预测值和真实值求loss val_loss val_bat_loss.cpu().item() plt_val_loss.append(val_loss / val_loader.__len__())5.模型保存min_val_loss是 “最优模型判定标准”只有验证集损失最低的模型才会被保存而非训练最后一轮的模型。训练后期模型会对训练集过拟合训练损失下降但验证损失上升保存 “验证损失最低” 的模型本质是选择泛化能力最强的版本这是工业界 / 科研中最常用的 “早停” 变体。#保存。因为模型并非越训越好因此要保存最好的模型 if val_loss min_val_loss: min_val_lossval_loss torch.save(model,save_file)6.可视化print([%03d/%03d]%2.2f sec(s) train_loss:%.6f val_loss:%.6f % \ (epoch,epochs,time.time()-start_time,plt_train_loss[-1],plt_val_loss[-1])) plt.plot(plt_train_loss) plt.plot(plt_val_loss) plt.title(loss) plt.legend([train,val]) plt.show()7.调用函数运行train_val(model,train_loader,val_loader,lr,optimizer,device,epochs,save_file)六.训练结果如下

更多文章