语音识别FBank特征提取学习笔记

语音识别就是把一段语音信号转换成对应的文本信息,这一过程包括四个大的模块,分别是:特征提取、声学模型、语言模型、字典与解码。

本篇就来梳理一下特征提取模块的实现思路和方法。

常用的语音特征有:

  • 梅尔频率倒谱系数(Mel-Frequency Cepstral Coefficients, MFCC)
  • 梅尔滤波器组系数(Mel Filter Bank, FBank,也叫log-Mel)
  • 线性预测系数(Linear Prediction Coefficient, LPC)

基于深度学习网络的语音识别,目前多采用FBank特征。 获得FBank特征主要包括以下几个步骤:

  1. 预加重;
  2. 分帧、加窗;
  3. 快速傅里叶变换,计算功率谱;
  4. Mel滤波器组;
  5. 取对数,得到FBank。

1. 预加重(Pre-Emphasis)

在音频录制过程中,高频信号更容易衰减,高频成分的丢失,可能导致音素的共振峰不明显,使得声学模型对这些音素的建模能力不强。预加重是个一阶高通滤波器,可以提高信号高频部分的能量。

预加重的实现方法:给定时域输入信号x,预加重之后的信号y为:y(t)=x(t)−αx(t−1),其中0.9≤α≤1.0。经过预加重之后的频谱图和原始的频谱图的比较如下图所示,其中,左侧为原始频谱图,右侧为预加重处理之后的频谱图。

2. 分帧、加窗

语音信号是一个时变的、非稳态的信号,但在短时间范围内可以认为是时不变的、稳态的。这个短时间的长度一般取10~30ms,可在这个时间范围内进行语音信号处理。这就是分帧。

分帧一般采用交叠分段的方法,这是为了使帧与帧之间平滑过渡,保持其连续性。前一帧和后一帧的交叠部分称为帧移,帧移与帧长的比值一般为0~1/2。分帧如下图所示:

分帧之后,需要使用有限长度窗口进行加权处理,也就是加窗,即sw(n) = s(n) * w(n)。那么,为什么要加窗呢?这是因为后面要对信号进行快速傅里叶变换(FFT)。FFT处理的要求是,信号要么从-∞到+∞,要么为周期信号。由于语音信号只能是有限长度信号,并且分帧后的信号是非周期的,进行FFT处理时会存在频率泄露的问题。为了尽可能地减小频率泄露,就需要对信号进行加窗处理。那么,窗函数的选择就需要满足:(1) 窗函数频谱主瓣宽度尽量窄,以得到较高的频率分辨能力;(2) 窗函数旁瓣衰减尽量大,以减少泄露。

下图显示了加窗和不加窗的FFT变换对比:

常用的加窗函数有汉明窗(Hamming)、汉宁窗(Hanning)等。其中,汉明窗的窗函数表达式为:

其中,0≤n≤N−1,N为窗口长度。窗口图形绘制如下:

3. 短时快速傅里叶变换(STFT),计算功率谱

对于每一帧加窗信号,进行N点FFT变换,也称为短时傅里叶变换(STFT),N通常取256或512。然后,计算能量谱:

4.  Mel滤波器组

人耳对不同频率的声音有不同的感知能力,通常情况下,人耳对低频的感知辨识力比高频更好,为了模拟人耳对不同频率的非线性感知能力,引入了Mel频率。赫兹频率(f)与Mel频率(m)之间的转换关系如下:

该步是通过定义M个三角滤波器组,对上一步得到的功率谱进行滤波。M的取值范围一般在22~40,标准值为26,这里取40。滤波器组中的每个滤波器都是三角形的,中心频率为f(m),该处响应为1,中心频率两边线性减小到0。各f(m)之间的间隔随着m值的增大而变宽,如下图所示:

三角滤波器的定义如下:

f(m)是在Mel尺度上转换回赫兹频率的位置,由于滤波器最终对第3步计算出来的功率谱进行滤波,因此,在实现中,可以将滤波器位置转换成FFT bin所在的位置来计算。为了说明这一点,用一段代码来描述这个过程:

