搭建深度学习框架+nn.Module

一、搭建项目框架(YOLO框架的简约版本)

最终成品的项目框架如下图,最终实现的效果,通过自己配置的框架函数,对模型进行定义与参数调配。同时在参数配置的过程中可选择是否进行模型初始化参数的使用。适用于YOLO框架的初认识。了解此框架可更好的认识YOLO框架。

二、Net模型的搭建-nn_net.py

net框架引用nn.Module父类框架,进行框架的搭建。本框架在文件夹net中。

python 复制代码
import torch.nn as nn

class Mynet_model(nn.Module):
    def __init__(self,input_size,output_size):
        super(Mynet_model,self).__init__()

        self.hiden1 = nn.Sequential(nn.Linear(input_size,128),nn.LeakyReLU())
        self.hiden2 = nn.Sequential(nn.Linear(128,256),nn.LeakyReLU())
        self.hiden3 = nn.Sequential(nn.Linear(256,512),nn.LeakyReLU())
        self.hiden4 = nn.Sequential(nn.Linear(512,256),nn.LeakyReLU())
        self.hiden5 = nn.Sequential(nn.Linear(256,128),nn.LeakyReLU())
        self.hiden6 = nn.Sequential(nn.Linear(128,64),nn.LeakyReLU())
        self.out = nn.Sequential(nn.Linear(64,output_size),nn.Softmax())
        self._init_weight()
        
    def forward(self,x):
        x = self.hiden1(x)
        x = self.hiden2(x)
        x = self.hiden3(x)
        x = self.hiden4(x)
        x = self.hiden5(x)
        x = self.hiden6(x)
        x = self.out(x)

        return x
    
    def _init_weight(self):
        # 对模型参数的初始化
        nn.init.kaiming_uniform_(self.hiden1[0].weight,nonlinearity='leaky_relu')
        nn.init.kaiming_uniform_(self.hiden2[0].weight,nonlinearity='leaky_relu')
        nn.init.kaiming_uniform_(self.hiden3[0].weight,nonlinearity='leaky_relu')
        nn.init.kaiming_uniform_(self.hiden4[0].weight,nonlinearity='leaky_relu')
        nn.init.kaiming_uniform_(self.hiden5[0].weight,nonlinearity='leaky_relu')
        nn.init.kaiming_uniform_(self.hiden6[0].weight,nonlinearity='leaky_relu')

三、优化器框架的搭建-optimizer.py

主要用于深度学习框架中,优化器的选择。本框架位于net文件夹中。

python 复制代码
# 创建优化器,按照参数名称进行优化器匹配,只能在这个文件中进行模型的配置
import torch.optim as optim

def optimizer_parents(model,name,lr,weight_decay,betas,eps):
    if name == 'SGD':
        optimizer = optim.SGD(model.parameters())
    elif name == 'Adam':
        optimizer = optim.Adam(model.parameters(),lr=lr,weight_decay=weight_decay,betas=betas,eps=eps)
    else:
        # 显示报错信息
        raise NotImplementedError('optimizer {} not implemented'.format(name))  
    return optimizer

if __name__ == '__main__':
    from nn_net import Mynet_model
    model = Mynet_model(input_size=20,output_size=10)
    optimizer = optimizer_parents(model,'SGD')

四、数据加载器-dataloder.py

本框架主要为读取csv文件,将csv文件进行数据处理后保存返回TensorDatasets类型的数据,便于后续进行Dataloder数据切分与调用。用于批量读取数据。本框架位于文件夹data中。

python 复制代码
# 创建数据集加载的工具
import torch ,os
from torch.utils.data import TensorDataset,Dataset,DataLoader
import pandas as pd 
from sklearn.preprocessing import StandardScaler
import numpy as np
from sklearn.model_selection import train_test_split
import parameter 

