在python中用pyTorch实现数字(0~9)语音识别
基于python的数字(0~9)语音识别1.收集训练数据speech_commands_v0.01.tar.gzhttp://download.tensorflow.org/data/speech_commands_v0.01.tar.gz自己用迅雷下载什么都行(推荐迅雷)2.准备环境①pycharm软件②cuda和cudnn(我的是11.3)③python(我的是3.9)④支持cuda的pyto
基于python的数字(0~9)语音识别
1.收集训练数据
speech_commands_v0.01.tar.gz
http://download.tensorflow.org/data/speech_commands_v0.01.tar.gz
自己用迅雷下载什么都行(推荐迅雷)
2.准备环境
①pycharm软件
②cuda和cudnn(我的是11.3)
③python(我的是3.9)
④支持cuda的pytorch
对于环境的准备,老样子,自己csdn查教程一大把。
推荐不要用conda,直接全pip,一步到胃。
Notes:pycharm里的python环境好像是虚拟机的,在cmd装好的环境下,在pycharm里面的控制台再装一次。
3.直接上代码
(1)提取数据并保存
①先把所需数据集(里面包括0-9语音集)保存到dataset文件夹
②获取里面所有文件路径并保存为Spoken_digit_path.csv文件
import os
import csv
digit = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']
d = {}
with open("Spoken_digit_path.csv", 'w') as csvfile:
csvwriter = csv.writer(csvfile)
csvwriter.writerow(["File", "Label"])
for x in digit:
if os.path.isdir('./dataset/' + x):
d[x] = os.listdir('./dataset/' + x)
for name in os.listdir('./dataset/' + x):
if os.path.isfile('./dataset/' + x + "/" + name):
csvwriter.writerow([x + '/' + name, x])
df = pd.read_csv('Spoken_digit_path.csv')
# 随机排列
df = df.sample(frac=1)
df.to_csv('Spoken_digit_path.csv', index=False)
print(df.shape)
③提取特征并保存数据为Spoken_digit_five_fts.csv文件
特征包括:
- Mel Frequency Cepstral Coefficients (MFCCs):根据人类听觉系统的响应(Mel尺度)间隔的频带组成声音的频谱表示的系数。
- Chroma:与12个不同的音高等级有关。
- Mel spectrogram:它的平均值-基于Mel标度的Mel谱图。
- Spectral Contrast:表示谱的质心。
- Tonnetz:代表音调空间。
对所有特征做均值处理,大小为(20,)(12,)(128,)(7,)和(6,)
这些连接起来形成一个大小为(173,)的特征数组。标签被附加到数组的头部,并写入每个记录的CSV文件中。
import librosa
import numpy as np
import pandas as pd
import csv
import os
#创建文件并写相应的格式
csvfile = open("Spoken_digit_five_fts.csv", "w")
csvwriter = csv.writer(csvfile)
csvwriter.writerow(np.concatenate((['Label'], [i for i in range(1, 174)])))
def extract_features(files):
data, sr = librosa.load('./dataset/' + files.File,sr=None)
print(files.File)
mfccs = np.mean(librosa.feature.mfcc(y=data, sr=sr).T, axis=0)
#spectral_centroids = librosa.feature.spectral_centroid(data + 0.01, sr=sr)[0]
stft = np.abs(librosa.stft(data))
chroma = np.mean(librosa.feature.chroma_stft(S=stft, sr=sr).T, axis=0)
mel = np.mean(librosa.feature.melspectrogram(data, sr).T, axis=0)
contrast = np.mean(librosa.feature.spectral_contrast(S=stft, sr=sr).T, axis=0)
tonnetz = np.mean(librosa.feature.tonnetz(y=librosa.effects.harmonic(data), sr=sr).T, axis=0)
# print(mfccs.shape, stft.shape, chroma.shape, mel.shape, contrast.shape, tonnetz.shape)
row = np.concatenate((mfccs, chroma, mel, contrast, tonnetz), axis = 0).astype('float32')
csvwriter.writerow(np.concatenate(([digit.index(files.Label)], row)))
sp = pd.read_csv("Spoken_digit_path.csv")
#最关键这个apply函数,sp读取了所有数据集路径,
#apply(extract_features, axis=1),把路径当做参数传进extract_features运行。
sp.apply(extract_features, axis=1)
Notes:
①上面两段代码可以放到一个文件data_process.py执行
②跑这段代码至少都要一个半小时。(如果有GPU形式请积极提供)
(2)训练模型
Notes:所需的python库
import torch
import torch.nn as nn
import torch.nn.functional as F
import pandas as pd
from sklearn.model_selection import train_test_split
import torch.utils.data as Data
from sklearn.preprocessing import StandardScaler
①模型代码
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.l1 = nn.Linear(173, 1024)
self.l2 = nn.Linear(1024, 512)
self.l3 = nn.Linear(512, 64)
self.l4 = nn.Linear(64, 10)
def forward(self, x):
x = F.relu(self.l1(x))
x = F.relu(self.l2(x))
x = F.relu(self.l3(x))
x = self.l4(x)
return x
②加载特征数据
def load_data(file):
sp = pd.read_csv(file)
# print(sp)
data, label = sp.drop(['Label'], axis=1), sp['Label']
print(data)
data = data.values.astype('float32')
label = label.values
scale = StandardScaler()
#fit()求训练集的均值、方差、最大值、最小值等训练集固有的属性。
#transform()在fit的基础上,进行标准化,降维,归一化等操作
#fit_transform是fit和transform的组合
data = scale.fit_transform(data)
data = torch.from_numpy(data)
label = torch.from_numpy(label).long()
return data, label
③训练模型
def train_model(data, label, lr, batch_size, epoch):
net = Net()
net = net.cuda()
print(net)
LR = lr
BATCH_SIZE = batch_size
EPOCH = epoch
optimizer = torch.optim.SGD(net.parameters(), lr=LR)
torch_dataset = Data.TensorDataset(data, label)
loader = Data.DataLoader(
dataset=torch_dataset,
batch_size=BATCH_SIZE,
shuffle=True,
)
for epoch in range(EPOCH):
for step, (batch_data, batch_label) in enumerate(loader):
print('Epoch:', epoch + 1, '/', EPOCH, 'Step:', step)
prediction = net(batch_data)
loss = F.cross_entropy(prediction, batch_label)
optimizer.zero_grad()
loss.backward()
optimizer.step()
_, pred = torch.max(prediction, 1)
accuracy = torch.sum(pred == batch_label).item() / len(pred)
print('Accuracy:', accuracy)
return net
④保存模型
def save_model(net, file):
# 保存整个模型
torch.save(net, file)
# 保存模型参数
# torch.save(net.state_dict(),file)
⑤加载模型
def restore_net(file):
net = torch.load(file)
return net
⑥测试模型
def test_model(net, data, label):
prediction = net(data)
_, pred = torch.max(prediction, 1)
accuracy = torch.sum(pred == label).item() / len(pred)
print("test_Accuracy:", accuracy)
⑦主程序
data, label = load_data("Spoken_digit_five_fts.csv")
#用GPU加速
data = data.cuda()
label = label.cuda()
#训练:测试=7:3
train_data, test_data, train_label, test_label = train_test_split(data, label, test_size=0.3, random_state=0)
print(train_data.shape)
print(test_data.shape)
#训练模型
net = train_model(data=train_data, label=train_label, lr=0.3, batch_size=512, epoch=64)
#保存模型
save_model(net, 'net.pkl')
#加载模型
net=restore_net('net.pkl')
#测试模型
test_model(net, test_data, test_label)
Notes:
①(2)的所有代码可以保存为model.py直接运行(这里就不提供完整代码,让你们分段理解)
②用GPU加速基本上几分钟就能训练出来,特快超爽
4.总结
①最终训练出来的模型测试集识别率大概在0.7左右
②网上大神另外用了CNN训练可以得到0.9以上的识别率(你们自行去研究)
③如果出现什么奇怪bug,自己csdn都可以解决。
更多推荐
所有评论(0)