理解梅尔频谱(mel spectrogram)

简介

语音处理中 常常需要用到mel spectrogram,比如在语音分类中常常会把把信号signal变成图片spectrogram的形式, 然后用分类图片的算法(比如CNN)来分类语音。 本文主要介绍什么是mel specgrogram以及如何通过librosa来获取spectrogram 和mel spectrogram

信号signal

常说一个信号是多少多少赫兹的,指的是 这个信号 每秒有多少个取值点。44.1kHZ的声音就是 这个声音每秒有44100个取值。

读取声音:

import librosa
import matplotlib.pyplot as plt
%matplotlib inline

y, sr = librosa.load('./sample.wav')

plt.plot(y)
plt.title('Signal')
plt.title('Signal')
plt.xlabel('samples')
plt.ylabel('Amplitude')

 

傅里叶变换(Fourier Transform)

每个信号都可以看成不同频率的sine或者cosine的信号单元合成, 通过快速傅里叶变换(Fast Fourier Transform)可以分解一个信号到不同频率的信号单元:

import numpy as np 
n_fft=2048
ft = np.abs(librosa.stft(y[:n_fft], hop_length=n_fft+1))

plt.plot(ft)
plt.title('Spectrum')
plt.xlabel('Frequency Bin')
plt.ylabel('Amplitude')

 

短时傅里叶变换

声音的频率可能会随着时间而变化,所以对长信号来说直接用FFT来分解整个信号会不妥, 所以用到短时傅里叶变换(short time fourier transform), 只是把信号分成很多小段, 在每小段上进行FFT运算

 window length 是每小段的长度, 某一小段计算完以后,会计算下一小段,hop lenth就是两个小段之间的跳跃间隔。最后得到的STFT就是这些小段FFT的堆加, 每一小段有 Amplitude 和Frequency信息,以及这一小段所在的Time信息。把这些信息汇总到图片上 就得到了Spectrogram.

 Spectrogram

由于人类会对低频低音高的片段更感兴趣,所以会对通过FFT变换得到的Amplitude 和Frequency 信息进行log运算, 压缩高频和高音高的部分:

import librosa.display

spec = np.abs(librosa.stft(y, hop_length=512))
spec = librosa.amplitude_to_db(spec, ref=np.max) #将音高变为分贝。log运算

librosa.display.specshow(spec, sr=sr, x_axis='time', y_axis='log')
plt.colorbar(format='%+2.0f dB')
plt.title('Spectrogram')

 

颜色表示分贝。 

The Mel Scale

人类对低频信号更敏感, 你可以很容易区分500HZ 和1000HZ的声音, 但区分不清楚9000HZ和9500HZ的声音。 但在物理上却很容易区分。 把频率信号做一个非线性映射:

这样 人类对不同频率声音的区分 可以直接通过数值差异来显示了。

Mel spectrogram 

Mel spectrogram和spectrogram的区别就是 mel spectrogram的频率是mel scale变换后的频率(你可以想象把Spectrogram整体往下压,) 

mel_spect = librosa.feature.melspectrogram(y=y, sr=sr, n_fft=2048, hop_length=1024)
mel_spect = librosa.power_to_db(mel_spect, ref=np.max)
librosa.display.specshow(mel_spect, y_axis='mel', fmax=8000, x_axis='time');
plt.title('Mel Spectrogram');
plt.colorbar(format='%+2.0f dB');

 

总结

应用 librosa库可以很容易计算spectrogram和mel spectrogram, 至于用哪个效果会好(还有个MFCC)要根据自己的实验结果来。

 

### Mel频谱图的概念 Mel频谱图是一种用于音频处理的技术,能够有效地捕捉人类听觉系统的特性。它基于Mel尺度设计,这是一种模拟人耳感知声音的方式。Mel尺度反映了人耳对不同频率的声音敏感度的变化规律[^1]。 具体来说,低频区域的人耳更加敏感,而高频区域则相对迟钝。因此,Mel频谱图通过对频率轴进行非线性变换来更好地匹配这种感知特征。这一变换通常由`Hz`到`Mel`的转换函数实现: ```python import numpy as np def hz2mel(hz): '''把频率hz转化为梅尔频率''' return 2595 * np.log10(1 + hz / 700.0) def mel2hz(mel): '''把梅尔频率转化为hz''' return 700 * (10 ** (mel / 2595.0) - 1) ``` 上述代码定义了两个核心函数:`hz2mel` 和 `mel2hz`,分别实现了从赫兹到Mel以及反向的转换操作。 --- ### Mel频谱图的生成方法 为了生成Mel频谱图,一般遵循以下技术流程: #### 1. 预处理阶段 输入信号通常是时间域上的原始音频数据。首先对其进行分帧(Frame Splitting),并应用窗口函数(如汉明窗)以减少边界效应。 #### 2. 转换至频域 利用快速傅里叶变换(FFT)将每一帧的时间域信号转换为频域表示。这一步骤的结果是一个复数数组,其中包含了幅度和相位信息。 #### 3. 应用Mel滤波器组 构建一系列三角形滤波器覆盖整个频带范围,并将其应用于FFT后的功率谱上。这些滤波器的设计依据就是前面提到的`hz2mel`映射关系,从而使得最终得到的能量分布更接近于人的听力感受。 计算公式如下所示: \[ M_k = \sum_{n=0}^{N-1}{|X(n)|^2 H_k(f_n)} \] 这里 \(M_k\) 表示第k个Mel滤波器输出;\(H_k(f)\) 是对应位置处的增益系数;\(|X(n)|^2\) 则代表离散Fourier Transform之后取模平方所得数值。 #### 4. 取对数运算 由于动态范围较大,所以最后还要加上一个自然对数步骤以便压缩这个区间内的差异程度。 #### 5. 进行DCT变换 如果目的是提取MFCCs,则还需要执行离散余弦变换(DCT),选取前若干维作为特征向量。 以下是完整的Python代码示范如何生成Mel Spectrogram: ```python import librosa import matplotlib.pyplot as plt # 加载音频文件 y, sr = librosa.load(librosa.ex('trumpet')) # 计算Mel Spectrogram S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128,fmax=8000) # 将功率转成dB单位 S_dB = librosa.power_to_db(S, ref=np.max) # 显示图像 plt.figure(figsize=(10, 4)) librosa.display.specshow(S_dB, x_axis='time', y_axis='mel', sr=sr, fmax=8000) plt.colorbar(format='%+2.0f dB') plt.title('Mel-frequency spectrogram') plt.tight_layout() plt.show() ``` 此脚本使用LibROSA库加载一段示例音乐(`'trumpet'`),并通过内置功能完成Mel频谱图绘制工作。 --- ### 在语音模型中的作用 在现代深度学习框架下,比如Wav2Vec2或者HuBERT等先进架构中,Mel频谱图经常充当重要的中间表征形式之一。例如,在Waveform-to-MFCC路径当中,先要经历这样的转化过程才能进一步送入神经网络内部去挖掘高层次语义含义[^2]。 另外值得注意的是,当涉及到实际部署场景时,可能还会考虑优化参数设置等问题。像TensorFlow提供了一些特定命令选项让用户可以灵活调整训练细节,确保达到最佳性能表现[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值