深度学习模型:Pytorch搭建ResNet、DenseNet网络,完成一维数据分类任务

2023.7.17

DenseNet和ResNet都是深度学习中常用的网络结构,它们各有优缺点。

DenseNet的优点是可以充分利用网络中的信息,因为每个层都可以接收来自前面所有层的信息。这种密集连接的结构可以提高网络的准确性,减少过拟合的风险。此外,DenseNet的参数量比ResNet少,训练速度更快。

ResNet的优点是可以解决深度网络中的梯度消失问题,使得网络可以更深更复杂。ResNet的残差结构可以让信息直接从前面的层传递到后面的层,避免了信息的丢失,提高了网络的准确性。此外,ResNet的结构简单,易于理解和实现。

DenseNet和ResNet的缺点也有所不同。DenseNet的缺点是需要更多的内存和计算资源,因为每个层都需要接收来自前面所有层的信息。此外,DenseNet的结构较为复杂,不易于理解和实现。

ResNet的缺点是在某些情况下可能会出现过拟合的问题,因为残差结构可以让信息直接从前面的层传递到后面的层,可能会导致网络过于复杂,难以泛化。

一、数据集的处理:

训练集、验证集、测试集的划分:

数据会被整理为.txt:(例如形成的trian.txt)

                最后会分割为trian_data.txt和train_labels.txt两个文件 

import os
import numpy as np
import random
import mathdef normalization(data):  # 归一化:均值0,方差1data = (data - data.mean()) / data.std()return datadef random_rowl(data):  # 把行的顺序随机排列idx = np.arange(data.shape[0])np.random.shuffle(idx)data = data[idx[0:]]return datadef getfilelist(path):  # 读取文件夹下所有txt文件filelist = []for filename in os.listdir(path):if os.path.splitext(filename)[1] == '.txt':filelist.append(filename)random.shuffle(filelist)  # 随机打乱文件列表里的顺序return filelistpath = '第一类数据的文件夹子路径','第二类数据的文件夹子路径','第三类数据的文件夹子路径'sort_num = 3  # 一共多少类?for i in range(sort_num):  # 个数修改为路径的数目,与文件夹个数相同fileName = "{}/".format(path[i])files = getfilelist(fileName)# files=getfilelist(path[i]+'/')a = len(files)print(path[i], a)data = np.loadtxt(fileName + files[0])[:, 1]data = normalization(data)for j in range(1, a):data1 = np.loadtxt(fileName + '/' + files[j])[:, 1]data1 = normalization(data1)data = np.c_[data, data1]data = data.T# 加标签label = np.zeros((len(data), sort_num))  # 标签也改为分类的数目,与文件夹个数相同for m in range(len(label)):label[m, i] = 1data = np.c_[data, label]data = random_rowl(data)t = math.floor(len(data) * 0.7)v = math.floor(len(data) * 0.2)train = data[:t, :]val = data[t:(t + v), :]test = data[(t + v):, :]np.savetxt(path[i] + '_train.txt', train, fmt='%.6f')np.savetxt(path[i] + '_val.txt', val, fmt='%.6f')np.savetxt(path[i] + '_test.txt', test, fmt='%.6f')train = np.loadtxt(path[0] + '_train.txt')
val = np.loadtxt(path[0] + '_val.txt')
test = np.loadtxt(path[0] + '_test.txt')for i in range(1, sort_num):  # 需要修改为与分类个数相同,最后一个数与文件夹train1 = np.loadtxt(path[i] + '_train.txt')val1 = np.loadtxt(path[i] + '_val.txt')test1 = np.loadtxt(path[i] + '_test.txt')train = random_rowl(np.r_[train, train1])val = random_rowl(np.r_[val, val1])test = random_rowl(np.r_[test, test1])np.savetxt('train.txt', train, fmt='%.6f') # 划分训练集
np.savetxt('val.txt', val, fmt='%.6f')  # 划分验证集
np.savetxt('test.txt', test, fmt='%.6f')  # 划分测试集# 从train.txt、val.txt、test.txt中分别获取数据和标签class_num = sort_num  # 分类的类数 train_labels = np.loadtxt('./train.txt')[:, -class_num:]
test_labels = np.loadtxt('./test.txt')[:, -class_num:]
val_labels = np.loadtxt('./val.txt')[:, -class_num:]train_data = np.loadtxt('./train.txt')[:, :-class_num]
test_data = np.loadtxt('./test.txt')[:, :-class_num]
val_data = np.loadtxt('./val.txt')[:, :-class_num]np.savetxt('train_data.txt', train_data, fmt='%.6f')
np.savetxt('val_data.txt', val_data, fmt='%.6f')
np.savetxt('test_data.txt', test_data, fmt='%.6f')np.savetxt('train_labels.txt', train_labels, fmt='%d')
np.savetxt('val_labels.txt', val_labels, fmt='%d')
np.savetxt('test_labels.txt', test_labels, fmt='%d')

