语音信号处理基础学习和源码理解Melspectrogram

最近为了在实习前集满GM的5金去参加了kaggle的语音比赛
参加语音比赛除了为了集金更是为了补足对语音方向基础的了解
以下源码部分来自kapre

音频数据长啥样?

这里写图片描述
如图所示
这是一个单声道的语音数据
输入维度 (time_steps, channels)
channels表示声道个数

以下讨论都以单声道进行讨论,多声道的话同样的处理方式最后在通道轴拼接即可

什么是频谱图?

频谱图是音频信号的一种传统特征,效果不错
先上关键源码,再进行分析

1
2
3
4
5
6
7
8
9
10
11
x = input   ##  x -> (batch_size,time_steps,1,1)
subsample = (self.n_hop, 1)
output_real = K.conv2d(x, self.dft_real_kernels,
strides=subsample,
padding=self.padding,
data_format='channels_last')
output_imag = K.conv2d(x, self.dft_imag_kernels,
strides=subsample,
padding=self.padding,
data_format='channels_last')
output = output_real ** 2 + output_imag ** 2 ## output -> (batch_size,time_steps,1,freq)

总得来说,他是以卷积的方式扩展出了频率轴
会有人问:为什么是频率轴不是通道轴
因为这里的卷积是傅里叶变换的替代实现,这个轴的物理意义即频率。

操作如下:

  1. 音频数据分帧定帧长(即卷积的窗口大小)
  2. 各帧进行FFT后计算频域复数的模长(即能量)
  3. 然后通过帧移对各帧(卷积步长)对各帧进行FFT
  4. 以上从而将(time_steps,1)->(time_steps,freq)
    由于FFT的频率是按序计算,所以音频数据在频率轴仍然有局部依赖
    即可使用CNN或ConvLSTM1D之类的结构进行建模

上一张图吧

这里写图片描述

Melspectrogram

这个Mel频谱其实我也不太理解物理意义
但看源码十分简单,就是用一个矩阵对频谱图做线性变换
翻阅一些其他人的说法主要是考虑了人耳的声学结构
然后在尺度上做一些变换

1
output = K.dot(power_spectrogram, self.freq2mel)

了解到这儿应该够我做这个任务了。。
毕竟就算理解了Mel频谱的滤波器设计方式我也大概率优化不好

最后

MFCC也不详述了,因为MFCC根据往年比赛方案以及相关总结都是说不适合nn
上面讲的特征都是可以e2e实现的,但是一旦设置成可训练效果极差。。。真是NB的手工特征