【语音识别入门】特征提取(Python完整代码)

这篇具有很好参考价值的文章主要介绍了【语音识别入门】特征提取(Python完整代码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、数字信号处理基础

1.1数字信号处理基础

在科学和工程中遇到的大多数信号都是连续模拟信号,例如电压随着时间变化,一天中温度的变化等等,而计算机智能处理离散的信号,因此必须对这些连续的模拟信号进行转化。通过采样–量化来转换成数字信号。
正弦波为例:
x ( t ) = s i n ( 2 Π f ∗ t ) x(t) = sin (2Πf*t) x(t)=sin(ft)

( f f f表示信号本身的频率,单位 H z Hz Hz)
首先对正弦波进行采样,每 t t t秒进行一次采用,并使用一定范围的离散数值来表示采样值,得到离散信号 x ( n ) x(n) x(n):
x ( n ) = s i n ( 2 Π f ∗ n t ) x(n) = sin (2Πf*nt) x(n)=sin(fnt)

1.2频率混叠

由于采样信号频谱发生变化,而出现高、低频成分发生混淆的一种现象。抽样时频率不够高,抽样出来的点既代表了信号中的低频信号的样本值,也同时代表高频信号样本值,在信号重建的时候,高频信号被低频信号代替,两种波形完全重叠在一起,形成严重失真。

1.3 奈奎斯特采样定理

采样频率要大于信号中最大频率的两倍
f s / 2 ≥ f m a x fs/2≥fmax fs/2fmax
即在原始信号的一个周期内至少要采样两个点才能有效杜绝频率混叠问题

1.4 离散傅里叶变换(DFT)

DFT将时域离散且周期的信号的时域变换到频域,分析信号中的频率成分,若是非周期的离散信号需要进行周期延拓再进行DFT。

python实现特征提取tpc,语音识别入门,语音识别,python,人工智能
DFT在时域和频域上都具有离散周期的特点,可用于计算机处理

python实现特征提取tpc,语音识别入门,语音识别,python,人工智能

1.5 DFT的性质
  • 对称性 X ( m ) = X ∗ ( N − m ) X(m) =X*(N-m) X(m)=X(Nm)
  • 线性
  • 时移性

2、特征提取流程

Fbank和MFCC提取流程
python实现特征提取tpc,语音识别入门,语音识别,python,人工智能

2.1预加重(preemphasis)
  • 提高信号高频部分能量
  • 预加重滤波器是一个一阶高通滤波器,给定时域输入信号 x [ n ] x[n] x[n],预加重后的信号为 y [ n ] = x [ n ] − a ∗ x [ n − 1 ] y[n]=x[n]-a*x[n-1] y[n]=x[n]ax[n1],其中 0.9 < = a < = 1.0 0.9<=a<=1.0 0.9<=a<=1.0

代码

np.append(signal[0], signal[1:] - coeff * signal[:-1])
2.2加窗分帧(enframe)

语音信号为非平稳信号,其统计属性是随着时间变化的;语音信号又具有短时平稳的属性,在进行语音识别的时候,对于一句话,识别的过程也是以较小的发音单元(音素、字音素或者字、字节)为单位进行识别,因此用滑动窗来提取短时片段
、帧长、帧移、窗函数,对于采样率为16kHz的信号,帧长、帧移一般为25ms、10ms即400和160个采样点。分帧的过程,在时域上即是用一个窗函数和原始信号进行相乘 y [ n ] = w [ n ] x [ n ] y[n]=w[n]x[n] y[n]=w[n]x[n], w [ n ] w[n] w[n]为窗函数,常用矩形窗和汉明窗。注在加窗的过程中一般不直接使用矩形窗,实际上是在时域上将信号截断,窗函数与信号在时域相乘,就等于对应的频域表示进行卷积,矩形窗主瓣窄但是旁瓣较大,将其与原信号的频域表示进行卷积就会导致频率泄露。

代码

def enframe(signal, frame_len=frame_len, frame_shift=frame_shift, win=np.hamming(frame_len)):
    """Enframe with Hamming widow function.

        :param signal: The signal be enframed
        :param win: window function, default Hamming
        :returns: the enframed signal, num_frames by frame_len array
    """
    num_samples = signal.size
    // num_frames表示总共有多少个帧
    // 帧长frame_len表示一帧 包含多少个点
    // 帧移frame_shift表示一个帧移 包含多少个点
    num_frames = np.floor((num_samples - frame_len) / frame_shift) + 1
    frames = np.zeros((int(num_frames), frame_len))
    for i in range(int(num_frames)):
        frames[i, :] = signal[i * frame_shift:i * frame_shift + frame_len]
        frames[i, :] = frames[i, :] * win
    return frames
2.3傅里叶变换

经过上一步分帧之后的语音帧,已经从时域变换到了频域,取DFT系数的模,得到谱特征。(语谱图的生成)

#DFT具有对称性,在N点DFT之后,只需要保证前N/2+1个点即可
def get_spectrum(frames, fft_len=fft_len):
    """Get spectrum using fft
        :param frames: the enframed signal, num_frames by frame_len array
        :param fft_len: FFT length, default 512
        :returns: spectrum, a num_frames by fft_len/2+1 array (real)
    """
    cFFT = np.fft.fft(frames, n=fft_len)
    valid_len = int(fft_len / 2) + 1
    spectrum = np.abs(cFFT[:, 0:valid_len])
    return spectrum
2.4梅尔滤波器组和对数操作

DFT得到了每个频带上信号的能量,但是人耳对频率的感知不是等间隔的,近似于对数函数。将线性频率转换为梅尔频率,梅尔频率和线性频率的转换关系是: m e l = 2595 l o g 10 ( 1 + f / 700 ) mel=2595log10(1+f/700) mel=2595log10(1+f/700)

梅尔三角滤波器组:根据起始频率、中间频率和截止频率,确定各滤波系数
梅尔滤波器组设计:

(1)确定滤波器组个数P
(2)根据采样率 f s fs fs,DFT点数N,滤波器个数P,在梅尔域上等间隔的产生每个滤波器的起始频率,中间频率和截止频率,注意,上一个滤波器的中间频率为下一个滤波器的起始频率(存在overlap)
(3)将梅尔域上每个三角滤波器的起始、中间和截止频率转换线性频率域,并对DFT之后的谱特征进行滤波,得到P个滤波器组能量,进行log操作,得到FBank特征
MFCC特征在FBank特征的基础上继续进行IDFT变换等操作。

代码

def mel_filter(frame_pow, fs, n_filter, nfft):
    """
    mel 滤波器系数计算
    :param frame_pow: 分帧信号功率谱
    :param fs: 采样率 hz
    :param n_filter: 滤波器个数
    :param nfft: fft点数
    :return: 分帧信号功率谱mel滤波后的值的对数值
    mel = 2595 * log10(1 + f/700)   # 频率到mel值映射
    f = 700 * (10^(m/2595) - 1      # mel值到频率映射
    上述过程本质上是对频率f对数化
    """
    mel_min = 0     # 最低mel值
    mel_max = 2595 * np.log10(1 + fs / 2.0 / 700)   # 最高mel值,最大信号频率为 fs/2
    mel_points = np.linspace(mel_min, mel_max, n_filter + 2)    # n_filter个mel值均匀分布与最低与最高mel值之间
    hz_points = 700 * (10 ** (mel_points / 2595.0) - 1)     # mel值对应回频率点,频率间隔指数化
    filter_edge = np.floor(hz_points * (nfft + 1) / fs)     # 对应到fft的点数比例上
    
    # 求mel滤波器系数
    fbank = np.zeros((n_filter, int(nfft / 2 + 1)))
    for m in range(1, 1 + n_filter):
        f_left = int(filter_edge[m - 1])     # 左边界点
        f_center = int(filter_edge[m])       # 中心点
        f_right = int(filter_edge[m + 1])    # 右边界点
        
        for k in range(f_left, f_center):
            fbank[m - 1, k] = (k - f_left) / (f_center - f_left)
        for k in range(f_center, f_right):
            fbank[m - 1, k] = (f_right - k) / (f_right - f_center)
    
    # mel 滤波
    # [num_frame, nfft/2 + 1] * [nfft/2 + 1, n_filter] = [num_frame, n_filter]
    filter_banks = np.dot(frame_pow, fbank.T)
    filter_banks = np.where(filter_banks == 0, np.finfo(float).eps, filter_banks)
    # 取对数
    filter_banks = 20 * np.log10(filter_banks)  # dB
    return filter_banks

2.5动态特征计算
  • 一阶差分(△) △ t = ( c ( t + 1 ) − c ( t − 1 ) ) / 2 △t =( c(t+1) - c(t-1))/2 t=(c(t+1)c(t1))/2 (类比速度)
  • 二阶差分(△△) △△ t = ( △ ( t + 1 ) − △ ( t − 1 ) ) / 2 △△t = (△(t+1) - △(t -1)) /2 △△t=((t+1)(t1))/2
2.6能量计算

e = ∑ x 2 [ n ] e = ∑x²[n] e=x2[n]
MFCC特征总结:一般常用的MFCC特征是39维,包括12维原始MFCC+12维一阶差分+12维二阶差分—+1维原始能量+一维一阶能量+一维二阶能量
MFCC特征一般用于对角GMM训练,各维度之间相关性小;
FBank特征一般用于DNN训练。

代码

#前面提取到的FBank特征,往往是高度相关的。因此可以继续用DCT(离散余弦变换)变换,将这些相关的滤波器组系数进行压缩。对于ASR来说,通常取2~13维,扔掉的信息里面包含滤波器组系数快速变化部分
num_ceps = 12
mfcc = dct(filter_banks, type=2, axis=1, norm='ortho')[:, 1:(num_ceps+1)]
plot_spectrogram(mfcc.T, 'MFCC Coefficients')

3、Feature-extraction实践

给定一段音频,请提取12维MFCC特征和23维FBank,阅读代码预加重、分帧、加窗部分,完善作业代码中FBank特征提取和MFCC特征提取部分,并给出最终的FBank特征和MFCC特征,存储在纯文本中,用默认的配置参数,无需进行修改。

3.1代码文件说明

代码依赖
python3
librosa
如果需要观察特征频谱,请确保自己有matplotlib依赖并将代码中相关注解解掉
注:不要修改文件默认输出test.fbank test.mfcc的文件名

3.2文件路径说明
mfcc.py 作业代码
test.wav 测试音频
Readme.md 说明文件
3.3实验完整代码
import librosa
import numpy as np
from scipy.fftpack import dct
# If you want to see the spectrogram picture
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
def plot_spectrogram(spec, note,file_name):
    """Draw the spectrogram picture
        :param spec: a feature_dim by num_frames array(real)
        :param note: title of the picture
        :param file_name: name of the file
    """
    fig = plt.figure(figsize=(20, 5))
    heatmap = plt.pcolor(spec)
    fig.colorbar(mappable=heatmap)
    plt.xlabel('Time(s)')
    plt.ylabel(note)
    plt.tight_layout()
    plt.savefig(file_name)


#preemphasis config 
alpha = 0.97

# Enframe config
frame_len = 400      # 25ms, fs=16kHz
frame_shift = 160    # 10ms, fs=15kHz
fft_len = 512

# Mel filter config
num_filter = 23
num_mfcc = 12

# Read wav file
wav, fs = librosa.load('./test.wav', sr=None)

# Enframe with Hamming window function
def preemphasis(signal, coeff=alpha):
    """perform preemphasis on the input signal.

        :param signal: The signal to filter.
        :param coeff: The preemphasis coefficient. 0 is no filter, default is 0.97.
        :returns: the filtered signal.
    """
    return np.append(signal[0], signal[1:] - coeff * signal[:-1])

def enframe(signal, frame_len=frame_len, frame_shift=frame_shift, win=np.hamming(frame_len)):
    """Enframe with Hamming widow function.

        :param signal: The signal be enframed
        :param win: window function, default Hamming
        :returns: the enframed signal, num_frames by frame_len array
    """
    
    num_samples = signal.size
    num_frames = np.floor((num_samples - frame_len) / frame_shift)+1
    frames = np.zeros((int(num_frames),frame_len))
    for i in range(int(num_frames)):
        frames[i,:] = signal[i*frame_shift:i*frame_shift + frame_len] 
        frames[i,:] = frames[i,:] * win

    return frames

def get_spectrum(frames, fft_len=fft_len):
    """Get spectrum using fft
        :param frames: the enframed signal, num_frames by frame_len array
        :param fft_len: FFT length, default 512
        :returns: spectrum, a num_frames by fft_len/2+1 array (real)
    """
    cFFT = np.fft.fft(frames, n=fft_len)
    valid_len = int(fft_len / 2 ) + 1
    spectrum = np.abs(cFFT[:,0:valid_len])
    return spectrum

def fbank(spectrum, num_filter = num_filter):
    """Get mel filter bank feature from spectrum
        :param spectrum: a num_frames by fft_len/2+1 array(real)
        :param num_filter: mel filters number, default 23
        :returns: fbank feature, a num_frames by num_filter array 
        DON'T FORGET LOG OPRETION AFTER MEL FILTER!
    """
    low_mel_freq = 0
    high_mel_freq = 2595 * np.log10(1+(fs /2)/700) #转到梅尔尺度上
    mel_filters_points = np.linspace(low_mel_freq,high_mel_freq,num_filter+2)
    freq_filters_pints = (700 * (np.power(10.,(mel_filters_points/2595))-1))
    freq_bin = np.floor(freq_filters_pints / (fs /2)*(fft_len /2 + 1))
    feats=np.zeros((int(fft_len/2+1), num_filter))
    for  m in range(1,num_filter+1):
        bin_low = int(freq_bin[m-1])
        bin_medium = int(freq_bin[m])
        bin_high = int(freq_bin[m+1])
        for k in range(bin_low,bin_medium):
            feats[k,m-1]=(k-freq_bin[m-1])/(freq_bin[m]-freq_bin[m-1])
        for k in range(bin_medium,bin_high):
            feats[k,m-1]=(freq_bin[m+1]-k)/(freq_bin[m+1]-freq_bin[m])
    feats = np.dot(spectrum,feats)
    feats = 20 *np.log10(feats)
    return feats

def mfcc(fbank, num_mfcc = num_mfcc):
    """Get mfcc feature from fbank feature
        :param fbank: a num_frames by  num_filter array(real)
        :param num_mfcc: mfcc number, default 12
        :returns: mfcc feature, a num_frames by num_mfcc array 
    """

    #feats = np.zeros((fbank.shape[0],num_mfcc))
    mfcc = dct(fbank, type=2, axis=1, norm='ortho')[:, 1:(num_mfcc+1)]
    return mfcc

def write_file(feats, file_name):
    """Write the feature to file
        :param feats: a num_frames by feature_dim array(real)
        :param file_name: name of the file
    """
    f=open(file_name,'w')
    (row,col) = feats.shape
    for i in range(row):
        f.write('[')
        for j in range(col):
            f.write(str(feats[i,j])+' ')
        f.write(']\n')
    f.close()


def main():
    wav, fs = librosa.load('./test.wav', sr=None)
    signal = preemphasis(wav)
    frames = enframe(signal)
    spectrum = get_spectrum(frames)
    fbank_feats = fbank(spectrum)
    mfcc_feats = mfcc(fbank_feats)
    plot_spectrogram(fbank_feats, 'Filter Bank','fbank.png')
    write_file(fbank_feats,'./test.fbank')
    plot_spectrogram(mfcc_feats.T, 'MFCC','mfcc.png')
    write_file(mfcc_feats,'./test.mfcc')


if __name__ == '__main__':
    main()


3.4实验结果

FBank:
python实现特征提取tpc,语音识别入门,语音识别,python,人工智能

MFCC:
python实现特征提取tpc,语音识别入门,语音识别,python,人工智能文章来源地址https://www.toymoban.com/news/detail-796646.html

到了这里,关于【语音识别入门】特征提取(Python完整代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OpenCV 入门教程:人脸识别和特征提取

    人脸识别是计算机视觉中的热门研究领域,通过对人脸图像或视频进行分析和比对,实现对个体身份的自动识别。人脸特征提取是人脸识别中的重要步骤,它用于从人脸图像中

    2024年02月13日
    浏览(92)
  • 【目标检测】(8) ASPP改进加强特征提取模块,附Tensorflow完整代码

    各位同学好,最近想改进一下YOLOV4的SPP加强特征提取模块,看到很多论文中都使用 语义分割中的ASPP模块 来改进,今天用Tensorflow复现一下代码。 YOLOV4的主干网络代码可见我上一篇文章:https://blog.csdn.net/dgvv4/article/details/123818580 将本节的ASPP代码替换原来的SPP模块代码即可 YO

    2024年02月06日
    浏览(36)
  • 语音识别实战(python代码)(一)

      (python :pyttsx、SAPI、SpeechLib实例代码)(一) 本文目录: 一、语音识别的基本原理 (1)、语音识别的起源与发展 (2)、语音识别的基本原理 (3)、语音识别过程 (4)、语音识别的近期发展 二、Python 语音识别 (1)、文本转换为语音 (2)、文本转存为语音文件wav 三、总结

    2023年04月09日
    浏览(41)
  • 语音识别入门——常用软件及python运用

    ffmpeg sox audacity pydub scipy librosa pyAudioAnalysis plotly 本文分为两个部分: P1 : 如何使用ffmpeg和sox处理音频文件 P2 : 如何编程处理音频文件并执行基本处理 格式转换 使用ffmpeg将输入mkv文件转为mp3文件 降采样、通道转换 ar:声频采样率(audio rate) ac:声频通道(audio channel) 此处

    2024年02月03日
    浏览(40)
  • 【ANSYS APDL】提取结构刚度矩阵完整过程--附Python代码实现

    在这里简要回顾一下结构力学知识,可参考朱慈勉老师的《结构力学》 结构刚度矩阵来源于 矩阵位移法 ,其中包括单元刚度矩阵,总刚度矩阵,结构刚度矩阵。在二维问题求解过程中,依次计算三者,最后求解可得到所有的节点位移 U 。该过程也称为 直接刚度法 ,分析步

    2024年01月25日
    浏览(83)
  • python基于opencv和tkinter实现人脸识别【内附完整代码】

    人脸识别技术已经在许多领域得到了广泛应用,例如安防、金融、医疗等等。人脸识别可以帮助我们识别和验证一个人的身份,这是一项非常重要的任务。本篇博客将介绍如何使用Python和OpenCV库进行人脸识别。我们将学习如何使用OpenCV中的人脸检测器检测图像中的人脸,如何

    2023年04月14日
    浏览(40)
  • 基于深度学习的中文语音识别系统(计算机毕设 附完整代码)

    该系统实现了基于深度框架的语音识别中的声学模型和语言模型建模,其中声学模型包括 CNN-CTC、GRU-CTC、CNN-RNN-CTC,语言模型包含 transformer、CBHG,数据集包含 stc、primewords、Aishell、thchs30 四个数据集。 本项目现已训练一个迷你的语音识别系统,将项目下载到本地上,下载 th

    2024年02月11日
    浏览(79)
  • 语音特征提取:语音识别的关键技术

    语音特征提取是语音识别系统中的关键技术,它的目的是从语音信号中提取出与语言相关的特征信息,以便于后续的语音识别和语音处理任务。在这篇文章中,我们将从以下几个方面进行深入探讨: 背景介绍 核心概念与联系 核心算法原理和具体操作步骤以及数学模型公式详

    2024年04月12日
    浏览(34)
  • 语音特征提取与预处理

    导入相关包  语音读取与显示  端点检测(去除前后静音段) 原理:将每帧均方根能量与全局最大均方根能量进行比较。  端点检测(包含语音内部)  频域分析 预加重  高通滤波,弥补高频部分的损耗,保护了声道信息:y[n] - y[n] - coef * y[n-1]。 Filter Bank:梅尔谱特征 梅尔滤

    2024年02月10日
    浏览(39)
  • 语音特征参数MFCC提取过程详解

      在语音识别(SpeechRecognition)和话者识别(SpeakerRecognition)方面,最常用到的语音特征就是梅尔倒谱系数(Mel-scaleFrequency Cepstral Coefficients,简称MFCC)。根据人耳听觉机理的研究发现,人耳对不同频率的声波有不同的听觉敏感度。从200Hz到5000Hz的语音信号对语音的清晰度影

    2023年04月18日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包