手把手教你:基于TensorFlow的语音识别系统

系列文章

目录

一、项目简介

本文主要介绍如何使用python搭建一个:基于TensorFlow的语音识别系统。

本文主要分为3部分:

  • 1、项目数据集介绍。
  • 2、项目功能及相关代码展示。
  • 3、项目完整下载地址。

博主也参考过语音识别系统相关模型的文章,但大多是理论大于方法。很多同学肯定对原理不需要过多了解,只需要搭建出一个可视化系统即可。

正是因为我发现,大部分的网帖都只是针对原理的介绍,实现功能的相对较少。

[En]

It is precisely because I found that most of the online posts are only for the introduction of the principle, the realization of the function is relatively few.

如果你有以上想法,那你来对地方了!

[En]

If you have the above ideas, you are in the right place!

别说太多废话了,开门见山吧!

[En]

Don’t talk too much nonsense, just get to the point!

二、语音数据集介绍

本项目使用不同英语单词和不同语言发音的电信号采样数据。

[En]

This project uses electrical signal sampling data of different English words and different people’s language pronunciation.

1.不同人的声音

  • 三个不同人的声音:

手把手教你:基于TensorFlow的语音识别系统

; 2.每人不同单词的发音

  • 每个人不同单词的发音:

手把手教你:基于TensorFlow的语音识别系统

3.声音波形

  • 单词”CAMARA”:
    手把手教你:基于TensorFlow的语音识别系统
  • 单词”WELCOME”:
    手把手教你:基于TensorFlow的语音识别系统

; 三、代码功能介绍

项目思路是:
1.将不同单词的发音文件分类。
2.将音频文件进行分帧。
3.实现mfcc编码。
4.构建训练及测试数据。
5.送入模型进行分类训练。
6.验证训练结果

1.依赖环境及项目目录

1.TensorFlow-GPU,版本:2.0及以上
2. librosa
3. sklearn

; 2.数据读取与预处理(data_create.py)

语音数据文件为.data 的时序数据。

def get_voice_vec(path):
"""
    读取文件
    :param path:
    :return:
"""
    with open(path, 'r') as f:

        readData = f.readlines()

        readData_d = readData[9:]
        voice_list = []

        for e in readData_d:

            e_s = e.replace('\n', '').split('\t')
            voice = e_s[2]
            voice_list.append(float(voice))
    return_list = voice_list
    return return_list

3.语音数据分帧及mfcc处理(data_create.py)

使用librosa对语音数据文件进行分帧和mfcc处理

def vec_label(in_vec, in_label, cut_length=20000, sap_num=50):
"""
    数据截取,生成训练数据
    :return:
"""
    print("读取的数据文件数量:", len(in_vec))
    print("开始处理数据分割......")

    train_data = []
    train_label = []
    for org_vec, org_label in tqdm(zip(in_vec, in_label)):
        head_vec = org_vec[:cut_length]
        end_vec = org_vec[len(org_vec) - cut_length:]

        cuted_vec = org_vec[20000:len(org_vec) - 20000]

        '''
        # 添加无语音块
        train_data.append(head_vec)
        train_label.append("-1")
        train_data.append(end_vec)
        train_label.append("-1")

        # 语音数据分割采样
        cut_time = int(len(cuted_vec) / cut_length)
        for i in range(0, cut_time):
            cut_vec = cuted_vec[i * cut_length: (i + 1) * cut_length]
            train_data.append(cut_vec)
            train_label.append(org_label)
        '''
        for i in range(0, sap_num):

            start_index = int(random.uniform(0, len(cuted_vec) - cut_length))

            cut_vec = cuted_vec[start_index:start_index + cut_length]
            train_data.append(cut_vec)
            train_label.append(org_label)

    print("完成数据分割和采样!")

    train_label = change_label(train_label, "train_data/label_class.npy")
    print("完成分类类别编码!")

    train_data = np.asarray(train_data, np.float64)
    train_label = np.asarray(train_label, np.int64)
    print("完成numpy数组转换!")

    train_data = extract_features(train_data)
    print("完成mfcc编码!")
    train_data, train_label = random_data(train_data, train_label)
    print("完成数据打乱!")

    return train_data, train_label

