likes
comments
collection
share

从零搭建——基于HMM-GMM的语音识别模型构建

作者站长头像
站长
· 阅读数 33

从零搭建——基于HMM-GMM的语音识别模型构建

HMM-GMM(Hidden Markov Model - Gaussian Mixture Model)是语音识别中的经典模型之一。它结合了隐马尔可夫模型(HMM)和高斯混合模型(GMM)的优点,用于建模语音信号的时间序列特性和观测值的概率分布。

原理

隐马尔可夫模型(HMM)

隐马尔可夫模型(HMM, Hidden Markov Model)是一种统计模型,用于描述一个系统通过一系列隐状态(hidden states)生成观测数据(observations)的过程。在HMM中,我们假设:

  • 系统在任何时刻 ttt 的状态 StS_tSt 是一个离散的随机变量,取值范围为 {1,2,...,N}\{1, 2, ..., N\}{1,2,...,N}
  • 在时刻 ttt 的状态 StS_tSt 只依赖于前一时刻的状态 St−1S_{t-1}St1(即一阶马尔可夫性质)。
  • 在时刻 ttt 的观测 OtO_tOt 只依赖于当前的状态 StS_tSt
  1. 状态集合 S={s1,s2,…,sN}S = \{s_1, s_2, \ldots, s_N\}S={s1,s2,,sN} :表示系统可能的状态。

  2. 观测集合 V={v1,v2,…,vM}V = \{v_1, v_2, \ldots, v_M\}V={v1,v2,,vM} :表示系统可能的观测值。

  3. 状态转移概率矩阵 A={aij}A = \{a_{ij}\}A={aij} :表示从状态 sis_isi 转移到状态 sjs_jsj 的概率。

    aij=P(qt+1=sj∣qt=si),1≤i,j≤Na_{ij} = P(q_{t+1} = s_j \mid q_t = s_i), \quad 1 \leq i, j \leq Naij=P(qt+1=sjqt=si),1i,jN

  4. 观测概率矩阵 B={bj(ot)}B = \{b_j(o_t)\}B={bj(ot)} :表示在状态 sjs_jsj 下生成观测值 oto_tot 的概率。

    bj(ot)=P(ot∣qt=sj),1≤j≤Nb_j(o_t) = P(o_t \mid q_t = s_j), \quad 1 \leq j \leq Nbj(ot)=P(otqt=sj),1jN

  5. 初始状态概率向量 π={πi}\pi = \{\pi_i\}π={πi} :表示系统初始处于状态 sis_isi 的概率。

    πi=P(q1=si),1≤i≤N\pi_i = P(q_1 = s_i), \quad 1 \leq i \leq Nπi=P(q1=si),1iN

高斯混合模型(GMM)

高斯混合模型(GMM, Gaussian Mixture Model)是一种概率模型,用于表示一个由多个高斯分布(正态分布)混合而成的复杂分布。在语音识别中,我们通常使用GMM来建模在某一状态下的观测概率。

一个GMM由以下参数定义:

  • 混合权重 {wk}\{w_k\}{wk},其中 wkw_kwk 表示第 kkk 个高斯分量的权重,满足 ∑k=1Kwk=1\sum_{k=1}^K w_k = 1k=1Kwk=1
  • 高斯分量的均值向量 {μk}\{\mu_k\}{μk} 和协方差矩阵 {Σk}\{\Sigma_k\}{Σk}

GMM的概率密度函数(pdf)表示为:

p(o)=∑k=1KwkN(o∣μk,Σk)p(o) = \sum_{k=1}^K w_k \mathcal{N}(o | \mu_k, \Sigma_k)p(o)=k=1KwkN(oμk,Σk)

其中 N(o∣μk,Σk)\mathcal{N}(o | \mu_k, \Sigma_k)N(oμk,Σk)表示第 kkk 个高斯分量的pdf,其形式为:

N(o∣μk,Σk)=1(2π)d/2∣Σk∣1/2exp⁡(−12(o−μk)TΣk−1(o−μk))\mathcal{N}(o | \mu_k, \Sigma_k) = \frac{1}{(2\pi)^{d/2} |\Sigma_k|^{1/2}} \exp\left( -\frac{1}{2} (o - \mu_k)^T \Sigma_k^{-1} (o - \mu_k) \right)N(oμk,Σk)=(2π)d/2Σk1/21exp(21(oμk)TΣk1(oμk))