class Mydatasets():
    def __init__(self,path,pt_path,device):
        self.data = pd.read_csv(path)
        self.pt_path = pt_path
        self.device = device
        
    def datasets(self):
        data = np.array(self.data)
        x_ = data[:,:-1]
        y_ = data[:,-1]

        x_train,x_text,y_train,y_test = train_test_split(x_,y_,test_size=0.2,random_state=42,stratify=y_)

        # 数据标准化
        stander = StandardScaler()
        x_train = stander.fit_transform(x_train)
        x_text = stander.transform(x_text)

        # 标准化工具参数保存
        stander_dic = {
            "mean":stander.mean_,
            "std":stander.scale_
        }
        path = f"{self.pt_path}/stander.pth"
        if os.path.exists(path):
            pass
        else:
            torch.save(stander_dic,path)

        device = torch.device(self.device)

        # 将数据转换为tensor
        x_train = torch.tensor(x_train,dtype=torch.float32).to(device)
        x_text = torch.tensor(x_text,dtype=torch.float32).to(device)
        y_train = torch.tensor(y_train,dtype=torch.int64).to(device)
        y_test = torch.tensor(y_test,dtype=torch.int64).to(device)
        
        train = TensorDataset(x_train,y_train)
        test = TensorDataset(x_text,y_test)

        return train,test

五、文件路径创建框架-creat_path.py

本框架主要用于模型训练前,创建文件夹路径,用于保存本次训练过程中的相关训练参数以及模型。在每次训练过程中,在文件夹pt中生成相关exp文件,在exp文件内生成model_weight,优化器参数,其他参数等。

python 复制代码
import os 

def creat_path():
    name = 'exp_'
    Root = "./Torch/mobile_pheno/pt"
    i = 1
    for root,dir,list in os.walk(Root):
        if root == Root:
            if not dir:
                path = root+'/'+f"{name}{i}"
                os.makedirs(path)
            else:
                i = len(dir)
                path = root+'/'+f"{name}{i+1}"
                if not os.path.exists(path):
                    os.makedirs(path)
    return path

def read_path():
    name = 'exp_'
    Root = "./Torch/mobile_pheno/pt"
    i = 1
    for root,dir,list in os.walk(Root):
        if root == Root:
            i = len(dir)
            path = root+'/'+f"{name}{i}"

    return path

if __name__ == '__main__':
    creat_path()

六、模型相关参数配置-parameter.py

python 复制代码
# 模型的相关参数配置文件
import os 
import creat_path as cp

# 对训练文件模型中相关参数进行配置
def train_parameter():
    root_path = cp.creat_path()
    argument = {
        "device": "cpu",   # 运行的设备
        "optimizer_name": "Adam",  # 优化器的名称
        "learning_rate": 1e-4,   # 优化器相关参数
        "weight_decay": 0.01,
        "betas": (0.9, 0.999),
        "eps": 1e-8,
        "epochs": 50,  # 循环轮次
        "model_weight_file_path": './Torch/mobile_pheno/model/model_weight.yaml',   # 初始模型权重路径
        "root_path": root_path,  
        "optimizer_weight_file_path":'./Torch/mobile_pheno/model/optimizer_weight.yaml',  # 初始优化器权重路径
    }
    return argument

# 测试框架模型相关调优参数
def test_parameter():
    root_path = cp.read_path()
    argument = {
        "device": "cpu",
        "model_weight_file_path": os.path.join(root_path,"model_weight.yaml"),
        "root_path": root_path,
        "optimizer_weight_file_path":os.path.join(root_path,"optimizer_weight.yaml"),
        "other_weight_file_path":os.path.join(root_path,"other_weight.yaml")
    }
    return argument

七、训练框架-train.py

python 复制代码
from data.dataloder import Mydatasets
from net.nn_net import Mynet_model
from net.optimizer import optimizer_parents
import torch 
import torch.nn as nn
import os 
import time 
import parameter 
from torch.utils.data import DataLoader