4.模型构建(model.py)

使用TensorFlow对模型进行构建,本文构建的是基于残差模块的cnn网络。

    def __init__(self, input_shape=(512, 512, 3), classes=2):
        self.input_shape = input_shape
        self.classes = classes

    def identity_block(self, X, f, filters, stage, block):
"""
        三层的恒等残差块
        param :
            X -- 输入的张量,维度为(m, n_H_prev, n_W_prev, n_C_prev)
            f -- 整数,指定主路径的中间 CONV 窗口的形状
            filters -- python整数列表,定义主路径的CONV层中的过滤器数目
            stage -- 整数,用于命名层,取决于它们在网络中的位置
            block --字符串/字符,用于命名层,取决于它们在网络中的位置
        return:
            X -- 三层的恒等残差块的输出,维度为:(n_H, n_W, n_C)
"""

        conv_name_base = "res" + str(stage) + block + "_branch"
        bn_name_base = "bn" + str(stage) + block + "_branch"

        F1, F2, F3 = filters

        X_shortcut = X

        X = layers.Conv2D(filters=F1, kernel_size=(1, 1), strides=(1, 1), padding="valid",
                          name=conv_name_base + "2a", kernel_initializer=keras.initializers.glorot_uniform(seed=0))(X)
        X = layers.BatchNormalization(axis=3, name=bn_name_base + "2a")(X)
        X = layers.Activation("relu")(X)

        X = layers.Conv2D(filters=F2, kernel_size=(f, f), strides=(1, 1), padding="same",
                          name=conv_name_base + "2b", kernel_initializer=keras.initializers.glorot_uniform(seed=0))(X)
        X = layers.BatchNormalization(axis=3, name=bn_name_base + "2b")(X)
        X = layers.Activation("relu")(X)

        X = layers.Conv2D(filters=F3, kernel_size=(1, 1), strides=(1, 1), padding="valid",
                          name=conv_name_base + "2c", kernel_initializer=keras.initializers.glorot_uniform(seed=0))(X)
        X = layers.BatchNormalization(axis=3, name=bn_name_base + "2c")(X)

        X = layers.Add()([X, X_shortcut])
        X = layers.Activation("relu")(X)
        return X

    def convolutional_block(self, X, f, filters, stage, block, s=2):
"""
        param :
        X -- 输入的张量,维度为(m, n_H_prev, n_W_prev, n_C_prev)
        f -- 整数,指定主路径的中间 CONV 窗口的形状(过滤器大小,ResNet中f=3)
        filters -- python整数列表,定义主路径的CONV层中过滤器的数目
        stage -- 整数,用于命名层,取决于它们在网络中的位置
        block --字符串/字符,用于命名层,取决于它们在网络中的位置
        s -- 整数,指定使用的步幅
        return:
        X -- 卷积残差块的输出,维度为:(n_H, n_W, n_C)
"""

        conv_name_base = "res" + str(stage) + block + "_branch"
        bn_name_base = "bn" + str(stage) + block + "_branch"

        F1, F2, F3 = filters

        X_shortcut = X

        X = layers.Conv2D(filters=F1, kernel_size=(1, 1), strides=(s, s), padding="valid",
                          name=conv_name_base + "2a", kernel_initializer=keras.initializers.glorot_uniform(seed=0))(X)
        X = layers.BatchNormalization(axis=3, name=bn_name_base + "2a")(X)
        X = layers.Activation("relu")(X)

        X = layers.Conv2D(filters=F2, kernel_size=(f, f), strides=(1, 1), padding="same",
                          name=conv_name_base + "2b", kernel_initializer=keras.initializers.glorot_uniform(seed=0))(X)
        X = layers.BatchNormalization(axis=3, name=bn_name_base + "2b")(X)
        X = layers.Activation("relu")(X)

        X = layers.Conv2D(filters=F3, kernel_size=(1, 1), strides=(1, 1), padding="valid",
                          name=conv_name_base + "2c", kernel_initializer=keras.initializers.glorot_uniform(seed=0))(X)
        X = layers.BatchNormalization(axis=3, name=bn_name_base + "2c")(X)

        X_shortcut = layers.Conv2D(filters=F3, kernel_size=(1, 1), strides=(s, s), padding="valid",
                                   name=conv_name_base + "1",
                                   kernel_initializer=keras.initializers.glorot_uniform(seed=0))(X_shortcut)
        X_shortcut = layers.BatchNormalization(axis=3, name=bn_name_base + "1")(X_shortcut)

        X = layers.Add()([X, X_shortcut])
        X = layers.Activation("relu")(X)

        return X