其中 ddd 是观测向量 ooo 的维数。

对于每个状态sjs_jsj,其观测概率 bj(ot)b_j(o_t)bj(ot)可表示为多个高斯分布的线性组合:

bj(ot)=∑m=1Mcjm⋅N(ot;μjm,Σjm)b_j(o_t) = \sum_{m=1}^M c_{jm} \cdot \mathcal{N}(o_t; \mu_{jm}, \Sigma_{jm})bj(ot)=m=1McjmN(ot;μjm,Σjm)

其中, cjmc_{jm}cjm 是混合权重,满足 ∑m=1Mcjm=1\sum_{m=1}^M c_{jm} = 1m=1Mcjm=1N(ot;μjm,Σjm)\mathcal{N}(o_t; \mu_{jm}, \Sigma_{jm})N(ot;μjm,Σjm) 是均值为 μjm\mu_{jm}μjm、协方差为 Σjm\Sigma_{jm}Σjm 的多维高斯分布。

HMM-GMM语音识别模型构建

1. 数据预处理

1.1 语音信号分帧

语音信号是一个连续的时间序列,首先需要将其分割成短时帧。每帧通常包含10到30毫秒的语音数据,并且相邻帧之间有部分重叠(通常为50%重叠)。

假设语音信号为 x(t)x(t)x(t),我们可以用一个滑动窗口函数w(t)w(t)w(t) 对其分帧:

xn(t)=x(t)w(t−nT)x_n(t) = x(t) w(t - nT)xn(t)=x(t)w(tnT)其中 TTT 是帧移。

1.2 特征提取

对每一帧提取特征向量,常用的方法是梅尔频率倒谱系数(MFCC)或线性预测倒谱系数(LPCC)。

以MFCC为例,其计算步骤如下:

  • 傅里叶变换:计算每一帧的快速傅里叶变换(FFT):

    Xk=∑n=0N−1xne−j2πNknX_k = \sum_{n=0}^{N-1} x_n e^{-j \frac{2\pi}{N} kn}Xk=n=0N1xnejN2πkn

    其中 NNN 是帧长, kkk 是频率索引。

  • 梅尔滤波器组:应用梅尔滤波器组,将频域信号转换到梅尔频率尺度。

  • 对数能量:对每个滤波器输出取对数能量。

  • 离散余弦变换(DCT) :对对数能量进行离散余弦变换,得到MFCC。

2. 模型构建

2.1 HMM模型结构

选择适当的HMM结构,例如每个音素用一个HMM模型表示,每个HMM有多个状态(通常是3到5个状态)。

2.2 GMM参数

在每个HMM状态下,用GMM表示观测概率密度函数。设第 jjj 个状态的观测概率密度函数为:

bj(o)=∑k=1KwjkN(o∣μjk,Σjk)b_j(o) = \sum_{k=1}^K w_{jk} \mathcal{N}(o | \mu_{jk}, \Sigma_{jk})bj(o)=k=1KwjkN(oμjk,Σjk)

其中 KKK 是高斯分量的个数, wjkw_{jk}wjk 是第 kkk 个高斯分量的权重, μjk\mu_{jk}μjk 是均值向量, Σjk\Sigma_{jk}Σjk 是协方差矩阵。

3. 模型训练

3.1 Baum-Welch算法

使用Baum-Welch算法(EM算法)来训练HMM-GMM模型。具体步骤如下:

E步(期望步) : 计算前向概率 αt(i)\alpha_t(i)αt(i) 和后向概率 βt(i)\beta_t(i)βt(i)

αt(i)=P(O1,O2,...,Ot,St=i∣λ)\alpha_t(i) = P(O_1, O_2, ..., O_t, S_t = i | \lambda)αt(i)=P(O1,O2,...,Ot,St=iλ)

βt(i)=P(Ot+1,Ot+2,...,OT∣St=i,λ)\beta_t(i) = P(O_{t+1}, O_{t+2}, ..., O_T | S_t = i, \lambda)βt(i)=P(Ot+1,Ot+2,...,OTSt=i,λ)

计算状态概率 γt(i)\gamma_t(i)γt(i) 和状态转移概率 ξt(i,j)\xi_t(i, j)ξt(i,j)