二、数据的训练:

ResNet:

import numpy as np
import torch.optim as optim
import torch.nn as nnimport torch
from torch.utils.data import DataLoader, Datasetclass Bottlrneck(torch.nn.Module):def __init__(self, In_channel, Med_channel, Out_channel, downsample=False):super(Bottlrneck, self).__init__()self.stride = 1if downsample == True:self.stride = 2self.layer = torch.nn.Sequential(torch.nn.Conv1d(In_channel, Med_channel, 1, self.stride),torch.nn.BatchNorm1d(Med_channel),torch.nn.ReLU(),torch.nn.Conv1d(Med_channel, Med_channel, 3, padding=1),torch.nn.BatchNorm1d(Med_channel),torch.nn.ReLU(),torch.nn.Conv1d(Med_channel, Out_channel, 1),torch.nn.BatchNorm1d(Out_channel),torch.nn.ReLU(),)if In_channel != Out_channel:self.res_layer = torch.nn.Conv1d(In_channel, Out_channel, 1, self.stride)else:self.res_layer = Nonedef forward(self, x):if self.res_layer is not None:residual = self.res_layer(x)else:residual = xreturn self.layer(x) + residualclass ResNet(torch.nn.Module):def __init__(self, in_channels=2, classes=6):super(ResNet, self).__init__()self.features = torch.nn.Sequential(torch.nn.Conv1d(in_channels, 64, kernel_size=7, stride=2, padding=3),torch.nn.MaxPool1d(3, 2, 1),Bottlrneck(64, 64, 256, False),Bottlrneck(256, 64, 256, False),Bottlrneck(256, 64, 256, False),#Bottlrneck(256, 128, 512, True),Bottlrneck(512, 128, 512, False),Bottlrneck(512, 128, 512, False),Bottlrneck(512, 128, 512, False),#Bottlrneck(512, 256, 1024, True),Bottlrneck(1024, 256, 1024, False),Bottlrneck(1024, 256, 1024, False),Bottlrneck(1024, 256, 1024, False),Bottlrneck(1024, 256, 1024, False),Bottlrneck(1024, 256, 1024, False),#Bottlrneck(1024, 512, 2048, True),Bottlrneck(2048, 512, 2048, False),Bottlrneck(2048, 512, 2048, False),torch.nn.AdaptiveAvgPool1d(1))self.classifer = torch.nn.Sequential(torch.nn.Linear(2048, classes))def forward(self, x):x = torch.Tensor.view(x, (-1, 2, 511))x = self.features(x)x = x.view(-1, 2048)x = self.classifer(x)return xclass MyDataset(Dataset):def __init__(self, raman_dir, label_file):self.raman_dir = np.loadtxt(raman_dir)self.label_file = np.loadtxt(label_file)self.raman_data = []self.label_list = []for index in self.raman_dir:self.raman_data.append(index)for index in self.label_file:self.label_list.append(index)def __getitem__(self, idx):raman = torch.Tensor(self.raman_data[idx])label = torch.Tensor(self.label_list[idx])label = np.argmax(label)return raman, labeldef __len__(self):# 获取数据集的长度return len(self.label_list)if __name__ == '__main__':# 准备数据集train_data = './train_data.txt'val_data = './val_data.txt'# 标签train_label = './train_labels.txt'val_label = './val_labels.txt'# 创建数据加载器batch_size = 128# 训练集输入train_dataset = MyDataset(train_data, train_label)train_dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)# 测试集输入test_dataset = MyDataset(test_data, test_label)test_dataloader = DataLoader(test_dataset, batch_size=batch_size, shuffle=True)# 验证集输入val_dataset = MyDataset(val_data, val_label)val_dataloader = DataLoader(val_dataset, batch_size=batch_size, shuffle=True)train_data_size = len(train_dataset)val_data_size = len(val_dataset)# 创建网络模型class_num = 6test_data_length = 600ResNetOutput = ResNet(in_channels=2, classes=class_num).cuda()# 定义损失函数loss_fn = nn.CrossEntropyLoss().cuda()# 定义优化器learning_rate = 0.00001optimizer = optim.Adam(ResNetOutput.parameters(), lr=learning_rate)# 记录验证的次数total_train_step = 0total_val_step = 0# 训练epoch = 100acc_list = np.zeros(epoch)print("{0:-^27}".format('Train_Model'))for i in range(epoch):print("----------epoch={}----------".format(i + 1))ResNetOutput.train()for data in train_dataloader:  # data 是batch大小raman_train_data, t_labels = dataraman_train_data = raman_train_data.cuda()t_labels = t_labels.cuda()output = ResNetOutput(raman_train_data)loss = loss_fn(output, t_labels)# 优化器优化模型optimizer.zero_grad()  # 梯度清零loss.backward()  # 反向传播optimizer.step()  # 优化更新参数total_train_step = total_train_step + 1print("train_times:{},Loss:{}".format(total_train_step, loss.item()))# 测试步骤开始ResNetOutput.eval()total_val_loss = 0total_accuracy = 0with torch.no_grad():  # 测试的时候不需要对梯度进行调整,所以梯度设置不调整for data in val_dataloader:raman_val_data, v_labels = dataraman_val_data = raman_val_data.cuda()v_labels = v_labels.cuda()outputs = ResNetOutput(raman_val_data)loss = loss_fn(outputs, v_labels)total_val_loss = total_val_loss + loss.item()  # 计算损失值的和accuracy = 0for j in v_labels:if outputs.argmax(1)[j] == v_labels[j]:accuracy = accuracy + 1# accuracy = (outputs.argmax(1) == v_labels).sum()  # 计算一个数据的精确度total_accuracy = total_accuracy + accuracyval_acc = float(total_accuracy / 1440) * 100acc_list[i] = val_accprint('the_classification_is_correct :', total_accuracy)  # 正确分类的个数print("val_Loss:{}".format(total_val_loss))print("val_acc:{}".format(float(total_accuracy / 1440) * 100), '%')total_val_step += 1torch.save(ResNetOutput, "ResNet_{}.pth".format(i))# torch.save(ResNetOutput.state_dict(), "ResNet_{}.pth".format(i))print("{0:-^24}".format('Model_Save'), '\n')print('val_max=', max(acc_list), '%')

注意!在代码的75行:

x = torch.Tensor.view(x, (-1, 2, 511))  # 511的位置要根据自己的数据集形状调整

DenseNet:

import numpy as np
import torch.optim as optim
import torch.nn as nnimport torch
from torch.utils.data import DataLoader, Datasetclass DenseLayer(torch.nn.Module):def __init__(self, in_channels, middle_channels=128, out_channels=32):super(DenseLayer, self).__init__()self.layer = torch.nn.Sequential(torch.nn.BatchNorm1d(in_channels),torch.nn.ReLU(inplace=True),torch.nn.Conv1d(in_channels, middle_channels, 1),torch.nn.BatchNorm1d(middle_channels),torch.nn.ReLU(inplace=True),torch.nn.Conv1d(middle_channels, out_channels, 3, padding=1))def forward(self, x):return torch.cat([x, self.layer(x)], dim=1)class DenseBlock(torch.nn.Sequential):def __init__(self, layer_num, growth_rate, in_channels, middele_channels=128):super(DenseBlock, self).__init__()for i in range(layer_num):layer = DenseLayer(in_channels + i * growth_rate, middele_channels, growth_rate)self.add_module('denselayer%d' % (i), layer)class Transition(torch.nn.Sequential):def __init__(self, channels):super(Transition, self).__init__()self.add_module('norm', torch.nn.BatchNorm1d(channels))self.add_module('relu', torch.nn.ReLU(inplace=True))self.add_module('conv', torch.nn.Conv1d(channels, channels // 2, 3, padding=1))self.add_module('Avgpool', torch.nn.AvgPool1d(2))class DenseNet(torch.nn.Module):def __init__(self, layer_num=(6, 12, 24, 16), growth_rate=32, init_features=64, in_channels=1, middele_channels=128,classes=6):super(DenseNet, self).__init__()self.feature_channel_num = init_featuresself.conv = torch.nn.Conv1d(in_channels, self.feature_channel_num, 7, 2, 3)self.norm = torch.nn.BatchNorm1d(self.feature_channel_num)self.relu = torch.nn.ReLU()self.maxpool = torch.nn.MaxPool1d(3, 2, 1)# self.attention = SpatialAttention(64)  # 空间注意力机制self.DenseBlock1 = DenseBlock(layer_num[0], growth_rate, self.feature_channel_num, middele_channels)self.feature_channel_num = self.feature_channel_num + layer_num[0] * growth_rateself.Transition1 = Transition(self.feature_channel_num)self.DenseBlock2 = DenseBlock(layer_num[1], growth_rate, self.feature_channel_num // 2, middele_channels)self.feature_channel_num = self.feature_channel_num // 2 + layer_num[1] * growth_rateself.Transition2 = Transition(self.feature_channel_num)self.DenseBlock3 = DenseBlock(layer_num[2], growth_rate, self.feature_channel_num // 2, middele_channels)self.feature_channel_num = self.feature_channel_num // 2 + layer_num[2] * growth_rateself.Transition3 = Transition(self.feature_channel_num)self.DenseBlock4 = DenseBlock(layer_num[3], growth_rate, self.feature_channel_num // 2, middele_channels)self.feature_channel_num = self.feature_channel_num // 2 + layer_num[3] * growth_rateself.avgpool = torch.nn.AdaptiveAvgPool1d(1)self.classifer = torch.nn.Sequential(torch.nn.Linear(self.feature_channel_num, self.feature_channel_num // 2),torch.nn.ReLU(),torch.nn.Dropout(0.5),torch.nn.Linear(self.feature_channel_num // 2, classes),)def forward(self, x):x = torch.Tensor.view(x, (-1, 1, 1022))  # 第一个参数是batch_sizex = x.resize_as_(x.to(torch.float32))x = self.conv(x)x = self.norm(x)  # 正则化x = self.relu(x)x = self.maxpool(x)x = self.DenseBlock1(x)x = self.Transition1(x)x = self.DenseBlock2(x)x = self.Transition2(x)x = self.DenseBlock3(x)x = self.Transition3(x)x = self.DenseBlock4(x)x = self.avgpool(x)x = x.view(-1, self.feature_channel_num)x = self.classifer(x)return xclass MyDataset(Dataset):  # 利用Pytorch的内置函数加载数据def __init__(self, raman_dir, label_file):self.raman_dir = np.loadtxt(raman_dir)self.label_file = np.loadtxt(label_file)self.raman_data = []self.label_list = []for index in self.raman_dir:self.raman_data.append(index)for index in self.label_file:self.label_list.append(index)def __getitem__(self, idx):raman = torch.Tensor(self.raman_data[idx])label = torch.Tensor(self.label_list[idx])label = np.argmax(label)return raman, labeldef __len__(self):# 获取数据集的长度return len(self.label_list)if __name__ == '__main__':# 准备数据集train_data = './train_data.txt'val_data = './val_data.txt'# 标签train_label = './train_labels.txt'val_label = './val_labels.txt'# 数据长度test_data_length = 600val_data_length = 1440# 分类的类别class_num = 6  # 注意调整58行的函数中的class(分类类别)# 学习率learning_rate = 0.00001# 批处理大小batch_size = 128# 数据加载器train_dataset = MyDataset(train_data, train_label)train_dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)test_dataset = MyDataset(test_data, test_label)test_dataloader = DataLoader(test_dataset, batch_size=batch_size, shuffle=True)val_dataset = MyDataset(val_data, val_label)val_dataloader = DataLoader(val_dataset, batch_size=batch_size, shuffle=True)train_data_size = len(train_dataset)val_data_size = len(val_dataset)# 创建网络模型DenseNetOutput = DenseNet().cuda()  # .Cuda()数据是指放到GPU上# 定义损失函数loss_fn = nn.CrossEntropyLoss().cuda()  # 交叉熵函数# 定义优化器optimizer = optim.Adam(DenseNetOutput.parameters(), lr=learning_rate)# 记录验证的次数total_train_step = 0total_val_step = 0writer = SummaryWriter("logs_train")  # 记录训练的权重# 训练epoch = 30  #acc_list = np.zeros(epoch)print("{0:-^27}".format('Train_Model'))for i in range(epoch):print("----------epoch={}----------".format(i + 1))DenseNetOutput.train()for data in train_dataloader:  # data 是batch大小raman_train_data, t_labels = dataraman_train_data = raman_train_data.cuda()t_labels = t_labels.cuda()output = DenseNetOutput(raman_train_data)loss = loss_fn(output, t_labels)# 优化器优化模型optimizer.zero_grad()  # 梯度清零loss.backward()  # 反向传播optimizer.step()  # 优化更新参数total_train_step = total_train_step + 1print("train_times:{},Loss:{}".format(total_train_step, loss.item()))# 测试步骤开始DenseNetOutput.eval()total_val_loss = 0total_accuracy = 0with torch.no_grad():  # 测试的时候不需要对梯度进行调整,所以梯度设置不调整for data in val_dataloader:raman_val_data, v_labels = dataraman_val_data = raman_val_data.cuda()v_labels = v_labels.cuda()outputs = DenseNetOutput(raman_val_data)loss = loss_fn(outputs, v_labels)total_val_loss = total_val_loss + loss.item()  # 计算损失值的和accuracy = 0for j in v_labels:  # 计算精确度的和if outputs.argmax(1)[j] == v_labels[j]:accuracy = accuracy + 1# accuracy = (outputs.argmax(1) == v_labels).sum()  # 计算一个数据的精确度total_accuracy = total_accuracy + accuracyval_acc = float(total_accuracy / val_data_size) * 100acc_list[i] = val_acc  # 记录验证集的正确率print('the_classification_is_correct :', total_accuracy, val_data_length)print("val_Loss:{}".format(total_val_loss))print("val_acc:{}".format(val_acc), '%')total_val_step += 1torch.save(DenseNetOutput, "DenseNet_{}.pth".format(i + 1))print("{0:-^24}".format('Model_Saved'), '\n')print('val_max=', max(acc_list), '%')  # 验证集的最高正确率

注意!在代码的93行:

x = torch.Tensor.view(x, (-1, 1, 1022))  # 1022的位置要根据自己的数据集大小取调整 

测试代码:

import torch
import numpy as np
from ResNet import Bottlrneck, ResNet# from DenseNet_SpatialAttention import DenseNet, DenseLayer, DenseBlockdevice = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')  # 判断是否有GPUtest_data = np.loadtxt('./test_data.txt')  # 测试集的路径model = ResNet().to(device)
model.load_state_dict(torch.load('ResNet_100.pth'))  # 加载模型# model = DenseNet().to(device)
# model.load_state_dict(torch.load('DenseNet_100.pth'))  # 加载模型test_length = test_data.shape[0]for i in range(test_length):td = torch.from_numpy(test_data[i]).float().to(device)Predict_output = model(td).to(device)_, predicted = Predict_output.max(1)pred_type = predicted.item()print('pred_type:', pred_type)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/26346.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DBeaver连接华为高斯数据库 DBeaver连接Gaussdb数据库 DBeaver connect Gaussdb

DBeaver连接华为高斯数据库 DBeaver连接Gaussdb数据库 DBeaver connect Gaussdb 一、概述 华为GaussDB出来已经有一段时间,最近工作中刚到Gauss数据库。作为coder,那么如何通过可视化工具来操作Gauss呢? 本文将记录使用免费、开源的DBeaver来…

Python迭代器与生成器

文章目录 迭代器创建迭代器StopIteration 生成器 迭代器 访问集合元素的一种方式,可以记住遍历的位置的对象 从集合的第一个元素开始,直到所有的元素被访问完结束,迭代器只能往前不会后退 iter(),创建迭代器对象 iter(object, …

matlab滤波器设计-IIR滤波器的设计与仿真

matlab滤波器设计-IIR滤波器的设计与仿真 1 引言 在现代通信系统中,由于信号中经常混有各种复杂成分,所以很多信号的处理和分析都是基于滤波器而进行的。但是,传统的数字滤波器的设计使用繁琐的公式计算,改变参数后需要重新计…

AlienSwap 首期 Launchpad — 粉丝偶像女团 NFT+RWA 的创新探索

NFT 是整个加密市场一致看好,并认为会继续爆发的领域。随着更多的 NFT 平台和 NFT 项目的推出,NFT 市场的格局也在不断变化。从开始的 OpenSea 占据领先地位,到 Blur 的横空出世风头无两,在加密领域,局势更迭总是在不经…

Hive自定义函数

本文章主要分享单行函数UDF(一进一出) 现在前面大体总结,后边文章详细介绍 自定义函数分为临时函数与永久函数 需要创建Java项目,导入hive依赖 创建类继承 GenericUDF(自定义函数的抽象类)(实现…

如何通过Pytest的插件,轻松切换自动化测试的环境地址?

前言 前面小编介绍了如何通过Pytest的插件来实现自动化测试的环境的切换,当时使用的方法是通过钩子函数进行获取命令行参数值,然后通过提前配置好的参数进行切换测试环境地址。 今天小编再次介绍一种方法,通过Pytest的插件:pyte…

谷歌Bard更新中文支持;GPT-4:1.8万亿参数、混合专家模型揭秘; Meta推出商用版本AI模型

🦉 AI新闻 🚀 谷歌的AI聊天工具Bard更新,增加中文支持 摘要:谷歌的AI聊天工具Bard新增中文环境,用户可以使用简体和繁体中文进行交流。然而,与竞品相比,Bard的回复略显生硬,语义理…

Redis深入——管道、发布订阅、主从复制、哨兵监控和集群

前言 在前面的学习中,我们已经了解了Redis的基本语法以及Redis持久化和事务的概念。而在这篇文章中我们继续来梳理管道、发布订阅、主从复制、哨兵监控和集群的知识,理解Redis主从复制到集群分片的演进过程,希望对正在学习的小伙伴有一定的帮…

关于学习过程中的小点

nfev : 函数求值次数njev : Jacobian 评估的数量nit :算法的迭代次数 permute(dims)#维度转换 torch.split #[按块大小拆分张量] Pytorch.view Pytorch中使用view()函数对张量进行重构维度,类似于resize()、reshape()。用法如下:view(参数a,参数b,...)&a…

Boojum:zkSync的高性能去中心化STARK证明系统

1. 引言 2023年7月17日zkSync官方twitter Say hello to Boojum宣称在不regenesis的情况下,将zkSync Era迁移至Boojum证明系统。 Boojum为STARK证明系统(PlonkFRI),开源代码见: https://github.com/matter-labs/era-…

Python爬虫学习笔记(三)————urllib

目录 1.使用urllib来获取百度首页的源码 2.下载网页图片视频 3.总结-1 4.请求对象的定制(解决第一种反爬) 5.编解码 (1)get请求方式:urllib.parse.quote() (2)get请求…

微信小程序用户登录及头像昵称设置教程(前后端)

目录 1.背景分析 2.具体需求分析 3.前端设计 3.1 用户登录 3.2 头像昵称填写(个人信息界面) 4.后端设计 4.1项目架构分析 4.2 代码分析 实体类 dao层 service层 controller层 工具类 5.nginx部署 6.效果演示 1.背景分析 众所周知&#x…