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

一、项目介绍

二、简单的神经网络项目

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

1.Data

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

torch中一般用dataloader来装载

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

 Dataset:(数据集函数定义)

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)

2.Model

定义自己的模型:输入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)

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

一般包含:设备,学习率,优化器,损失函数,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"])

4.训练流程

训练函数
#训练流程  训练得到一个比较好的模型 保存在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()

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

验证函数

#加载最好的模型 最后保存在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)

三、项目创新点

1.正则化

#创新点 自己定义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 即 平方差损失

2.相关系数:线性相关

#直接用  相关性 线性相关
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"])

​

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程导语:    人工智能可谓是现阶段最火的行业,在资本和技术协同支持下正在进入高速发展期。当今全球市值前五大公司都指向同一发展目标:人工智能。近几年,人工智能逐渐从理论科学落地到现实中,与生活越来越息息相关,相关的各种职位炙手可热,而深度学习更是人工智能无法绕开的重要一环。 从AlphaGo打败李世石开始,深度学习技术越来越引起社会各界的广泛关注。不只学术界,甚至在工业界也取得了重大突破和广泛应用。其中应用最广的研究领域就是图像处理和自然语言处理。而要入门深度学习,CNN和RNN作为最常用的两种神经网络是必学的。网上关于深度学习的资料很多,但大多知识点分散、内容不系统,或者以理论为主、代码实操少,造成学员学习成本高。本门课程将从最基础的神经元出发,对深度学习的基础知识进行全面讲解,帮助大家迅速成为人工智能领域的入门者,是进阶人工智能深层领域的基石。 讲师简介:赵辛,人工智能算法科学家。2019年福布斯科技榜U30,深圳市海外高层次人才(孔雀人才)。澳大利亚新南威尔士大学全奖博士,SCI收录其发表过的10篇国际期刊学术文章。曾任深圳市微埃智能科技有限公司联合创始人。CSDN人工智能机器学习、深度学习方向满分级精英讲师。授课风格逻辑严谨、条理清晰、循序渐进、循循善诱,化枯燥为如沐春风,所教学生人数过万。 课程设计: 本课程分为5大模块,19小节,共计540时长(约9小时): 第一部分,课程介绍、目标与内容概览。主要学习人工智能深度学习应用场景;熟悉深度学习主流技术;掌握使用keras解决深度学习主要问题(神经网络、卷积神经网络、循环神经网络),以及深度学习主要内容:神经网络、卷积神经网络、循环神经网络;案例简介。 第二部分,深度学习之多层感知器(MLP)。主要学习多层感知器(MLP);MLP实现非线性分类;深度学习实战准备;Python调用keras实现MLP。 MLP技术点实战案例:第三部分,深度学习之卷积神经网络(CNN)。主要学习卷积神经网络 ; CNN模型分析;主流CNN模型; Python调用keras实现CNN; CNN技术点实战案例:第四部分,深度学习之循环神经网络(RNN)。主要学习循环神经网络;RNN模型分析;Python调用keras实现RNN。 RNN技术点实战案例: 第五部分,综合提升。主要进行迁移学习;混合模型;实战准备+综合实战,以及最后进行课程内容总结。 混合模型技术点实战案例

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值