音乐流派识别:从MFCC特征提取到LSTM模型训练
立即解锁
发布时间: 2025-08-31 00:22:44 阅读量: 6 订阅数: 18 AIGC 

# 音乐流派识别:从MFCC特征提取到LSTM模型训练
## 1. 数值差异分析与MFCC特征提取基础
在计算过程中,我们可以打印输出日志中绝对差异的最小值、最大值、平均值和标准差,代码如下:
```python
print("DIFF:\n",
"min:", np.min(abs_diff),
"max:", np.max(abs_diff),
"mean:", np.mean(abs_diff),
"std:", np.std(abs_diff))
```
输出日志中的统计信息表明,两种实现方式在数值上并不相同。这种数值差异可归因于它们不同的数值精度。不过,由于模型的训练数据将来自CMSIS - DSP Python版本,输出值的这种差异不会影响模型的准确性。
在FFT幅度计算中,我们可以利用CMSIS - DSP Python库中的Q15定点算术。对于那些希望在牺牲一定准确性的前提下提高FFT幅度计算性能的人来说,CMSIS - DSP的`arm_cmplx_mag_fast_q15()`函数是进行复数幅度计算的另一种选择。该函数的输出仍为Q2.14格式,但由于将小值钳位为零,其准确性往往较低。
## 2. 利用CMSIS - DSP库实现MFCC特征提取
### 2.1 准备工作
Raspberry Pi Pico等微控制器没有浮点运算的硬件加速。不过,我们可以利用定点格式进行计算,仅依靠整数运算。此外,Raspberry Pi Pico的大程序内存可用于优化MFCC计算。我们可以预先计算算法中每次执行时重复的部分,并将其存储在查找表中,从而消除冗余计算,显著提高性能。例如,汉宁窗系数在所有帧中都相同,我们可以预先计算它们以跳过余弦的昂贵计算。同样,这种优化技术也适用于Mel尺度转换、对数函数和离散余弦变换(DCT)。
DCT系数的计算公式为:
\[W_{DCT}(k) = \sqrt{\frac{2}{N}}\sum_{n = 0}^{N - 1} \cos(\frac{\pi}{N}(n + 0.5)k)\]
其中:
- \(W_{DCT}(k)\) 是索引 \(k\) 处的DCT系数
- \(N\) 是Mel频率的数量(在我们的例子中为40)
- \(n\) 是Mel频率的索引
- \(k\) 是我们要计算的DCT系数的索引
DCT计算可以通过向量与矩阵的运算来完成,左操作数是对数函数的输出,右操作数是DCT权重矩阵。
### 2.2 具体步骤
以下是使用16位定点算术通过CMSIS - DSP库实现MFCC管道的步骤:
1. **预计算汉宁窗系数**:
```python
def gen_hann_lut_q15(frame_len):
hann_lut_f32 = tf.signal.hann_window(frame_len)
return dsp.arm_float_to_q15(hann_lut_f32)
```
2. **预计算Mel权重矩阵**:
```python
def gen_mel_weight_mtx(sr, fmin_hz, fmax_hz,
num_mel_freqs, num_fft_freqs):
m_f32 = tf.signal.linear_to_mel_weight_matrix(
num_mel_freqs,
num_fft_freqs,
sr,
fmin_hz,
fmax_hz)
m_q15 = dsp.arm_float_to_q15(m_f32)
return m_q15.reshape((m_f32.shape[0],
m_f32.shape[1]))
```
3. **预计算对数函数**:
```python
def gen_log_lut_q(q_scale):
max_int16 = np.iinfo("int16").max
log_lut = np.zeros(shape=(max_int16), dtype="int16")
for i16 in range(0, max_int16):
q16 = np.array([i16,], dtype="int16")
f_v = q16 / float(q_scale)
log_f = np.array(np.log(f_v + 1e-6),)
log_q = log_f * float(q_scale)
log_lut[i16] = int(log_q)
return log_lut
```
4. **预计算DCT权重矩阵**:
```python
import math
def gen_dct_weight_mtx(num_mel_freqs, num_mfccs):
mtx_q15 = np.zeros(shape=(num_mel_freqs, num_mfccs),
dtype="int16")
scale = np.sqrt(2.0 / float(num_mel_freqs))
pi_div_mel = (math.pi / num_mel_freqs)
for n in range(num_mel_freqs):
for k in range(num_mfccs):
v = scale * np.cos(pi_div_mel * (n + 0.5) * k)
v_f32 = np.array([v,], dtype="float32")
mtx_q15[n][k] = dsp.arm_float_to_q15(v_f32)
return mtx_q15
```
5. **预计算相关参数并计算内存使用**:
```python
num_fft_freqs = int((FFT_LENGTH / 2) + 1)
q13_3_scale = 8
hann_lut_q15 = gen_hann_lut_q15(FRAME_LENGTH)
mel_wei_mtx_q15 = g
```
0
0
复制全文
相关推荐










