当前位置:   article > 正文

深度学习——简单的神经网络项目_csdn深度学习项目

csdn深度学习项目

一、项目介绍

二、简单的神经网络项目

深度学习的目的是为了得到一个好的模型

1.Data

一般输入是文件地址,或者数据内容,输出是一个存储了数据X,Y的数据结构

torch中一般用dataloader来装载

Data分为训练集,测试集和验证集

 Dataset:(数据集函数定义)

  1. class Covid_dataset(Dataset):
  2. def __init__(self,file_path,mode,dim=4,all_feature=True):#mode告诉数据集类型 训练集或测试集
  3. #读文件
  4. with open(file_path,"r") as f: #"r"以读的方式
  5. csv_data = list(csv.reader(f))
  6. data = np.array(csv_data[1:]) #去掉第一行
  7. #取矩阵形式的数据 逢5扣1
  8. #确定行 确定训练集和验证集
  9. if mode == "train":
  10. indices = [i for i in range(len(data)) if i % 5 !=0]
  11. elif mode == "val":
  12. indices = [i for i in range(len(data)) if i % 5 ==0]
  13. if all_feature:
  14. col_idx = [i for i in range(0, 93)]
  15. else:
  16. _, col_idx = get_feature_importance(data[:, 1:-1], data[:, -1],k=dim,column=csv_data[0][1:-1]) # 挑中了想要的列
  17. if mode == "test": #测试集 不要第一列转换为float型
  18. x = data[:,1:].astype(float)
  19. x = torch.tensor(x[:,col_idx]) #转换为张量
  20. else:
  21. x = data[indices,1:-1].astype(float) #不是测试集,行不是所有行,列不包括最后一列 最后一列为y
  22. x = torch.tensor(x[:,col_idx])
  23. y = data[indices,-1].astype(float)
  24. self.y = torch.tensor(y)
  25. #列x归一化 减去平均值除以标准差 keepdim 保持形状
  26. self.x = (x-x.mean(dim=0,keepdim=True))/x.std(dim=0,keepdim=True)
  27. self.mode = mode
  28. #取下标的值的函数
  29. def __getitem__(self, item):
  30. if self.mode == "test":
  31. return self.x[item].float()
  32. else:
  33. return self.x[item].float(), self.y[item].float()
  34. def __len__(self):
  35. return len(self.x)

定义训练集、验证集、测试集

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

调试数据函数

  1. for batch_x,batch_y in train_loader:
  2. print(batch_x,batch_y)

2.Model

定义自己的模型:输入X,输出预测值  定义f

  1. #二、Model:定义自己的模型 输入x,输出预测值 f 模型:维度变化 参数量
  2. #定义模型框架 nn.module torch里面模型的父类
  3. class myModel(nn.Module): #搭建框架
  4. def __init__(self,dim): #修改父类的初始化 dim维度 输入维度 维度变化
  5. super(myModel, self).__init__()
  6. #模型的第一层
  7. self.fc1 = nn.Linear(dim,100) #维度
  8. self.relu = nn.ReLU() #激活函数
  9. self.fc2 = nn.Linear(100,1) #只有两层全连接
  10. def forward(self,x):#前向 数据一步一步通过模型
  11. x = self.fc1(x)
  12. x = self.relu(x)
  13. x = self.fc2(x)
  14. #输出的维度要和真实的维度一样 预测值和真实值的维度一样
  15. if len(x.size())>1:
  16. x = x.squeeze(dim=1) #把张量降低一维
  17. return x
  18. model = myModel(dim)

3.hyperPara(除模型外的超参数)

一般包含:设备,学习率,优化器,损失函数,epochs等

  1. #将参数值写入字典中
  2. #超参数
  3. config = {
  4. "lr" : 0.001,
  5. "momentum" : 0.9,
  6. "epochs" : 20,
  7. "save_path" : "model_save/model.pth" , # 在训练集上训练,在验证集上验证 保存路径
  8. "rel_path" : "pred_csv"
  9. }
  10. #设备 如果 torch和cuda两个是适配的就在Gpu上算,否则就在cpu上算
  11. device = "cuda" if torch.cuda.is_available() else "cpu"
  12. #loss函数
  13. loss = nn.MSELoss()
  14. #优化器 momentum 动量 model.parameters()模型参数 lr 学习率
  15. optimizer = optim.SGD(model.parameters(),lr=config["lr"],momentum=config["momentum"])