low_freq_mel = 0
high_freq_mel = (2595 * numpy.log10(1 + (sample_rate / 2) / 700))  # Convert Hz to Mel
mel_points = numpy.linspace(low_freq_mel, high_freq_mel, nfilt + 2)  # Equally spaced in Mel scale,在Mel频率范围内均匀创建nfilt+2也就是40个点
hz_points = (700 * (10**(mel_points / 2595) - 1))  # Convert Mel to Hz,将42个点的Mel points转回赫兹频率
bin = numpy.floor((NFFT + 1) * hz_points / sample_rate)   # 将hz_points转换到FFT binfbank = numpy.zeros((nfilt, int(numpy.floor(NFFT / 2 + 1))))for m in range(1, nfilt + 1):f_m_minus = int(bin[m - 1])   # leftf_m = int(bin[m])             # centerf_m_plus = int(bin[m + 1])    # rightfor k in range(f_m_minus, f_m):fbank[m - 1, k] = (k - bin[m - 1]) / (bin[m] - bin[m - 1])     # 三角滤波器左侧for k in range(f_m, f_m_plus):fbank[m - 1, k] = (bin[m + 1] - k) / (bin[m + 1] - bin[m])   # 三角滤波器右侧filter_banks = numpy.dot(pow_frames, fbank.T)  # pow_frames即当前帧的功率谱
filter_banks = numpy.where(filter_banks == 0, numpy.finfo(float).eps, filter_banks)  # Numerical Stability
filter_banks = 20 * numpy.log10(filter_banks)  # dB,进行对数计算,得到最终的FBank特征

5. 取对数,得到FBank

这一步较简单,在上一步的Python代码中,对三角滤波器组的输出取对数,得到最终的FBank特征。不再赘述。

6. 均值归一化(Mean Normalization)

为了平衡频谱并提高信噪比,可以通过减去(所有帧的)系数平均值的方式来进行归一化。

filter_banks -= (numpy.mean(filter_banks, axis=0) + 1e-8)

7. MFCC特征

由于许多ASR系统使用MFCC特征,这里做一个补充说明。

由于FBank系数存在高度相关性,在一些机器学习系统(如之前流行的GMMs-HMMs)中会存在问题,因此,如果对Fbank进行DCT变换来对FBank系数进行去相关,则可以得到MFCC(Mel-Frequency Cepstral Coefficients)。MFCC是FBank的一种压缩表示。在ASR系统中,一般会保留前2~13个系数,其他的则被丢弃。被丢弃的这些系数表示filter bank的快速变化,这些精细的细节对某些ASR系统是没有贡献的。

mfcc = dct(filter_banks, type=2, axis=1, norm='ortho')[:, 1 : (num_ceps + 1)] # num_ceps = 2 - 13

 还可以对MFCC应用正弦提升来改善ASR在噪声信号下的识别能力:

(nframes, ncoeff) = mfcc.shape
n = numpy.arange(ncoeff)
lift = 1 + (cep_lifter / 2) * numpy.sin(numpy.pi * n / cep_lifter)
mfcc *= lift  

MFCC也可以应用均值归一化。 

参考资料:

Practical Cryptography

Speech Processing for Machine Learning: Filter banks, Mel-Frequency Cepstral Coefficients (MFCCs) and What’s In-Between | Haytham Fayek

《人工智能技术》,郑孝宗主编 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/42626.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学生管理系统(通过顺序表,获取连续堆区空间实现)

将学生的信息,以顺序表的方式存储(堆区),并且实现封装函数 : 1】顺序表的创建, 2】判满、 3】判空、 4】往顺序表里增加学生信息、 5】遍历学生信息 6】任意位置插入学生信息 7】任意位置删除学生信…

0301STM32GPIO外设输出

STM32GPIO外设输出 STM32内部的GPIO外设GPIO简介基本结构GPIO位结构输入部分:输出部分: GPIO八种工作模式浮空/上拉/下拉输入模拟输入开漏/推挽输出复用开漏/推挽输出 手册寄存器描述GPIO功能描述外设的GPIO配置GPIO寄存器描述端口输入数据寄存器端口输出…

QT入门笔记-自定义控件封装 30

具体代码如下: QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c17# You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES QT_DISABLE_DEPRECATED_BEFORE0x060000 …

并查集(还有反集也在)

一.定义 定义: 并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题(即所谓的并、查)。比如说,我们可以用并查集来判断一个森林中有几棵树、某个节点是否属于某棵树等。 主要构成: 并查集…

Android计算器界面的设计——表格布局TableLayout实操

目录 任务目标任务分析任务实施 任务目标 使用TextView、Button等实现一个计算器界面,界面如图1所示。 图1 计算器界面效果图 任务分析 界面整体使用表格布局,第一行使用一个TextView控件,横跨4列,中间4行4列,最后一…

io流 多线程

目录 一、io流 1.什么是io流 2.流的方向 i.输入流 ii.输出流 3.操作文件的类型 i.字节流 1.拷贝 ii.字符流 ​3.字符流输出流出数据 4.字节流和字符流的使用场景 5.练习 6.缓冲流 1.字节缓冲流拷贝文件 2.字符缓冲流特有的方法 1.方法 2.总结 7.转换流基本用法…

