新冠人数预测项目学习

简述和理论知识

一个简单的深度学习项目有不可或缺的三部分:

  1. 数据集:主要包括训练集,验证集和测试集,其中训练集和验证集中数据有标签,即准确值,测试集无标签。
  2. 模型:定义相关模型,根据数据(x)预测(pre_y)值。
  3. 超参数:loss函数,学习率,优化器。

相关类

  1. Dataset

初始化函数,用来初始化数据集,并且根据传入参数将原本数据划分为训练集,验证集,测试集是独立一个文件,没有最终的准确值。

class CovidDataset(Dataset):
    def __init__(self,file_path,mode="train",all_feature=True,feature_dim=6):
        with open(file_path,"r") as f:
            ori_data = list(csv.reader(f))
            csv_data=np.array(ori_data[1:])[:,1:].astype(float)#先去掉第一行的标题,然后转化为array后进行切片,取所有行,第一列到最后一列(去掉第一列序号),最后将字符串类型的值转换为浮点型
            columns = ori_data[0]

        features = np.array(ori_data[1:])[:,1:-1]#特征值为除标签外全部数据
        label_data = np.array(ori_data[1:])[:,-1]#最后一列为标签
        if all_feature:
            col = np.array([i for i in range(0,93)])#所有列的下标
        else:
            _,col = get_feature_importance(features,label_data,feature_dim,columns)
        col = col.tolist()
        if mode =="train":          #逢5取1个,在总体数据中划分出训练集
            indices = [i for i in range(len(csv_data)) if i%5 != 0]
            data = torch.tensor(csv_data[indices, :-1])
            self.y = torch.tensor(csv_data[indices,-1])
        elif mode =="val":   #总体数据中划分出验证集
            indices = [i for i in range(len(csv_data)) if i%5 == 0]
            data = torch.tensor(csv_data[indices, :-1])
            self.y = torch.tensor(csv_data[indices, -1])
        else:
            indices = [i for i in range(len(csv_data))]
            data = torch.tensor(csv_data[indices])
        data = data[:,col]
        self.data =(data -data.mean(dim=0,keepdim=True))/data.std(dim=0,keepdim=True)//数据标准化,防止因某些数据值过大影响数据,将减去均值后的数据除以每一列的标准差,从而使每一列数据的标准差变为 1。
        self.mode = mode
    def __getitem__(self, idx):#根据不同的模式选择不同的集合
        if self.mode !="test":
            return self.data[idx].float(),self.y[idx].float()
        else:
            return self.data[idx]

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

 模型(model)

全链接神经网络模型类,MyModule1

class MyModel(nn.Module):
    def __init__(self,inDim):
        super(MyModel,self).__init__()
        self.fc = nn.Linear(inDim,64)#线性全链接层,输入维数为inDim,输出维度为64维
        self.relu1 = nn.ReLU() #激活函数
        self.fc2 = nn.Linear(64,1)#线性全连接层,输入64,输出1维

    def forward(self,x):
        x=self.fc(x)
        x=self.relu1(x)
        x=self.fc2(x)

        if len(x.size()) >1:
            return x.squeeze(1)#如果输出维度大于一则进行维度压缩
        return x

 模型训练

每次训练和验证过后打印loss值

def train_val(model,train_loader,val_loader,device,epochs,optimize,loss,saveKey):
    model=model.to(device)

    plt_train_loss = []
    plt_val_loss = []

    min_loss = 9999999999999999

    for epoch in range(epochs):  #训练开始
        train_loss = 0.0
        val_loss = 0.0
        start_time = time.time()
        model.train() #模型调为训练模式
        for batch_x,batch_y in train_loader:
            x,target = batch_x.to(device),batch_y.to(device)#在 PyTorch 里,所有的张量(数据)和模型(由一系列张量组成)都必须位于同一设备上才能进行计算
            pred = model(x)#进行前向传播,得到模型的预测结果
            train_bat_loss = loss(pred,target,model)
            train_bat_loss.backward()
            optimize.step()#根据梯度更新模型参数。
            optimize.zero_grad()
            train_loss +=  train_bat_loss.cpu().item()
        plt_train_loss.append(train_loss/train_loader.__len__())


        model.eval()
        with torch.no_grad():#上下文管理器,用于关闭梯度计算,减少内存消耗并提高计算速度。
            for batch_x,batch_y in val_loader:
                x, target = batch_x.to(device), batch_y.to(device)
                pred = model(x)
                val_bat_loss = loss(pred, target,model)
                val_loss+= val_bat_loss.cpu().item()
        plt_val_loss.append(val_loss/val_loader.__len__())
        if val_loss< min_loss:
            torch.save(model,saveKey)

        print("[%03d/%03d] %2.2f sec(s) Trainloss:%.6f |Valloss: %.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()

得出结果

最后将测试集数据放入模型中得出最后结果,并且写入到csv文件中

def evaluate(save_path, test_loader, device, rel_path):  # 得出测试结果文件
    model = torch.load(save_path).to(device)
    model.eval()  # 将模型设置为评估模式
    all_preds = []
    with torch.no_grad():
        for x in test_loader:
            x=x.to(device).float()
            # pred = model(x.to(device))
            pred = model(x)
            all_preds.append(pred.cpu().numpy())  # 将预测结果转换为 numpy 数组并存储

    # 拼接所有批次的预测结果
    all_preds = torch.tensor(np.concatenate(all_preds, axis=0))

    with open(rel_path, "w", newline='') as f:
        csvWriter = csv.writer(f)
        csvWriter.writerow(["id", "tested_positive"])
        for i, value in enumerate(all_preds):
            csvWriter.writerow([str(i), str(value.item())])  # 将预测结果转换为 Python 标量并写入文件

    print("文件已经保存到{}".format(rel_path))

总结

这次实战让我理解到了数据的细致分类,以及如何优化模型(计算出每列的相关系数,找出相关系数最大的几列数据对模型进行优化,采用正则化loss=loss+w*w目的是为了找最小loss时也让w尽量小),也学会了如何计算需要的参数个数(偏置,权重个数)如linear(4,1),参数个数为4*1+1=5个。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值