γt(i)=αt(i)βt(i)∑j=1Nαt(j)βt(j)\gamma_t(i)=\frac{\alpha_t(i)\beta_t(i)}{\sum_{j=1}^N\alpha_t(j)\beta_t(j)} γt(i)=j=1Nαt(j)βt(j)αt(i)βt(i)

ξt(i,j)=αt(i)aijbj(Ot+1)βt+1(j)∑i=1N∑j=1Nαt(i)aijbj(Ot+1)βt+1(j)\xi_t(i,j)=\frac{\alpha_t(i)a_{ij}b_j(O_{t+1})\beta_{t+1}(j)}{\sum_{i=1}^N\sum_{j=1}^N\alpha_t(i)a_{ij}b_j(O_{t+1})\beta_{t+1}(j)}ξt(i,j)=i=1Nj=1Nαt(i)aijbj(Ot+1)βt+1(j)αt(i)aijbj(Ot+1)βt+1(j)

M步(最大化步) : 更新模型参数 λ(n+1)\lambda^{(n+1)}λ(n+1)

πi(n+1)=γ1(i)aij(n+1)=∑t=1T−1ξt(i,j)∑t=1T−1γt(i)wjk(n+1)=∑t=1Tγt(k)Tμjk(n+1)=∑t=1Tγt(k)Ot∑t=1Tγt(k)Σjk(n+1)=∑t=1Tγt(k)(Ot−μjk(n+1))(Ot−μjk(n+1))T∑t=1Tγt(k)\begin{aligned} &\pi_{i}^{(n+1)}=\gamma_{1}(i) \\ &a_{ij}^{(n+1)}=\frac{\sum_{t=1}^{T-1}\xi_t(i,j)}{\sum_{t=1}^{T-1}\gamma_t(i)} \\ &w_{jk}^{(n+1)}=\frac{\sum_{t=1}^T\gamma_t^{(k)}}T \\ &\mu_{jk}^{(n+1)}=\frac{\sum_{t=1}^{T}\gamma_{t}^{(k)}O_{t}}{\sum_{t=1}^{T}\gamma_{t}^{(k)}} \\ &\Sigma_{jk}^{(n+1)}=\frac{\sum_{t=1}^{T}\gamma_{t}^{(k)}(O_{t}-\mu_{jk}^{(n+1)})(O_{t}-\mu_{jk}^{(n+1)})^{T}}{\sum_{t=1}^{T}\gamma_{t}^{(k)}} \end{aligned}πi(n+1)=γ1(i)aij(n+1)=t=1T1γt(i)t=1T1ξt(i,j)wjk(n+1)=Tt=1Tγt(k)μjk(n+1)=t=1Tγt(k)t=1Tγt(k)OtΣjk(n+1)=t=1Tγt(k)t=1Tγt(k)(Otμjk(n+1))(Otμjk(n+1))T

4. 语言模型与字典

4.1 语言模型

语言模型(LM, Language Model)用来描述词序列的概率分布,常用的是n-gram模型。n-gram模型的形式为:

P(w1,w2,...,wN)=∏i=1NP(wi∣wi−n+1,...,wi−1)P(w_1, w_2, ..., w_N) = \prod_{i=1}^N P(w_i | w_{i-n+1}, ..., w_{i-1})P(w1,w2,...,wN)=i=1NP(wiwin+1,...,wi1)

4.2 字典

字典(Lexicon)是词汇表,包括每个词的发音。每个词由音素序列表示。

5. 解码

解码是将观测序列转化为词序列的过程。通常使用Viterbi算法结合语言模型进行解码。

5.1 Viterbi算法

Viterbi算法用于寻找最可能的状态序列 Q=(q1,q2,...,qT)Q = (q_1, q_2, ..., q_T)Q=(q1,q2,...,qT)

Q∗=argmaxQ​P(Q∣O,λ)Q^{*}=argmaxQ​P(Q∣O,λ)Q=argmaxQP(QO,λ)

其递推关系为:

δt(j)=max⁡1≤i≤N[δt−1(i)aij]bj(Ot)ψt(j)=arg⁡max⁡1≤i≤N[δt−1(i)aij]\delta_{t}(j)=\max_{1\leq i\leq N}[\delta_{t-1}(i)a_{ij}]b_j(O_t)\\\psi_{t}(j)=\arg\max_{1\leq i\leq N}[\delta_{t-1}(i)a_{ij}]δt(j)=max1iN[δt1(i)aij]bj(Ot)ψt(j)=argmax1iN[δt1(i)aij]