第2集《修习止观坐禅法要》

请打开补充讲表第一面,附表一、念佛摄心方便法。 我们前面讲到修止,就是善取所缘境的相貌,然后心于所缘,专一安住;心于所缘,相续安住;达到心一境性的目的。 站在修学净土的角度,他…

《C语言》预处理

文章目录 一、预定义符号二、#define定义常量三、#define定义宏四、宏更函数的对比五、#和##1、#运算符2、##运算符 一、预定义符号 C语言设置了一些预定义符号,可以直接使用,在预处理期间进行处理的。 __FILE__//进行编译的源文件 __LINE__//文件当前的…

【数据结构与算法】插入排序

💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《数据结构与算法》 期待您的关注 ​

人工智能、机器学习、神经网络、深度学习和卷积神经网络的概念和关系

人工智能(Artificial Intelligence,缩写为AI)--又称为机器智能,是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。 人工智能是智能学科重要的组成部分,它企图了解智能的实质…

【问题解决】 pyocd 报错 No USB backend found 的解决方法

pyocd 报错 No USB backend found 的解决方法 本文记录了我在Windows 10系统上遇到的pyocd命令执行报错——No USB backend found 的分析过程和解决方法。遇到类似问题的朋友可以直接参考最后的解决方法,向了解问题发送原因的可以查看原因分析部分。 文章目录 pyoc…

排序-java(插入排序和选择排序)

一,分类 主要的排序大致分为以下几类: 1,插入排序,又分为直接插入排序和希尔排序 2,选择排序,又分为选择排序和堆排序 3,交换排序,又分为冒泡排序和快速排序 4,归并…

springboot配置扫描生效顺序

文章目录 举例分析项目结构如下noddles-user-backend 两个配置文件noddles-user-job 配置文件noddles-user-server 配置文件问题:server和Job启动时对应加载的数据库配置为哪一个? 总结 在微服务架构中,backend模块会定义一个基础的配置文件,…

Report Design Analysis报告之logic level详解

目录 一、前言 二、Logic Level distribution 2.1 logic level配置 2.2 Logic Level Distribution报告 2.3 Logic Level 报告详情查看 2.4 Route Distributions 报告详情查看 2.5 示例代码 一、前言 ​在工程设计中,如果需要了解路径的逻辑级数,可…

卷积神经网络基础篇

文章目录 1、卷积层1.1、激活函数1.3、sigmoid1.4、Tanh1.5、ReLU1.6、Leaky ReLU1.7、误差计算 2、池化层3、全连接层4、CNN训练 参考链接1 参考链接2 1、卷积层 卷积层(Convolutional layer),这一层就是卷积神经网络最重要的一个层次&…

动手学深度学习(Pytorch版)代码实践 -循环神经网络- 56门控循环单元(`GRU`)

56门控循环单元(GRU) 我们讨论了如何在循环神经网络中计算梯度, 以及矩阵连续乘积可以导致梯度消失或梯度爆炸的问题。 下面我们简单思考一下这种梯度异常在实践中的意义: 我们可能会遇到这样的情况:早期观测值对预测…

机器人动力学模型及其线性化阻抗控制模型

机器人动力学模型 机器人动力学模型描述了机器人的运动与所受力和力矩之间的关系。这个模型考虑了机器人的质量、惯性、关节摩擦、重力等多种因素,用于预测和解释机器人在给定输入下的动态行为。动力学模型是设计机器人控制器的基础,它可以帮助我们理解…

2024/7/7周报

文章目录 摘要Abstract文献阅读题目问题本文贡献问题描述图神经网络Framework实验数据集实验结果 深度学习MAGNN模型相关代码GNN为什么要用GNN?GNN面临挑战 总结 摘要 本周阅读了一篇用于多变量时间序列预测的多尺度自适应图神经网络的文章,多变量时间序…

SAP已下发EWM的交货单修改下发状态

此种情况针对EWM未接收到ERP交货单时,可以使用此程序将ERP交货单调整为未分配状态,在进行调整数据后,然后使用VL06I(启用自动下发EWM配置,则在交货单修改保存后会立即下发EWM)重新下发EWM系统。 操作步骤如…

3ds Max渲染曝光过度怎么办?

3dmax效果图云渲染平台——渲染100 以3ds Max 2025、VR 6.2、CR 11.2等最新版本为基础,兼容fp、acescg等常用插件,同时LUT滤镜等参数也得到了同步支持。 注册填邀请码【7788】可领30元礼包和免费渲染券哦~ 遇到3ds Max渲染过程中曝光过度的问题&#xf…