4.训练流程

训练函数
  1. #训练流程 训练得到一个比较好的模型 保存在save_path
  2. train_val(model,train_loader,val_loader,device,config["epochs"],optimizer,loss,config["save_path"])
  1. #训练过程 (固定的)
  2. def train_val(model,train_loader,val_loader,device,epochs,optimizer,loss,save_path):
  3. model = model.to(device) #将模型放在gpu上面 模型在gpu上训练
  4. #记录训练集 验证集上loss是怎么变化的
  5. plt_train_loss = []
  6. plt_val_loss = []
  7. min_val_loss = 9999999999
  8. #训练的标志
  9. for epoch in range(epochs):
  10. train_loss = 0.0
  11. val_loss = 0.0
  12. start_time = time.time()
  13. model.train() #将模型设置为训练模式
  14. for batch_x,batch_y in train_loader: #取数据
  15. x, target = batch_x.to(device), batch_y.to(device) #把数据放在gpu上
  16. pred = model(x) #一旦数据经过模型,就会积攒梯度 前向过程
  17. train_bat_loss = loss(pred,target) #损失函数
  18. train_bat_loss.backward() #梯度回传过程
  19. #优化器
  20. optimizer.step() #更新参数的过程
  21. optimizer.zero_grad() #梯度归零
  22. train_loss += train_bat_loss.cpu().item() #将数据取下来 训练的总loss
  23. plt_train_loss.append(train_loss/train_loader.dataset.__len__()) #loss的均值
  24. #训练完验证 测试模式 看模型效果
  25. model.eval()
  26. with torch.no_grad(): #验证时不更新参数 不积攒梯度
  27. for batch_x, batch_y in val_loader: # 取数据
  28. x, target = batch_x.to(device), batch_y.to(device)
  29. pred = model(x) # 一旦数据经过模型,就会积攒梯度 前向过程
  30. val_bat_loss = loss(pred, target)
  31. val_loss += val_bat_loss.cpu().item()
  32. plt_val_loss.append(val_loss / val_loader.dataset.__len__())
  33. if val_loss < min_val_loss:
  34. torch.save(model, save_path) #保存模型
  35. min_val_loss = val_loss
  36. #每一轮训练的plt_train_loss,plt_val_loss都记载在最后一位
  37. print("[%03d/%03d] %2.2f secs Trainloss: %.6f Valloss: %.6f"%(epoch,epochs,time.time()-start_time, plt_train_loss[-1], plt_val_loss[-1]))
  38. #画图
  39. plt.plot(plt_train_loss)
  40. plt.plot(plt_val_loss)
  41. plt.title("loss")
  42. plt.legend("train", "val") #标签
  43. plt.show()

5.验证,运用训练好的模型预测

验证函数

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

三、项目创新点

1.正则化

  1. #创新点 自己定义MSELoss 平滑 防止过拟合
  2. def mseLoss(pred, target, model):
  3. loss = nn.MSELoss(reduction='mean')
  4. ''' Calculate loss '''
  5. regularization_loss = 0 # 正则项 平滑 防止过拟合
  6. for param in model.parameters():
  7. # TODO: you may implement L1/L2 regularization here
  8. # 使用L2正则项
  9. # regularization_loss += torch.sum(abs(param))
  10. regularization_loss += torch.sum(param ** 2) # 计算所有参数平方
  11. return loss(pred, target) + 0.00075 * regularization_loss # 返回损失
  12. loss = mseLoss() #定义mseloss 即 平方差损失