5.模型训练(model_train.py)

本次项目设置的同时输入语音数据: batch_size = 16。训练轮数: num_epochs = 10。初始化学习率参数: learning_rate = 1e-4。训练结果如下:

手把手教你:基于TensorFlow的语音识别系统

; 6.模型评估(model_test.py)

针对13个不同人的发音的单词进行训练后测试模型分类的准确率。

手把手教你:基于TensorFlow的语音识别系统
  • 可见该模型的精确度较高
    [En]

    it can be seen that the accuracy of the model is relatively high.*

7.模型训练可视化

  • 可以看到在模型训练至 2-3个epoch左右的时候模型接近收敛。

手把手教你:基于TensorFlow的语音识别系统

; 8.模型预测(func_test.py)

  • 最后的功能是读取单个语音数据文件,模型将在预测后输出该文件中的单词。代码和效果如下:
    [En]

    the final function is to read a single voice data file, and the model will output the words in this file after prediction. The code and effect are as follows:*

def get_voice_vec(path):"""    读取文件    :param path:    :return:"""    with open(path, 'r') as f:        readData = f.readlines()        readData_d = readData[9:]        voice_list = []        for e in readData_d:            e_s = e.replace('\n', '').split('\t')            voice = e_s[2]            voice_list.append(float(voice))    return_list = voice_list    cuted_vec = return_list[20000:]    cut_length = 40000    test_data = []    cut_time = int(len(cuted_vec) / cut_length)    for i in range(0, cut_time):        cut_vec = cuted_vec[i * cut_length: (i + 1) * cut_length]        test_data.append(cut_vec)    test_data = extract_features(test_data)    return test_datadef run_classification():    choose_path = get_file_path()    vc = get_voice_vec(choose_path)    print("获取数据文件,mfcc转码成功!")    data = vc.reshape((vc.shape[0], vc.shape[1], vc.shape[2], 1))    print("*" * 10)    print("读取模型......")    model = keras.models.load_model('models_save/resnet_model.h5')    print("加载保存的模型成功!")    print("*" * 10)    print("开始预测......")    y_pred = model.predict(data)    print("*" * 10)    print("模型输出预测结果......")    y_pred = [np.argmax(x) for x in y_pred]    label_class = np.load('train_data/label_class.npy')    y_pred_e = []    for e in y_pred:        y_pred_e.append(label_class[e])    print("您选择的语音文件对应的单词为:", y_pred_e)
  • 模型测试效果:
    手把手教你:基于TensorFlow的语音识别系统

四、代码下载地址

由于项目代码和数据集庞大,有兴趣的学生可以直接下载代码。如果你在评论区遇到任何问题,我会一一回答。

[En]

Due to the large amount of project code and data set, interested students can download the code directly. If you encounter any questions in the comments area, I will answer them one by one.

代码下载:

Original: https://blog.csdn.net/weixin_43486940/article/details/123866074
Author: 大雾的小屋
Title: 手把手教你:基于TensorFlow的语音识别系统

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/496687/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球