import IPython.display as ipd
import librosa
import glob
import os
import pandas as pd
import random
import librosa.display
import matplotlib.pyplot as plt
import numpy as np
from sklearn.preprocessing import LabelEncoder
from keras.utils import np_utils
from torch.utils.data import Dataset,DataLoader,TensorDataset
import torch
import torch.nn.functional as F
import torch.nn as nn
import torch.optim as optim
import pickle
train=pd.read_csv("train/train.csv",sep=',')
提取音频数据的特征的方式有很多,我这里比较简单用的是mfcc,固定40个
train.apply是pandas中批处理的一个方法,会返回一个pandas.DataFrame对象,里面存放着feature和label
def parser(row):
file_name=os.path.join('train','Train',str(row.ID)+'.wav')
try:
x,sample_rate=librosa.load(file_name)
mfccs = np.mean(librosa.feature.mfcc(y=x, sr=sample_rate, n_mfcc=40).T,axis=0)
except Exception as e:
print("error",file)
return None,None
features=mfccs
label=row.Class
return [features,label]
temp=train.apply(parser,axis=1,result_type='expand')
class Dataset(Dataset):
def __init__(self,x,y,use_gpu):
self.x=torch.tensor(x)
self.y=torch.tensor(y)
if use_gpu:
self.x=self.x.to("cuda")
self.y=self.y.to("cuda")
self.len=x.shape[0]
def __getitem__(self,index):
return self.x[index],self.y[index]
def __len__(self):
return self.len
class Classify(nn.Module):
def __init__(self):
super(Classify,self).__init__()
self.fc1=nn.Linear(40,64)
self.dp=nn.Dropout(0.03)
self.fc2=nn.Linear(64,20)
self.fc3=nn.Linear(20,10)
def forward(self,x):
x=F.relu(self.fc1(x))
x=self.dp(x)
x=F.relu(self.fc2(x))
x=F.relu(self.fc3(x))
x=F.softmax(x,dim=1)
return x
def train(train_loader,model,loss_fun,optimizer,epoches,use_gpu):
if use_gpu:
model=model.cuda()
loss_fun=loss_fun.cuda()
acc=0
all_loss=0
for i in range(epoches):
for j,data in enumerate(train_loader):
x,y=data
y_pre=model(x)
# print(y.dtype)
# print(y_pre)
loss=loss_fun(y_pre,y)
all_loss+=loss.item()
values,indices=torch.topk(y_pre,k=1)
values2,indices2=torch.topk(y,k=1)
#print(indices,indices2)
res=(indices==indices2)
acc+=torch.sum(res).item()
optimizer.zero_grad()
loss.backward()
optimizer.step()
print("epoch{}--acc:{}-{:.4%}--loss:{}".format(i,acc,acc/all_data_en,all_loss))
acc=0
all_loss=0
def validate(val_loader,model,use_gpu):
if use_gpu:
model=model.cuda()
model.eval()
acc=0
with torch.no_grad():
for _,(inputs,y) in enumerate(val_loader):
if use_gpu:
inputs=inputs.cuda()
y=y.cuda()
y_pre=model(inputs)
values,indices=torch.topk(y_pre,k=1)
values2,indices2=torch.topk(y,k=1)
res=(indices==indices2)
acc+=torch.sum(res).item()
print("acc:{:.4%}".format(acc/all_data_en))
use_gpu=True if torch.cuda.is_available() else False#是否使用cuda
#use_gpu=False
model=Classify()
optimizer=torch.optim.Adam(model.parameters())#Adam优化器
loss_fun=nn.MSELoss()#均方误差
epoches=100
dataset=Dataset(x,y,use_gpu)
train_loader=DataLoader(dataset,batch_size=6)#batchsize=6
train(train_loader,model,loss_fun,optimizer,epoches,use_gpu)
torch.save(model,"torchmodel.pth")
model=torch.load("torchmodel.pth")
use_gpu=True if torch.cuda.is_available() else False
train_loader=DataLoader(dataset,batch_size=all_data_en)#直接加载全部数据
validate(train_loader,model,use_gpu)