2021作业1


根据美国一项COVID-19的调查40个州,4种COVID可能的症状,8个日常的行为,5个心里方面的状况,和是否呈阳性。现在有连续三天的调查资料作为训练资料,测试资料为根据前两天的资料预测第三天的阳性情况。

训练资料如图:

在这里插入图片描述

测试资料:缺第三天的阳性情况,需要进行预测

在这里插入图片描述

1.构建神经网络

# 导入torch神经网络工具包
import torch
import torch.nn as nn
# 构建一个简单神经网络
# torch.nn.Sequential是一个Sequential容器,模块将按照构造函数中传递的顺序添加到模块中。
def myModel(input_dim):
  model=nn.Sequential(
    nn.Linear(input_features=input_dim,output_features=64),
    nn.Relu(),
    nn.Linear(input_features=64,out_features=1)
  )

这样就构建了一个三层的神经网络,其中的64是依据经验设定,第一层为线性层,根据模型的输入特征值,输出64个特征值,第二层为普通的激活函数层,第三层为线性层,输入64个特征值,输出为1,这里指输出为第三天的阳性情况,因此必须是1个特征。

2神经网络的输入

pytorch数据读取的核心是torch.utils.data.DataLoader类。即如果使用pytorch构建神经网络时,那么DNN中传入的数据类型就是DataLoader类。

from torch.utils.data import Dataloader
import torch.utils.data as data
def pre_Dataloader():
  dataloader=Dataloader(
        dataset=dataset, batch_size=batch_size,
        shuffle=(mode == 'train'), drop_last=False,
        num_workers=0, pin_memory=True)
# 这里直接输入表格内的数据是有问题的因此,需要先构建一个数据预处理方法使其能够满足于dataloader的数据输入,因此需要继承dataset作为父类,才能输入到dataloader中
# 在训练集和测试集的数据略有不同,因此加一个mode,使下面方法同时都适用
# 字典型数据集是指实现了__getitem__()和__len__()协议,表示从索引到数据样本的映射。
# 需要初始化三个协议
class COVID19Dataset(data.Dataset):
  def __int__(self):
    # 用于初始化数据
    data=xxx
    self.data=torch.FloatTensor(data)
  def __getitem__(self, index):
    # 用于字典型的数据实现,根据标签返回数值
    return self.data[index],self.target[index]
  def __len__():
    return len(self.data)

具体操作如下:

import torch.utils.data as data
import csv

class COVID19Dataset(data.dataset):
  def __init__(self,path,mode='train',):
    self.mode= mode
    with open(path,'r') as fp:
      data=list(csv.read(fp)):
      # 去掉行标题
      data=np.array(data[1:])
      # 转换为浮点型
      data=data.astype(float)
      if mode=='test':
        data=data[:,list(range(93))]
        self.data=torch.FloatTensor(data)
      else:
        data=data[:,list(range(93))]
        target=data[:,-1]
        # 将训练数据分为train data 和Validation data
        # 此次分割数据是每十个数据的前9个为训练集,一个验证集进行分割
        indices = []
        if mode == 'train':
            for i in range(len(data)):
                if i % 10 != 0:
                    indices.append(i)
        elif mode == 'validation':
            for i in range(len(data)):
                if i % 10 == 0:
                    indices.append(i)
        self.data=torch.FloatTensor(data[indices])
        self.target=torch.FloatTensor(data[indices])

3.进行训练

1.准备一组含有未知参数的公式y=f_θ (x),即上文所构建的DNN网络。2.将数据带入函数中计算得到预测结果y,且已知正确的结果是y^^。3此时需要一个量来评价预测结果和正确结果之间的差值,即损失函数。损失函数越小表明,预测值和真实值之间差异越小。4.为使得损失函数最小,需要不断更新参数θ的值,此时即需要一个优化函数对参数进行更新,使得损失函数的值最小。最终经过反复迭代,得到一个相对合适的θ值,即完成网络的训练。
因此,在训练之前需要定义一些参数:
定义损失函数

loss=nn.MSELoss()

定义优化函数

optimizer=torch.optim.SGD()

定义迭代次数,以及记录迭代时的loss和accuracy的值的变换,并设定迭代停止条件

epoch=0
n_epochs=1000
min_mse=1000

构造训练器

def train(DNN_model,trainingDataloader, validationDataloader):
      # 初始化迭代次数
    epoch = 0
    # 初始化模型
    this_model = DNN_model
    # 最大迭代次数
    n_epochs = config['n_epochs']
    # 定义损失函数
    loss = nn.MSELoss(reduction='mean')
    # 定义优化器
    optimizer = torch.optim.SGD(params=this_model.parameters(), lr=0.001, momentum=0.9)
    # 记录loss值
    loss_record = {'train': [], 'val': []}
    min_mse = 1000
    while epoch<n_epochs:
      this_model.train()  # 这句表示开始训练,并无实际影响
      for x,y in trainingDataloader:
        pred=this_model(x).squeeze(1)
        mse_Loss=loss(pred, y)
        optimizer.zero_grad()
        mse_loss.backward()
        optimizer.step()
        loss_record['train'].append(mse_loss.detach().item())
    # 评估模型
    this_model.eval()
    total_loss = 0
    # 禁用掉参数更新
    with torch.no_grad():
      for x,y in validationDataloader:
        pred=this_model(x).squeeze(1)
        mse_Loss=loss(pred, y)
        #这里的loss是一个minBatch的平均值,因此要乘以x的长度计算出一个batch里的总值
        total_loss+=mse_loss.detach.item()*len(x)
      # 计算平均loss
      total_loss=total_loss/len(validationDataloader.dataset)
    # 完成一个迭代
    # 当平均loss更小时,保存此时的模型参数
    early_stop_cnt = 0
    if total_loss < min_mse:
      min_mse = total_loss
      print("保存模型epoch{},loss{}".format(epoch+1,min_mse))
      torch.save(this_model.state_dict(), config['save_path'])
      early_stop_cnt =0
    else:
      early_stop_cnt +=1
    epoch+=1
    loss_record['val'].append(total_loss)
    # 适当退出
    if early_stop_cnt > config['early_stop']:
       break
  print("神经网络经过{}训练结束".format(epoch))
  return min_mse, loss_record

4.保存训练结果,读取训练结果,进行测试

torch网络必备

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值