基于1DCNN的音频分类模型训练与测试
coding = UTF-8
import sys import os
class Logger(object):
def init(self, filename='default.log', stream=sys.stdout): # ??????????????????????????????????????(sys.stdout)?
self.terminal = stream # ??????????self.terminal????
self.log = open(filename, 'w') #???????????????self.log???????????????
def write(self, message): # ????write????????????????????????????????????????
self.terminal.write(message)
self.log.write(message)
def flush(self): #????flush???????????????????????????????????flush?????????????
pass
sys.stdout = Logger('result.log', sys.stdout) # ?????????????????'result.log'??????? import argparse import numpy as np import time from sklearn.metrics import accuracy_score, confusion_matrix from Gmlp import CNN from mydataset import MyDataset import torch from torch.utils.data import DataLoader import torch.nn as nn import matplotlib.pyplot as plt import pandas as pd import seaborn as sns # 导入包 from tqdm import *
def test(model, dataset, criterion): #??????????????????????????????????????????????????????????????????????
model.eval() #???????????model.eval()?
total_batch_num =0. #????????0??????0??????????????????????Tensor?
val_loss = 0
prediction = []
labels = []
feature_list = torch.tensor([]) # test总数,特征数
#if torch.cuda.is_available(): #????????????????CUDA???????????????????????feature_list???GPU??????1
# feature_list = feature_list.cuda()
for (step, i) in enumerate(dataset): #???????for???????????dataset??????????????enumerate????????????????step??????i?
total_batch_num = total_batch_num + 1 #??????????????????total_batch_num??1
batch_x = i['data'] #??????'data'???????batch_x?
batch_y = i['label'] # ??????'label'???????batch_y?
batch_x = torch.unsqueeze(batch_x, dim=1) # (50, 1, 10000, 12) #batch_x????????(50, 1, 10000, 12)???2??????????
batch_x = batch_x.float() #?batch_x?????float???
if torch.cuda.is_available(): #????????CUDA????GPU??3
batch_x = batch_x.cuda()
batch_y = batch_y.cuda()
feature, probs = model(batch_x) # feature 20,400 #??????????????????????????
feature = feature.cpu().detach()#cpu
batch_label = batch_y.unsqueeze(1).float() #feature????????????????????
batch_label = batch_label.cpu().detach() #cpu
feature_label = torch.cat((feature, batch_label), dim=1) #??????????????
feature_list = torch.cat((feature_list, feature_label), dim=0) # feature_list #??????????????????
loss = criterion(probs, batch_y) #?????????????????
_, pred = torch.max(probs, dim=1) #??????????????????
predi = pred.tolist() #????????Python???
label = batch_y.tolist() #????????Python???
val_loss += loss.item() #??????????? x
prediction.extend(predi) #???????????????????????
labels.extend(label) #?????????????????????
accuracy = accuracy_score(labels, prediction) #??????????
C = confusion_matrix(labels, prediction) #??????????????
return accuracy, val_loss / total_batch_num, feature_list, C #?????????????????????
def train(model, train_x, train_y, optimizer, criterion): model.train() #?????????? model.zero_grad() #???????? ,probs = model(train_x) #??????train_x??????????probs??????????????? loss = criterion(probs, train_y) #??????criterion??????probs?????train_y?????? _, pred = torch.max(probs, dim=1) #?????probs???????????????????????pred? labels = train_y.tolist() #?????train_y???Python????? predi = pred.tolist() #?????pred???Python????? loss.backward() #????????? optimizer.step() #?????optimizer??????? return labels, predi, loss.item() #?????????????????
def draw(train_acc, train_loss, test_acc, test_loss): #??????draw??????????????train_acc?train_loss?test_acc?test_loss? x1 = range(len(train_acc)) #??????x1??range?????????0?train_acc????????? x2 = range(len(train_loss)) #?????x2??range?????????0?train_loss????????? y1 = train_acc y2 = train_loss y3 = test_acc y4 = test_loss plt.subplot(2, 1, 1) plt.plot(x1, y1, 'o-', label='train', color='b') plt.plot(x1, y3, 'o-', label='test', color='r') plt.legend(loc='upper left') plt.title('accuracy & NAR vs. epochs') plt.ylabel('accuracy') plt.subplot(2, 1, 2) plt.plot(x2, y2, '.-', label='train', color='b') plt.plot(x2, y4, '.-', label='test', color='r') plt.legend(loc='upper left') plt.xlabel('loss vs. epochs') plt.ylabel('loss') plt.savefig('Gmlp_accuracy_loss.jpg') plt.show()
def draw_result(C): fig = plt.figure() ax = fig.add_subplot(111) df = pd.DataFrame(C) # f1 = fm.fontProperties('Times New Roman', size=15) sns.heatmap(df, fmt='g', annot=True, annot_kws={'size': 10}, xticklabels=['1', '2', '3', '4', '5', '6'], yticklabels=['1', '2', '3', '4', '5', '6'], cmap='Blues') ax.set_xlabel('Predicted label') # fontProperties=f1) # x轴 ax.set_ylabel('True label') # fontProperties=f1) # y轴 plt.savefig('./Gmlp_matrix.jpg') plt.show() Acc = (C[0][0] + C[1][1] + C[2][2] + C[3][3] + C[4][4] + C[5][5]) / sum(C[0] + C[1] + C[2] + C[3] + C[4] + C[5]) print('acc: %.3f' % Acc) lie_he = sum(C, 1) - 1 for i in range(1, 7): Precision = C[i - 1][i - 1] / lie_he[i - 1] NAR = (sum(C[i - 1]) - C[i - 1][i - 1]) / sum(C[i - 1]) F1_score = 2 * C[i - 1][i - 1] / (lie_he[i - 1] + sum(C[i - 1])) print('precision_%d: %.3f' % (i, Precision)) print('NAR_%d: %.3f' % (i, NAR)) print('F1_score_%d: %.3f' % (i, F1_score))
def main(args): # 划分训练集、测试集 train_dataset = MyDataset(args.root, args.txtpath, transform=None) train_loader = DataLoader(dataset=train_dataset, batch_size=args.batch_size, shuffle=True, num_workers=0) test_dataset = MyDataset(args.root2, args.txtpath2, transform=None) test_loader = DataLoader(dataset=test_dataset, batch_size=args.batch_size, shuffle=True, num_workers=0)
cnn_gmlp_model= {'CNN': CNN}
# 二者取其一
# model = torch.load('./gmlp-modelpth/40.pth')#,map_location=torch.device('cpu')) # 加载参数
model = cnn_gmlp_model[args.model]()
if torch.cuda.is_available():
model = model.cuda()
#model = torch.load('./cnn-gmlp-modelpth/40.pth')
optimizer = torch.optim.Adam(model.parameters(), lr=1e-4, weight_decay=1e-5)
# optimizer.load_state_dict(torch.load('save_optim.pt'))
criterion = nn.CrossEntropyLoss()
batches_per_epoch = int(len(train_dataset) / args.batch_size)
train_loss_list = []
train_acc_list = []
test_loss_list = []
test_acc_list = []
train_time = 0
model_save_path = '1DCNN-modelpth/'
os.makedirs(model_save_path, exist_ok=True)
for epoch in range(args.epochs):
tic = time.time()
train_predict = []
train_label = []
runloss = 0
for (cnt, i) in enumerate(tqdm(train_loader)):
batch_x = i['data']
batch_y = i['label']
batch_x = torch.unsqueeze(batch_x, dim=1)
batch_x = batch_x.float()
if torch.cuda.is_available():
batch_x = batch_x.cuda()
batch_y = batch_y.cuda()
tlabels, tpredi, tloss = train(model, batch_x, batch_y, optimizer, criterion)
runloss = runloss + tloss
train_label.extend(tlabels)
train_predict.extend(tpredi)
per_epoch_train_time = time.time() - tic
train_time = per_epoch_train_time + train_time
taccuracy = accuracy_score(train_label, train_predict)
train_acc_list.append(taccuracy)
loss = runloss / batches_per_epoch
train_loss_list.append(loss)
acc_score, loss_score, feature_list, C = test(model, test_loader, criterion)
print('Epoch %d Val_accuracy %.3f Val_loss %.3f' % (epoch, acc_score, loss_score))
with open('Gmlp_train_log.csv', 'a+') as f:
f.write(f'{epoch}, {round(taccuracy, 4)}, {round(loss, 4)}
') f.close() with open('Gmlp_log.csv', 'a+')as f: f.write(f'{epoch}, {round(acc_score, 4)}, {round(loss_score, 4)} ') f.close() test_acc_list.append(acc_score) test_loss_list.append(loss_score)
if epoch % 1 == 0:
torch.save(model, f'1DCNN-modelpth/{epoch}.pth')
if epoch == args.epochs - 1: # 训练到最后一轮
torch.save(model, '1DCNN-modelpth/final.pth')
the_model = torch.load('./1DCNN-modelpth/final.pth')
acc_score, loss_score, NAR, featucre_list = test(the_model, test_loader, criterion)
#print('Epoch %d Train_accuracy %.3f Train_loss %.3f Val_accuracy %.3f Val_loss %.3f NAR %.3f ' % (epoch, taccuracy, loss, acc_score, loss_score, NAR))
print(f'Epoch {epoch} Train_accuracy {taccuracy} Train_loss {loss} Val_accuracy {acc_score} Val_loss {loss_score} NAR {NAR}')
feature_list = feature_list.detach().cpu().numpy()
np.savetxt('Gmlp.csv', feature_list, delimiter=',') # 保存特征向量
draw_result(C)
print('train totally using %.3f seconds ' % train_time)
draw(train_acc_list, train_loss_list, test_acc_list, test_loss_list)
if name == 'main': parser = argparse.ArgumentParser(description='CNN fou classification') '''save model''' parser.add_argument('--save', type=str, default='__', help='path to save model') '''model parameters''' rootpath = 'das_data' parser.add_argument('--root', type=str, default=rootpath + '/train', help='rootpath of traindata') parser.add_argument('--root2', type=str, default=rootpath + '/test', help='rootpath of valdata') parser.add_argument('--txtpath', type=str, default=rootpath + '/train/label.txt', help='path of train_list') parser.add_argument('--txtpath2', type=str, default=rootpath + '/test/label.txt', help='path pf val_list') parser.add_argument('--model', type=str, default='CNN', help='type of model to use for classification') parser.add_argument('--lr', type=float, default=0.01, help='learning rate') parser.add_argument('--epochs', type=int, default=70 , help='number of training epochs') parser.add_argument('--batch_size', type=int, default=100, help='batch size') my_args = parser.parse_args()
main(my_args)
报错RuntimeError: CUDA out of memory. Tried to allocate 184.00 MiB (GPU 0; 14.76 GiB total capacity; 8.33 GiB already allocated; 182.75 MiB free; 8.38 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation. See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF 怎么改内容:这个错误是由于GPU内存不足导致的。可以尝试以下几种解决方法:
-
减少batch_size:将batch_size调小一些,比如减少到50或更小的数值,以减少每个batch所占用的内存。
-
减少模型参数:如果模型比较大,可以尝试减少模型的参数量,比如减少网络层数或减小每层的神经元数量。
-
减小输入数据维度:如果输入数据的维度较高,可以考虑对数据进行降维处理,减小输入数据的维度。
-
使用更小的模型:如果以上方法都无法解决问题,可以尝试使用更小的模型,或者使用更轻量级的模型。
-
使用更高效的算法:有些算法在相同任务下可以使用更少的内存,可以尝试使用更高效的算法。
-
使用更高内存的GPU:如果有条件,可以考虑使用内存更高的GPU来解决该问题。
通过尝试以上方法,应该能够解决CUDA out of memory的问题。
原文地址: https://www.cveoy.top/t/topic/pmos 著作权归作者所有。请勿转载和采集!