赞
踩
深度学习的目的是为了得到一个好的模型
一般输入是文件地址,或者数据内容,输出是一个存储了数据X,Y的数据结构。
torch中一般用dataloader来装载
Data分为训练集,测试集和验证集
- class Covid_dataset(Dataset):
- def __init__(self,file_path,mode,dim=4,all_feature=True):#mode告诉数据集类型 训练集或测试集
- #读文件
- with open(file_path,"r") as f: #"r"以读的方式
- csv_data = list(csv.reader(f))
- data = np.array(csv_data[1:]) #去掉第一行
- #取矩阵形式的数据 逢5扣1
- #确定行 确定训练集和验证集
- if mode == "train":
- indices = [i for i in range(len(data)) if i % 5 !=0]
- elif mode == "val":
- indices = [i for i in range(len(data)) if i % 5 ==0]
-
- if all_feature:
- col_idx = [i for i in range(0, 93)]
- else:
- _, col_idx = get_feature_importance(data[:, 1:-1], data[:, -1],k=dim,column=csv_data[0][1:-1]) # 挑中了想要的列
-
- if mode == "test": #测试集 不要第一列转换为float型
- x = data[:,1:].astype(float)
- x = torch.tensor(x[:,col_idx]) #转换为张量
- else:
- x = data[indices,1:-1].astype(float) #不是测试集,行不是所有行,列不包括最后一列 最后一列为y
- x = torch.tensor(x[:,col_idx])
- y = data[indices,-1].astype(float)
- self.y = torch.tensor(y)
- #列x归一化 减去平均值除以标准差 keepdim 保持形状
- self.x = (x-x.mean(dim=0,keepdim=True))/x.std(dim=0,keepdim=True)
-
- self.mode = mode
-
- #取下标的值的函数
- def __getitem__(self, item):
- if self.mode == "test":
- return self.x[item].float()
- else:
- return self.x[item].float(), self.y[item].float()
-
- def __len__(self):
- return len(self.x)

定义训练集、验证集、测试集
- #两个数据 数据有三个函数
- train_file = "covid.train.csv"
- test_file = "covid.test.csv"
- #读数据
- # data = pd.read_csv(train_file)
- # print(data.head()) #读出前五行
- #定义训练集 验证集 测试集
- train_data = Covid_dataset(train_file,"train",dim = dim,all_feature=all_feature) #all_feature为true表示不挑取特征 false为挑取
- val_data = Covid_dataset(train_file,"val",dim = dim,all_feature=all_feature)
- test_data = Covid_dataset(test_file,"test",dim = dim,all_feature=all_feature)
-
- #一次取16个数据 shuffle 打乱数据 一批一批取数据
- #装入dataloader
- train_loader = DataLoader(train_data,batch_size=16,shuffle=True)
- val_loader = DataLoader(val_data,batch_size=16,shuffle=True)
- #测试集不打乱
- test_loader = DataLoader(test_data,batch_size=1,shuffle=False)

调试数据函数
- for batch_x,batch_y in train_loader:
- print(batch_x,batch_y)
定义自己的模型:输入X,输出预测值 定义f
- #二、Model:定义自己的模型 输入x,输出预测值 f 模型:维度变化 参数量
- #定义模型框架 nn.module torch里面模型的父类
- class myModel(nn.Module): #搭建框架
- def __init__(self,dim): #修改父类的初始化 dim维度 输入维度 维度变化
- super(myModel, self).__init__()
- #模型的第一层
- self.fc1 = nn.Linear(dim,100) #维度
- self.relu = nn.ReLU() #激活函数
- self.fc2 = nn.Linear(100,1) #只有两层全连接
-
- def forward(self,x):#前向 数据一步一步通过模型
- x = self.fc1(x)
- x = self.relu(x)
- x = self.fc2(x)
-
- #输出的维度要和真实的维度一样 预测值和真实值的维度一样
- if len(x.size())>1:
- x = x.squeeze(dim=1) #把张量降低一维
- return x
-
- model = myModel(dim)