def train(file_path):
    # 参数初始化
    argument = parameter.train_parameter()
    root_path = argument['root_path']
    train,_ = Mydatasets(file_path,root_path,argument['device']).datasets()  
    input_size = train[:][0].shape[1]
    output_size = torch.unique(train[:][1]).shape[0]
    
    # 加载数据加载器
    train = DataLoader(train,batch_size=16,shuffle=True)
    
    # device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    device = torch.device(argument['device'])
    model = Mynet_model(input_size,output_size).to(device)

    # 判定是否进行继承训练
    if os.path.exists(argument['model_weight_file_path']):
        model_weight = torch.load(argument['model_weight_file_path'])
        model.load_state_dict(model_weight["model_weight"])  

    loss_func = nn.CrossEntropyLoss()

    # 配置优化器
    # optimizer = torch.optim.Adam(model.parameters(),lr=learning_rate)
    optimizer = optimizer_parents(model,argument['optimizer_name'],argument['learning_rate'],argument['weight_decay'],argument['betas'],argument['eps'])
    # 进行optimizer参数优化
    if os.path.exists(argument['optimizer_weight_file_path']):
        optimizer_weight = torch.load(argument['optimizer_weight_file_path'])
        optimizer.load_state_dict(optimizer_weight['optimizer_weight'])

    start_time = time.time()
    epochs=argument['epochs']
    for epoch in range(epochs):
        conut = 0
        loss = 0
        for i,(x,y) in enumerate(train):
            y_pred = model(x)
            loss_value = loss_func(y_pred,y)
            optimizer.zero_grad()
            loss_value.backward()
            optimizer.step()
            conut +=1
            loss += loss_value
        print(f"epoch:{epoch},loss:{loss/conut}")
    end_time = time.time()
    print(f"time:{end_time-start_time}")
    

    # 生成字典对模型参数进行保存
    model_weight_parents = {
        "model_weight":model.state_dict(),
    }
    model_weight_parents_path = os.path.join(root_path,'model_weight.yaml')
    # torch.save(model_weight_parents,'./Torch/mobile_pheno/model/model_weight.yaml')   # 初始化模型保存
    torch.save(model_weight_parents,model_weight_parents_path)  # 在当前训练文件中进行当前训练模型的保存

    optimizer_weight_parents = {
        "optimizer_weight":optimizer.state_dict(),
    }
    optimizer_weight_parents_path = os.path.join(root_path,'optimizer_weight.yaml')
    # torch.save(optimizer_weight_parents,'./Torch/mobile_pheno/model/optimizer_weight.yaml')   # 初始化模型保存
    torch.save(optimizer_weight_parents,optimizer_weight_parents_path)  # 在当前训练文件中进行当前训练模型的保存

    other_parents = {
        "epoch":epochs,
        "input_size" : input_size,
        "output_size" : output_size,
    }
    other_parents_path = os.path.join(root_path,'other_weight.yaml')
    # torch.save(other_parents,'./Torch/mobile_pheno/model/other_weight.yaml')   # 初始化模型保存
    torch.save(other_parents,other_parents_path)  # 在当前训练文件中进行当前训练模型的保存

if __name__ == '__main__':
    path = "./Torch/mobile_pheno/data/手机价格预测.csv"
    train(path)

八,测试框架-test.py

python 复制代码
import torch 
import torch.nn as nn
from net.nn_net import Mynet_model
from data.dataloder import Mydatasets
import creat_path
import parameter
from torch.utils.data import DataLoader

def test(path):
    argument = parameter.test_parameter()
    root_path = argument['root_path']
    device = argument['device']
    _,test = Mydatasets(path,root_path,device).datasets()
    
    number = len(test)
    test = DataLoader(test,batch_size=8,shuffle=False)

    # 读取模型中的参数数据
    other_weight_file_path = torch.load(argument['other_weight_file_path'],map_location=device)
    input_size,output_size = other_weight_file_path['input_size'],other_weight_file_path['output_size']

    model_weight_file_path = torch.load(argument['model_weight_file_path'],map_location=device)
    model = Mynet_model(input_size,output_size).to(device)
    model.load_state_dict(model_weight_file_path['model_weight'])

    count = 0
    for x,y in test:
        y_pred = model(x)
        y_pred = torch.argmax(y_pred,dim=1)
        # print(f"预测结果:{y_pred},真实结果:{y}")
        count += (y_pred==y).sum()

    print(f"正确率:{count/number}")
    return count/number