最终路径通过回溯得到:

qT∗=arg⁡max⁡1≤i≤NδT(i)qt∗=ψt+1(qt+1∗)\begin{aligned}&q_{T}^{*}=\arg\max_{1\leq i\leq N}\delta_T(i)\\&q_{t}^{*}=\psi_{t+1}(q_{t+1}^*)\end{aligned}qT=arg1iNmaxδT(i)qt=ψt+1(qt+1)

5.2 结合语言模型的解码

在解码过程中,结合语言模型对路径概率进行调整。设语言模型的概率为 PLM(W)P_{LM}(W)PLM(W),则解码目标为:

W∗=arg⁡max⁡WP(O∣W,λ)PLM(W)W^*=\arg\max_WP(O|W,\lambda)P_{LM}(W)W=argmaxWP(OW,λ)PLM(W)

可以使用加权组合的方式:

log⁡P(W∣O,λ)+αlog⁡PLM(W)\begin{matrix}\log P(W|O,\lambda)+\alpha\log P_{LM}(W)\end{matrix}logP(WO,λ)+αlogPLM(W)

其中 α\alphaα 是调节参数。

系统实现

要求:

  1. Python 3 并安装相应库

  2. kenlm 语言模型安装应用

  3. CMU 发音词典

  4. LibriSpeech 数据集训练

  5. Linux OS

  • 数据预处理

    • 分帧并提取MFCC特征。

    • 将特征存储为文件以便后续使用。

      使用python_speech_features库提取梅尔频率倒谱系数(MFCC)特征:

import os
from scipy.io import wavfile
import numpy as np
from python_speech_features import mfcc
from sklearn.preprocessing import StandardScaler
import soundfile as sf
import pickle

def extract_mfcc_from_flac(file_path, numcep=13):
    signal, sample_rate = sf.read(file_path)
    mfcc_features = mfcc(signal, samplerate=sample_rate, numcep=numcep)
    return mfcc_features

def get_all_flac_files(data_dir):
    flac_files = []
    for root, dirs, files in os.walk(data_dir):
        for file in files:
            if file.endswith('.flac'):
                flac_files.append(os.path.join(root, file))
    return flac_files

def load_librispeech_data(data_dir):
    flac_files = get_all_flac_files(data_dir)
    mfcc_features_list = [extract_mfcc_from_flac(file) for file in flac_files]
    return mfcc_features_list

LIBRISPEECH_DIR = '/path/to/LibriSpeech/train-clean-100/'  
mfcc_features_list = load_librispeech_data(LIBRISPEECH_DIR)

# 保存 mfcc_features_list 到文件
with open('mfcc_features_list.pkl', 'wb') as f:
    pickle.dump(mfcc_features_list, f)

# 加载特征和长度信息
X = np.concatenate(mfcc_features_list)
lengths = [len(x) for x in mfcc_features_list]
  • 语言模型与字典

  • 加载预训练的语言模型(KenLM)。

import kenlm

# 加载预训练的语言模型
lm = kenlm.Model('3-gram.pruned.1e-7.arpa')
  • 加载CMU发音词典,并生成状态到音素的映射。
# 加载CMU发音词典
def load_cmudict(file_path):
    cmudict = {}
    phonemes = set()
    with open(file_path, 'r', encoding='ISO-8859-1') as f:
        for line in f:
            if line.startswith(';;;'):
                continue
            parts = line.strip().split('  ')
            word = parts[0]
            phoneme_seq = parts[1].split()
            cmudict[word] = phoneme_seq
            phonemes.update(phoneme_seq)
    return cmudict, list(phonemes)

# 提取音素集合
cmudict, phonemes = load_cmudict('cmudict-0.7b')


# 生成状态到音素的映射
def generate_state_to_phoneme_mapping(phonemes):
    state_to_phoneme = {i: phoneme for i, phoneme in enumerate(phonemes)}
    return state_to_phoneme

state_to_phoneme = generate_state_to_phoneme_mapping(phonemes)
  • 模型构建

    • 初始化HMM模型,设置状态数和混合高斯数。
from hmmlearn import hmm

# 设置模型参数
num_mixtures = 3  # 初始混合数,可以根据需要调整
num_states = len(phonemes)  # 使用音素的数量作为状态数

