基于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都可以解决。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