一般包含:设备,学习率,优化器,损失函数,epochs等
- #将参数值写入字典中
- #超参数
- config = {
- "lr" : 0.001,
- "momentum" : 0.9,
- "epochs" : 20,
- "save_path" : "model_save/model.pth" , # 在训练集上训练,在验证集上验证 保存路径
- "rel_path" : "pred_csv"
- }
-
- #设备 如果 torch和cuda两个是适配的就在Gpu上算,否则就在cpu上算
- device = "cuda" if torch.cuda.is_available() else "cpu"
-
-
- #loss函数
- loss = nn.MSELoss()
-
- #优化器 momentum 动量 model.parameters()模型参数 lr 学习率
- optimizer = optim.SGD(model.parameters(),lr=config["lr"],momentum=config["momentum"])

- #训练流程 训练得到一个比较好的模型 保存在save_path
- train_val(model,train_loader,val_loader,device,config["epochs"],optimizer,loss,config["save_path"])
- #训练过程 (固定的)
- def train_val(model,train_loader,val_loader,device,epochs,optimizer,loss,save_path):
- model = model.to(device) #将模型放在gpu上面 模型在gpu上训练
- #记录训练集 验证集上loss是怎么变化的
- plt_train_loss = []
- plt_val_loss = []
- min_val_loss = 9999999999
-
- #训练的标志
- 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) #把数据放在gpu上
- pred = model(x) #一旦数据经过模型,就会积攒梯度 前向过程
- train_bat_loss = loss(pred,target) #损失函数
- train_bat_loss.backward() #梯度回传过程
- #优化器
- optimizer.step() #更新参数的过程
- optimizer.zero_grad() #梯度归零
- train_loss += train_bat_loss.cpu().item() #将数据取下来 训练的总loss
-
- plt_train_loss.append(train_loss/train_loader.dataset.__len__()) #loss的均值
-
- #训练完验证 测试模式 看模型效果
- 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)
- val_loss += val_bat_loss.cpu().item()
-
- plt_val_loss.append(val_loss / val_loader.dataset.__len__())
- if val_loss < min_val_loss:
- torch.save(model, save_path) #保存模型
- min_val_loss = val_loss
- #每一轮训练的plt_train_loss,plt_val_loss都记载在最后一位
- print("[%03d/%03d] %2.2f secs 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()

验证函数
- #加载最好的模型 最后保存在rel_path
- evaluate(config["save_path"], device, test_loader, config["rel_path"])
- def evaluate(save_path, device, test_loader, rel_path):
- model = torch.load(save_path).to(device) #加载模型放在gpu上
- rel = [] #将结果记录在表中
- model.eval() #将模型设置为验证模式
-
- with torch.no_grad(): #不积攒梯度
- for x in test_loader: #取数据
- pred = model(x.to(device))
- rel.append(pred.cpu().item()) #将记录结果放在rel上 rel为张量
-
- print(rel)
-
- #将结果写在文件上
- with open(rel_path, "w") as f: #w写 先打开文件
- csv_writer = csv.writer(f)
- csv_writer.writerow(["id", "tested_positive"])
- #写数据
- for i in range(len(rel)):
- csv_writer.writerow([str(i), str(rel[i])])
- print("文件已经保存到"+rel_path)

- #创新点 自己定义MSELoss 平滑 防止过拟合
- def mseLoss(pred, target, model):
- loss = nn.MSELoss(reduction='mean')
- ''' Calculate loss '''
- regularization_loss = 0 # 正则项 平滑 防止过拟合
- for param in model.parameters():
- # TODO: you may implement L1/L2 regularization here
- # 使用L2正则项
- # regularization_loss += torch.sum(abs(param))
- regularization_loss += torch.sum(param ** 2) # 计算所有参数平方
- return loss(pred, target) + 0.00075 * regularization_loss # 返回损失
-
- loss = mseLoss() #定义mseloss 即 平方差损失
- #直接用 相关性 线性相关
- def get_feature_importance(feature_data, label_data, k =4,column = None):
- """
- feature_data,label_data 要求字符串形式
- k为选择的特征数量
- 如果需要打印column,需要传入行名
- 此处省略 feature_data, label_data 的生成代码。
- 如果是 CSV 文件,可通过 read_csv() 函数获得特征和标签。
- 这个函数的目的是, 找到所有的特征种, 比较有用的k个特征, 并打印这些列的名字。
- """
- model = SelectKBest(chi2, k=k) #定义一个选择k个最佳特征的函数
- X_new = model.fit_transform(feature_data, label_data) #用这个函数选择k个最佳特征
- #feature_data是特征数据,label_data是标签数据,该函数可以选择出k个特征
- print('x_new', X_new)
- scores = model.scores_ # scores即每一列与结果的相关性
- # 按重要性排序,选出最重要的 k 个
- indices = np.argsort(scores)[::-1] #[::-1]表示反转一个列表或者矩阵。
- # argsort这个函数, 可以矩阵排序后的下标。 比如 indices[0]表示的是,scores中最小值的下标。
-
- if column: # 如果需要打印选中的列
- k_best_features = [column[i+1] for i in indices[0:k].tolist()] # 选中这些列 打印
- print('k best features are: ',k_best_features)
- return X_new, indices[0:k] # 返回选中列的特征和他们的下标。

- import time #计算时间的包
- import matplotlib.pyplot as plt
- import torch
- #读数据
- from torch.utils.data import DataLoader,Dataset #写数据集时使用 引入两个类
- import csv #读csv文件
- import pandas as pd #pandas读数据
- import numpy as np #矩阵,张量计算
- import torch.nn as nn
- from torch import optim
- from sklearn.feature_selection import SelectKBest,chi2
-
- #直接用 相关性 线性相关
- def get_feature_importance(feature_data, label_data, k =4,column = None):
- """
- feature_data,label_data 要求字符串形式
- k为选择的特征数量
- 如果需要打印column,需要传入行名
- 此处省略 feature_data, label_data 的生成代码。
- 如果是 CSV 文件,可通过 read_csv() 函数获得特征和标签。
- 这个函数的目的是, 找到所有的特征种, 比较有用的k个特征, 并打印这些列的名字。
- """
- model = SelectKBest(chi2, k=k) #定义一个选择k个最佳特征的函数
- X_new = model.fit_transform(feature_data, label_data) #用这个函数选择k个最佳特征
- #feature_data是特征数据,label_data是标签数据,该函数可以选择出k个特征
- print('x_new', X_new)
- scores = model.scores_ # scores即每一列与结果的相关性
- # 按重要性排序,选出最重要的 k 个
- indices = np.argsort(scores)[::-1] #[::-1]表示反转一个列表或者矩阵。
- # argsort这个函数, 可以矩阵排序后的下标。 比如 indices[0]表示的是,scores中最小值的下标。
-
- if column: # 如果需要打印选中的列
- k_best_features = [column[i+1] for i in indices[0:k].tolist()] # 选中这些列 打印
- print('k best features are: ',k_best_features)
- return X_new, indices[0:k] # 返回选中列的特征和他们的下标。
- #神经网络项目
- # 一、Data 输入文件地址,或者数据内容,输出是一个存储了数据X,Y的数据结构,torch中一般用dataloader来装载
-
- #流感数据集
- class Covid_dataset(Dataset):
- def __init__(self,file_path,mode,dim=4,all_feature=True):#mode告诉数据集类型 训练集或测试集
- #读文件
- with open(file_path,"r") as f: #"r"以读的方式
- csv_data = list(csv.reader(f))
- data = np.array(csv_data[1:]) #去掉第一行 第一行为列名
- #取矩阵形式的数据 逢5扣1
- #确定行 确定训练集和验证集
- if mode == "train":
- indices = [i for i in range(len(data)) if i % 5 !=0] #列表形式
- elif mode == "val":
- indices = [i for i in range(len(data)) if i % 5 ==0]
-
- if all_feature:
- col_idx = [i for i in range(0, 93)]
- else:
- _, col_idx = get_feature_importance(data[:, 1:-1], data[:, -1],k=dim,column=csv_data[0][1:-1]) # 挑中了想要的列
-
- if mode == "test": #测试集 不要第一列转换为float型
- x = data[:,1:].astype(float)
- x = torch.tensor(x[:,col_idx]) #转换为张量
- else:
- x = data[indices,1:-1].astype(float) #不是测试集,行不是所有行,列不包括最后一列 最后一列为y
- x = torch.tensor(x[:,col_idx])
- y = data[indices,-1].astype(float) #train val 既有x,也有y
- self.y = torch.tensor(y)
- #列x归一化 减去平均值除以标准差 keepdim 保持形状
- self.x = (x-x.mean(dim=0,keepdim=True))/x.std(dim=0,keepdim=True)
-
- self.mode = mode
-
- #取下标的值的函数
- def __getitem__(self, item):
- if self.mode == "test":
- return self.x[item].float()
- else:
- return self.x[item].float(), self.y[item].float()
-
- def __len__(self):
- return len(self.x)
-
- #二、Model:定义自己的模型 输入x,输出预测值 f 模型:维度变化 参数量
- #定义模型框架 nn.module torch里面模型的父类
- class myModel(nn.Module): #搭建框架
- def __init__(self,dim): #修改父类的初始化 dim维度 输入维度 维度变化
- super(myModel, self).__init__()
- #模型的第一层
- self.fc1 = nn.Linear(dim,100) #维度
- self.relu = nn.ReLU() #激活函数
- self.fc2 = nn.Linear(100,1) #只有两层全连接
-
- def forward(self,x):#前向 数据一步一步通过模型
- x = self.fc1(x)
- x = self.relu(x)
- x = self.fc2(x)
-
- #输出的维度要和真实的维度一样 预测值和真实值的维度一样
- if len(x.size())>1:
- x = x.squeeze(dim=1) #把张量降低一维
- return x
- #训练过程 (固定的)
- def train_val(model,train_loader,val_loader,device,epochs,optimizer,loss,save_path):
- model = model.to(device) #将模型放在gpu上面 模型在gpu上训练
- #记录训练集 验证集上loss是怎么变化的
- plt_train_loss = []
- plt_val_loss = []
- min_val_loss = 9999999999
-
- #训练的标志
- 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) #把数据放在gpu上
- pred = model(x) #一旦数据经过模型,就会积攒梯度 前向过程
- train_bat_loss = loss(pred,target) #损失函数
- train_bat_loss.backward() #梯度回传过程
- #优化器
- optimizer.step() #更新参数的过程
- optimizer.zero_grad() #梯度归零
- train_loss += train_bat_loss.cpu().item() #将数据取下来 训练的总loss
-
- plt_train_loss.append(train_loss/train_loader.dataset.__len__()) #loss的均值
-
- #训练完验证 测试模式 看模型效果
- 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)
- val_loss += val_bat_loss.cpu().item()
-
- plt_val_loss.append(val_loss / val_loader.dataset.__len__())
- if val_loss < min_val_loss:
- torch.save(model, save_path) #保存模型
- min_val_loss = val_loss
- #每一轮训练的plt_train_loss,plt_val_loss都记载在最后一位
- print("[%03d/%03d] %2.2f secs 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()
-
-
- def evaluate(save_path, device, test_loader, rel_path):
- model = torch.load(save_path).to(device) #加载模型放在gpu上
- rel = [] #将结果记录在表中
- model.eval() #将模型设置为验证模式
-
- with torch.no_grad(): #不积攒梯度
- for x in test_loader: #取数据
- pred = model(x.to(device))
- rel.append(pred.cpu().item()) #将记录结果放在rel上 rel为张量
-
- print(rel)
-
- #将结果写在文件上
- with open(rel_path, "w") as f: #w写 先打开文件
- csv_writer = csv.writer(f)
- csv_writer.writerow(["id", "tested_positive"])
- #写数据
- for i in range(len(rel)):
- csv_writer.writerow([str(i), str(rel[i])])
- print("文件已经保存到"+rel_path)
-
-
- # train_data = Covid_dataset(train_file,"train")
- #
- # #一次取16个数据 shuffle 打乱数据 一批一批取数据
- # train_loader = DataLoader(train_data,batch_size=16,shuffle=True)
- # model = myModel(93)
- #
- # for batch_x,batch_y in train_loader:
- # print(batch_x,batch_y)
- # pred = model(batch_x) #传入x直接进入forward函数
-
- #三、hyperPara:除模型外的超参数 一般包含:学习率,优化器,损失函数 回归损失函数
-
- #维度
- all_feature = True
- if all_feature:
- dim = 93
- else:
- dim = 6
-
- #如果 torch和cuda两个是适配的就在Gpu上算,否则就在cpu上算
- device = "cuda" if torch.cuda.is_available() else "cpu"
- # print(device)
-
- #两个数据 数据有三个函数
- train_file = "covid.train.csv"
- test_file = "covid.test.csv"
- #读数据
- # data = pd.read_csv(train_file)
- # print(data.head()) #读出前五行
- #定义训练集 验证集 测试集
- train_data = Covid_dataset(train_file,"train",dim = dim,all_feature=all_feature) #all_feature为true表示不挑取特征 false为挑取
- val_data = Covid_dataset(train_file,"val",dim = dim,all_feature=all_feature)
- test_data = Covid_dataset(test_file,"test",dim = dim,all_feature=all_feature)
-
- #一次取16个数据 shuffle 打乱数据 一批一批取数据
- #装入dataloader
- train_loader = DataLoader(train_data,batch_size=16,shuffle=True)
- val_loader = DataLoader(val_data,batch_size=16,shuffle=True)
- #测试集不打乱
- test_loader = DataLoader(test_data,batch_size=1,shuffle=False)
- # for batch_x,batch_y in train_loader:
- # print(batch_x,batch_y)
-
-
- #超参数
- config = {
- "lr" : 0.001,
- "momentum" : 0.9,
- "epochs" : 20,
- "save_path" : "model_save/model.pth" , # 在训练集上训练,在验证集上验证 保存路径
- "rel_path" : "pred_csv"
- }
- model = myModel(dim)
-
- #loss函数
- loss = nn.MSELoss()
- #创新点 自己定义MSELoss
- # def mseLoss(pred, target, model):
- # loss = nn.MSELoss(reduction='mean')
- # ''' Calculate loss '''
- # regularization_loss = 0 # 正则项 平滑 防止过拟合
- # for param in model.parameters():
- # # TODO: you may implement L1/L2 regularization here
- # # 使用L2正则项
- # # regularization_loss += torch.sum(abs(param))
- # regularization_loss += torch.sum(param ** 2) # 计算所有参数平方
- # return loss(pred, target) + 0.00075 * regularization_loss # 返回损失
-
- # loss = mseLoss() #定义mseloss 即 平方差损失
-
- #优化器 momentum 动量 model.parameters()模型参数 lr 学习率
- optimizer = optim.SGD(model.parameters(),lr=config["lr"],momentum=config["momentum"])
-
- #训练流程 训练得到一个比较好的模型 保存在save_path
- train_val(model,train_loader,val_loader,device,config["epochs"],optimizer,loss,config["save_path"])
- #加载最好的模型 最后保存在rel_path
- evaluate(config["save_path"], device, test_loader, config["rel_path"])
-
-

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。