# 初始化并训练HMM-GMM模型
model = hmm.GMMHMM(n_components=num_states, n_mix=num_mixtures, covariance_type='diag', n_iter=200, init_params='mct')
  • 模型训练

    • 使用Baum-Welch算法训练HMM-GMM模型。
model.fit(X, lengths)
  • 解码

    • 使用Viterbi算法结合语言模型进行解码。
# 改进后的解码函数
def decode(features, hmm_model, lm_model, cmudict, state_to_phoneme):
    log_likelihood, state_sequence = hmm_model.decode(features, algorithm='viterbi')
    phoneme_sequence = [state_to_phoneme[state] for state in state_sequence]

    best_sequence = []
    phoneme_str = ' '.join(phoneme_sequence)
    word_candidates = []

    for word, phonemes in cmudict.items():
        phoneme_pattern = ' '.join(phonemes)
        if phoneme_pattern in phoneme_str:
            word_candidates.append((word, phoneme_pattern))

    word_candidates.sort(key=lambda x: len(x[1]), reverse=True)
    used_phonemes = set()
    for word, phoneme_pattern in word_candidates:
        if all(phoneme in phoneme_str for phoneme in phoneme_pattern.split()) and not used_phonemes.intersection(phoneme_pattern.split()):
            best_sequence.append(word)
            used_phonemes.update(phoneme_pattern.split())

    sequence_str = ' '.join(best_sequence)
    score = lm_model.score(sequence_str)
    
    return best_sequence, score

# 进行解码
decoded_sequence, decoded_score = decode(mfcc_features_list[0], model, lm, cmudict, state_to_phoneme)

print("Decoded sequence:", decoded_sequence)
print("Decoded score:", decoded_score)

补充

KenLM语言模型

KenLM 是一个用于快速语言模型训练和查询的工具,特别适用于自然语言处理和语音识别任务。

1. 安装 KenLM

安装依赖项: 在安装 KenLM 之前,需要确保系统上安装了一些必要的依赖项。可以使用以下命令安装:

sudo apt-get update
sudo apt-get install build-essential cmake libboost-system-dev libboost-thread-dev libboost-program-options-dev libboost-test-dev libboost-all-dev

克隆 KenLM 仓库: 从 GitHub 克隆 KenLM 的源码:

git clone https://github.com/kpu/kenlm.git
cd kenlm

编译 KenLM

mkdir build
cd build
cmake ..
make -j4

-j4 选项用于并行编译,可以根据 CPU 核心数进行调整。

2. 确认编译成功及使用

lmplz是否可用

首先,请确认 KenLM 已成功编译。检查 build/bin 目录下是否有可执行文件 lmplz

cd ~/ASR/kenlm/build/bin
ls

样例1:

cd ~/ASR/kenlm/build/bin
./lmplz -o 5 < ../../data.txt > ../../model.arpa
  • bin/lmplz 是可执行文件的路径。

  • -o 5 指定了 n-gram 模型的阶数,这里是 5-gram 模型。

  • < data.txt 表示将 data.txt 文件的内容作为输入。

  • > model.arpa 表示将输出写入 model.arpa 文件。

样例2:

cd ~/ASR/kenlm/build/bin
echo "hello world hello world hello" | ./lmplz -o 5 --discount_fallback > ../../model.arpa

检查 build_binary 可执行文件

确认 build_binary 可执行文件是否存在:

ls ~/ASR/kenlm/build/bin

如果 build_binary 文件存在,可以运行以下命令将 ARPA 模型转换为二进制格式:

cd ~/ASR/kenlm/build/bin
./build_binary ../../model.arpa ../../model.binary

使用 query 工具查询模型

如果 query 工具存在,可以用以下命令查询模型:

cd ~/ASR/kenlm/build/bin
./query ../../model.binary

回到kenlm文件夹,选择需要的python环境进行安装

python setup.py install

安装完成后可以在vscode 中 调用 kenlm

import kenlm

# 加载二进制模型
model = kenlm.Model('path/to/model.binary')

# 查询句子的对数概率
sentence = "hello world"
log_prob = model.score(sentence)
print(f"Log probability: {log_prob}")

随后,在OpenSLR上选择一个简单的预训练语言模型:openslr.org

从零搭建——基于HMM-GMM的语音识别模型构建

下载这个 3-gram 语言模型(3-gram.pruned.1e-7.arpa.gz)

下载完成后解压,转成kenlm二进制格式:

build/bin/build_binary 3-gram.pruned.1e-7.arpa 3-gram.pruned.1e-7.binary