2.相关系数:线性相关

  1. #直接用 相关性 线性相关
  2. def get_feature_importance(feature_data, label_data, k =4,column = None):
  3. """
  4. feature_data,label_data 要求字符串形式
  5. k为选择的特征数量
  6. 如果需要打印column,需要传入行名
  7. 此处省略 feature_data, label_data 的生成代码。
  8. 如果是 CSV 文件,可通过 read_csv() 函数获得特征和标签。
  9. 这个函数的目的是, 找到所有的特征种, 比较有用的k个特征, 并打印这些列的名字。
  10. """
  11. model = SelectKBest(chi2, k=k) #定义一个选择k个最佳特征的函数
  12. X_new = model.fit_transform(feature_data, label_data) #用这个函数选择k个最佳特征
  13. #feature_data是特征数据,label_data是标签数据,该函数可以选择出k个特征
  14. print('x_new', X_new)
  15. scores = model.scores_ # scores即每一列与结果的相关性
  16. # 按重要性排序,选出最重要的 k 个
  17. indices = np.argsort(scores)[::-1] #[::-1]表示反转一个列表或者矩阵。
  18. # argsort这个函数, 可以矩阵排序后的下标。 比如 indices[0]表示的是,scores中最小值的下标。
  19. if column: # 如果需要打印选中的列
  20. k_best_features = [column[i+1] for i in indices[0:k].tolist()] # 选中这些列 打印
  21. print('k best features are: ',k_best_features)
  22. return X_new, indices[0:k] # 返回选中列的特征和他们的下标。