if __name__ == '__main__':
    path = "./Torch/mobile_pheno/data/手机价格预测.csv"
    test(path)

九、推理框架

python 复制代码
# 推理验证模型 
import torch,os
import torch.nn as nn
import pandas as pd 
from sklearn.preprocessing import StandardScaler
import parameter
from torch.utils.data import DataLoader,TensorDataset
from net.nn_net import Mynet_model
import numpy as np

def data_sets(path):
    argument = parameter.test_parameter()
    device = argument['device']

    data = pd.read_csv(path)
    data = np.array(data)[:,1:]
    print(data.dtype)
    print(data.shape)
    print('**************************')
    # 导入数据标准化处理工具
    stander_file_path = os.path.join(argument['root_path'],'stander.pth')
    satander_mean_std = (torch.load(stander_file_path))


    satander = StandardScaler()
    satander.mean_ = np.array(satander_mean_std['mean'])
    satander.scale_ = np.array(satander_mean_std['std'])
    data = satander.transform(data)

    data = torch.tensor(data,dtype=torch.float32).to(device)
    return data

def detect(path):
    argument = parameter.test_parameter()
    data = data_sets(path)

    device = argument['device']
    model_weight_file_path = torch.load(argument['model_weight_file_path'],map_location=device)
    other_weight_file_path = torch.load(argument['other_weight_file_path'],map_location=device)

    model = Mynet_model(other_weight_file_path['input_size'],other_weight_file_path['output_size']).to(device)
    model.load_state_dict(model_weight_file_path['model_weight'])

    y_pred = model(data)
    y_pred = torch.argmax(y_pred,dim=1)
    print(y_pred)


if __name__ == "__main__":
    path = './Torch/mobile_pheno/data/detect_test.csv'
    detect(path)

十、main函数-save_best_model.py

python 复制代码
# 保存验证效果最好的模型数据参数
import train
import test
import torch

def bset_model():
    list = 0
    path = "./Torch/mobile_pheno/data/手机价格预测.csv"
    train.train(path)  
    result = test.test(path)  
    print(result)
    if result > list:
        model_parents =torch.load('./Torch/mobile_pheno/model/model_weight.yaml')
        torch.save(model_parents,'./Torch/mobile_pheno/model/best_model.yaml')
    
if __name__ == '__main__':
    bset_model()

十一、数据来源

本模型实验数据来源为https://tianchi.aliyun.com/dataset/157241,手机价格预测数据。

相关推荐
资讯分享周20 分钟前
思特奇亮相2024数字科技生态大会,以“智”谋新共赢AI新时代
人工智能·科技
HuggingAI24 分钟前
Stable Diffusion Controlnet常用控制类型解析与实战课程 2
人工智能·ai·stable diffusion·ai绘画
一尘之中1 小时前
基于Transformer的编码器-解码器图像描述模型在AMD GPU上的应用
人工智能·深度学习·transformer
IT古董1 小时前
【机器学习】机器学习的基本分类-监督学习-决策树-C4.5 算法
人工智能·学习·算法·决策树·机器学习·分类
电子工程师UP学堂1 小时前
电子应用设计方案-37:智能鼠标系统方案设计
人工智能·单片机·嵌入式硬件·计算机外设
Seeklike2 小时前
12.04 深度学习-用CNN做图像分类+训练可视化
深度学习·分类·cnn
后端研发Marion2 小时前
【AI工具】强大的AI编辑器Cursor详细使用教程
人工智能·编辑器·cusor
pzx_0012 小时前
【时间序列预测】基于Pytorch实现CNN_LSTM算法
人工智能·pytorch·python·算法·cnn·lstm
合合技术团队2 小时前
合合信息智能图像处理技术,让你的设备更智能
图像处理·人工智能·aigc
搏博4 小时前
路径规划之启发式算法之四:蚁群算法(Ant Colony Optimization,ACO)
人工智能·算法·机器学习