在python中加载:

# 加载二进制格式的语言模型 
lm = kenlm.Model('path/to/3-gram.pruned.1e-7.binary')
# 或者加载 ARPA 文件 
# lm = kenlm.Model('path/to/3-gram.pruned.1e-7.arpa')

CMU发音词典

由于语音识别的最终结果应该是对应的文字而不是数字序列。为了将解码后的状态序列映射到文字,需要使用一个词典或发音词典(Lexicon)将HMM的状态或音素序列转换为文字。

在此处下载CMU发音词典(一个英文发音词典,广泛用于语音识别和合成):The CMU Pronouncing Dictionary

下载这个简单的词典:CMUdict/cmudict-0.7b at master · Alexir/CMUdict · GitHub

从零搭建——基于HMM-GMM的语音识别模型构建 使用这个词典的demo:

def load_cmudict(file_path):
    cmudict = {}
    phonemes = set()
    with open(file_path, 'r', encoding='ISO-8859-1') as f:
        for line in f:
            if line.startswith(';;;'):
                continue
            parts = line.strip().split('  ')
            word = parts[0]
            phoneme_seq = parts[1].split()
            cmudict[word] = phoneme_seq
            phonemes.update(phoneme_seq)
    return cmudict, list(phonemes)

# 提取音素集合
cmudict, phonemes = load_cmudict('cmudict-0.7b')

# 打印示例词的发音
print(cmudict.get('HELLO', 'Word not found'))

使用 load_cmudict 函数加载 CMU 发音词典,并将其存储在 cmudict 字典中。

LibriSpeech数据集

在语音识别的研究和应用中,常用的大规模开源数据集可以显著提升模型的性能和稳定性。这些数据集通常包含大量的多样化语音样本,涵盖不同的说话人、环境和背景噪音,能够为模型提供丰富的训练数据。

常用开源数据集

以下是一些主流的开源语音数据集,适用于训练和评估语音识别系统:

  1. LibriSpeech

    • 描述:包含1000小时的英语语音数据,源自LibriVox的有声读物。
    • 链接:LibriSpeech ASR Corpus
  2. Common Voice

    • 描述:由Mozilla组织的众包语音数据集,包含多种语言和方言的语音数据。
    • 链接:Common Voice
  3. TED-LIUM

    • 描述:包含从TED演讲中提取的音频和相应的文本转录。
    • 链接:TED-LIUM Corpus
  4. WSJ (Wall Street Journal)

    • 描述:包含朗读自《华尔街日报》的语音数据,是语音识别领域的经典数据集。
    • 链接:WSJ Corpus

LibriSpeech数据集的使用

LibriSpeech 数据集页面 下载 train-clean-100.tar.gz。这个数据集包含100小时的干净语音,适合用于初步模型的训练。

从零搭建——基于HMM-GMM的语音识别模型构建 关于该数据集的解压与使用,我写了一个脚本用于处理,递归遍历train-clean-100目录中的所有子目录,找到所有的音频文件并提取它们的MFCC特征,然后将这些特征存储到一个列表中。:

tar -xzvf train-clean-100.tar.gz
import os
from scipy.io import wavfile
import numpy as np
from python_speech_features import mfcc
from hmmlearn import hmm
from sklearn.preprocessing import StandardScaler
import soundfile as sf
import kenlm

#定义处理音频文件的函数
def extract_mfcc_from_flac(file_path, numcep=13):
    # 使用soundfile库读取flac文件
    signal, sample_rate = sf.read(file_path)
    # 提取MFCC特征
    mfcc_features = mfcc(signal, samplerate=sample_rate, numcep=numcep)
    return mfcc_features
    
#定义递归函数来获取所有音频文件
def get_all_flac_files(data_dir):
    flac_files = []
    for root, dirs, files in os.walk(data_dir):
        for file in files:
            if file.endswith('.flac'):
                flac_files.append(os.path.join(root, file))
    return flac_files
    
#加载数据并提取MFCC特征
def load_librispeech_data(data_dir):
    flac_files = get_all_flac_files(data_dir)
    mfcc_features_list = [extract_mfcc_from_flac(file) for file in flac_files]
    return mfcc_features_list

通过上述方式,得到了该训练集内的音频数据的MFCC特征,用于训练HMM-GMM模型。

转载自:https://juejin.cn/post/7384635872618840074
评论
请登录