四、完整代码

  1. import time #计算时间的包
  2. import matplotlib.pyplot as plt
  3. import torch
  4. #读数据
  5. from torch.utils.data import DataLoader,Dataset #写数据集时使用 引入两个类
  6. import csv #读csv文件
  7. import pandas as pd #pandas读数据
  8. import numpy as np #矩阵,张量计算
  9. import torch.nn as nn
  10. from torch import optim
  11. from sklearn.feature_selection import SelectKBest,chi2
  12. #直接用 相关性 线性相关
  13. def get_feature_importance(feature_data, label_data, k =4,column = None):
  14. """
  15. feature_data,label_data 要求字符串形式
  16. k为选择的特征数量
  17. 如果需要打印column,需要传入行名
  18. 此处省略 feature_data, label_data 的生成代码。
  19. 如果是 CSV 文件,可通过 read_csv() 函数获得特征和标签。
  20. 这个函数的目的是, 找到所有的特征种, 比较有用的k个特征, 并打印这些列的名字。
  21. """
  22. model = SelectKBest(chi2, k=k) #定义一个选择k个最佳特征的函数
  23. X_new = model.fit_transform(feature_data, label_data) #用这个函数选择k个最佳特征
  24. #feature_data是特征数据,label_data是标签数据,该函数可以选择出k个特征
  25. print('x_new', X_new)
  26. scores = model.scores_ # scores即每一列与结果的相关性
  27. # 按重要性排序,选出最重要的 k 个
  28. indices = np.argsort(scores)[::-1] #[::-1]表示反转一个列表或者矩阵。
  29. # argsort这个函数, 可以矩阵排序后的下标。 比如 indices[0]表示的是,scores中最小值的下标。
  30. if column: # 如果需要打印选中的列
  31. k_best_features = [column[i+1] for i in indices[0:k].tolist()] # 选中这些列 打印
  32. print('k best features are: ',k_best_features)
  33. return X_new, indices[0:k] # 返回选中列的特征和他们的下标。
  34. #神经网络项目
  35. # 一、Data 输入文件地址,或者数据内容,输出是一个存储了数据X,Y的数据结构,torch中一般用dataloader来装载
  36. #流感数据集
  37. class Covid_dataset(Dataset):
  38. def __init__(self,file_path,mode,dim=4,all_feature=True):#mode告诉数据集类型 训练集或测试集
  39. #读文件
  40. with open(file_path,"r") as f: #"r"以读的方式
  41. csv_data = list(csv.reader(f))
  42. data = np.array(csv_data[1:]) #去掉第一行 第一行为列名
  43. #取矩阵形式的数据 逢5扣1
  44. #确定行 确定训练集和验证集
  45. if mode == "train":
  46. indices = [i for i in range(len(data)) if i % 5 !=0] #列表形式
  47. elif mode == "val":
  48. indices = [i for i in range(len(data)) if i % 5 ==0]
  49. if all_feature:
  50. col_idx = [i for i in range(0, 93)]
  51. else:
  52. _, col_idx = get_feature_importance(data[:, 1:-1], data[:, -1],k=dim,column=csv_data[0][1:-1]) # 挑中了想要的列
  53. if mode == "test": #测试集 不要第一列转换为float型
  54. x = data[:,1:].astype(float)
  55. x = torch.tensor(x[:,col_idx]) #转换为张量
  56. else:
  57. x = data[indices,1:-1].astype(float) #不是测试集,行不是所有行,列不包括最后一列 最后一列为y
  58. x = torch.tensor(x[:,col_idx])
  59. y = data[indices,-1].astype(float) #train val 既有x,也有y
  60. self.y = torch.tensor(y)
  61. #列x归一化 减去平均值除以标准差 keepdim 保持形状
  62. self.x = (x-x.mean(dim=0,keepdim=True))/x.std(dim=0,keepdim=True)
  63. self.mode = mode
  64. #取下标的值的函数
  65. def __getitem__(self, item):
  66. if self.mode == "test":
  67. return self.x[item].float()
  68. else:
  69. return self.x[item].float(), self.y[item].float()
  70. def __len__(self):
  71. return len(self.x)
  72. #二、Model:定义自己的模型 输入x,输出预测值 f 模型:维度变化 参数量
  73. #定义模型框架 nn.module torch里面模型的父类
  74. class myModel(nn.Module): #搭建框架
  75. def __init__(self,dim): #修改父类的初始化 dim维度 输入维度 维度变化
  76. super(myModel, self).__init__()
  77. #模型的第一层
  78. self.fc1 = nn.Linear(dim,100) #维度
  79. self.relu = nn.ReLU() #激活函数
  80. self.fc2 = nn.Linear(100,1) #只有两层全连接
  81. def forward(self,x):#前向 数据一步一步通过模型
  82. x = self.fc1(x)
  83. x = self.relu(x)
  84. x = self.fc2(x)
  85. #输出的维度要和真实的维度一样 预测值和真实值的维度一样
  86. if len(x.size())>1:
  87. x = x.squeeze(dim=1) #把张量降低一维
  88. return x
  89. #训练过程 (固定的)
  90. def train_val(model,train_loader,val_loader,device,epochs,optimizer,loss,save_path):
  91. model = model.to(device) #将模型放在gpu上面 模型在gpu上训练
  92. #记录训练集 验证集上loss是怎么变化的
  93. plt_train_loss = []
  94. plt_val_loss = []
  95. min_val_loss = 9999999999
  96. #训练的标志
  97. for epoch in range(epochs):
  98. train_loss = 0.0
  99. val_loss = 0.0
  100. start_time = time.time()
  101. model.train() #将模型设置为训练模式
  102. for batch_x,batch_y in train_loader: #取数据
  103. x, target = batch_x.to(device), batch_y.to(device) #把数据放在gpu上
  104. pred = model(x) #一旦数据经过模型,就会积攒梯度 前向过程
  105. train_bat_loss = loss(pred,target) #损失函数
  106. train_bat_loss.backward() #梯度回传过程
  107. #优化器
  108. optimizer.step() #更新参数的过程
  109. optimizer.zero_grad() #梯度归零
  110. train_loss += train_bat_loss.cpu().item() #将数据取下来 训练的总loss
  111. plt_train_loss.append(train_loss/train_loader.dataset.__len__()) #loss的均值
  112. #训练完验证 测试模式 看模型效果
  113. model.eval()
  114. with torch.no_grad(): #验证时不更新参数 不积攒梯度
  115. for batch_x, batch_y in val_loader: # 取数据
  116. x, target = batch_x.to(device), batch_y.to(device)
  117. pred = model(x) # 一旦数据经过模型,就会积攒梯度 前向过程
  118. val_bat_loss = loss(pred, target)
  119. val_loss += val_bat_loss.cpu().item()
  120. plt_val_loss.append(val_loss / val_loader.dataset.__len__())
  121. if val_loss < min_val_loss:
  122. torch.save(model, save_path) #保存模型
  123. min_val_loss = val_loss
  124. #每一轮训练的plt_train_loss,plt_val_loss都记载在最后一位
  125. print("[%03d/%03d] %2.2f secs Trainloss: %.6f Valloss: %.6f"%(epoch,epochs,time.time()-start_time, plt_train_loss[-1], plt_val_loss[-1]))
  126. #画图
  127. plt.plot(plt_train_loss)
  128. plt.plot(plt_val_loss)
  129. plt.title("loss")
  130. plt.legend("train", "val") #标签
  131. plt.show()
  132. def evaluate(save_path, device, test_loader, rel_path):
  133. model = torch.load(save_path).to(device) #加载模型放在gpu上
  134. rel = [] #将结果记录在表中
  135. model.eval() #将模型设置为验证模式
  136. with torch.no_grad(): #不积攒梯度
  137. for x in test_loader: #取数据
  138. pred = model(x.to(device))
  139. rel.append(pred.cpu().item()) #将记录结果放在rel上 rel为张量
  140. print(rel)
  141. #将结果写在文件上
  142. with open(rel_path, "w") as f: #w写 先打开文件
  143. csv_writer = csv.writer(f)
  144. csv_writer.writerow(["id", "tested_positive"])
  145. #写数据
  146. for i in range(len(rel)):
  147. csv_writer.writerow([str(i), str(rel[i])])
  148. print("文件已经保存到"+rel_path)
  149. # train_data = Covid_dataset(train_file,"train")
  150. #
  151. # #一次取16个数据 shuffle 打乱数据 一批一批取数据
  152. # train_loader = DataLoader(train_data,batch_size=16,shuffle=True)
  153. # model = myModel(93)
  154. #
  155. # for batch_x,batch_y in train_loader:
  156. # print(batch_x,batch_y)
  157. # pred = model(batch_x) #传入x直接进入forward函数
  158. #三、hyperPara:除模型外的超参数 一般包含:学习率,优化器,损失函数 回归损失函数
  159. #维度
  160. all_feature = True
  161. if all_feature:
  162. dim = 93
  163. else:
  164. dim = 6
  165. #如果 torch和cuda两个是适配的就在Gpu上算,否则就在cpu上算
  166. device = "cuda" if torch.cuda.is_available() else "cpu"
  167. # print(device)
  168. #两个数据 数据有三个函数
  169. train_file = "covid.train.csv"
  170. test_file = "covid.test.csv"
  171. #读数据
  172. # data = pd.read_csv(train_file)
  173. # print(data.head()) #读出前五行
  174. #定义训练集 验证集 测试集
  175. train_data = Covid_dataset(train_file,"train",dim = dim,all_feature=all_feature) #all_feature为true表示不挑取特征 false为挑取
  176. val_data = Covid_dataset(train_file,"val",dim = dim,all_feature=all_feature)
  177. test_data = Covid_dataset(test_file,"test",dim = dim,all_feature=all_feature)
  178. #一次取16个数据 shuffle 打乱数据 一批一批取数据
  179. #装入dataloader
  180. train_loader = DataLoader(train_data,batch_size=16,shuffle=True)
  181. val_loader = DataLoader(val_data,batch_size=16,shuffle=True)
  182. #测试集不打乱
  183. test_loader = DataLoader(test_data,batch_size=1,shuffle=False)
  184. # for batch_x,batch_y in train_loader:
  185. # print(batch_x,batch_y)
  186. #超参数
  187. config = {
  188. "lr" : 0.001,
  189. "momentum" : 0.9,
  190. "epochs" : 20,
  191. "save_path" : "model_save/model.pth" , # 在训练集上训练,在验证集上验证 保存路径
  192. "rel_path" : "pred_csv"
  193. }
  194. model = myModel(dim)
  195. #loss函数
  196. loss = nn.MSELoss()
  197. #创新点 自己定义MSELoss
  198. # def mseLoss(pred, target, model):
  199. # loss = nn.MSELoss(reduction='mean')
  200. # ''' Calculate loss '''
  201. # regularization_loss = 0 # 正则项 平滑 防止过拟合
  202. # for param in model.parameters():
  203. # # TODO: you may implement L1/L2 regularization here
  204. # # 使用L2正则项
  205. # # regularization_loss += torch.sum(abs(param))
  206. # regularization_loss += torch.sum(param ** 2) # 计算所有参数平方
  207. # return loss(pred, target) + 0.00075 * regularization_loss # 返回损失
  208. # loss = mseLoss() #定义mseloss 即 平方差损失
  209. #优化器 momentum 动量 model.parameters()模型参数 lr 学习率
  210. optimizer = optim.SGD(model.parameters(),lr=config["lr"],momentum=config["momentum"])
  211. #训练流程 训练得到一个比较好的模型 保存在save_path
  212. train_val(model,train_loader,val_loader,device,config["epochs"],optimizer,loss,config["save_path"])
  213. #加载最好的模型 最后保存在rel_path
  214. evaluate(config["save_path"], device, test_loader, config["rel_path"])

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/367862?site
推荐阅读
相关标签
  

闽ICP备14008679号