ML2022Spring HW2

Introduction

HW1 是根据数据 Delphi group@CMU 进行 COVID-19 Cases Prediction，即给定美国某个州过去 5 天的调查结果，预测第 5 天新增检测阳性病例的百分比，是一个回归任务。

HW2 是利用从原始音频信号数据集 LibriSpeech（subset of train-clean-100）预先提取的 MFCC 特征进行逐帧音素（phoneme）分类，是一个分类任务。

由于没有学过语音识别的相关知识，所以先对背景知识进行了简单学习。

Background

音素（phoneme）

一个通俗易懂的解释

MFCC 特征

音频信号以波的形式被记录。此任务从原始音频信号中提取 MFCC 特征，做数据预处理，为什么呢？

一个不错的回答是：

音频分类任务是指将音频信号根据其内容划分到不同的类别中。在进行音频分类时，需要从音频信号中提取有用的特征，以便更好地进行分类。
目前，大多数音频分类任务都会使用 MFCC 特征进行特征提取。MFCC 特征是一种基于人耳听觉特性的音频特征，它可以有效地模拟人耳对音频信号的识别能力。MFCC 特征主要由频率和能量等信息组成，能够捕捉音频信号中的频率和能量变化，从而为音频分类任务提供有效的特征信息。
此外，MFCC 特征具有很好的鲁棒性，能够在不同的音频环境下取得较好的性能。它可以适应不同的音频信号来源，包括人声、乐器声等，并且能够抑制噪声干扰，为音频分类任务

关于 MFCC 的理解，一个特别好的讲解可供参考，由于这不是此次 hw 的主要内容，因此就简单了解即可。

注意，由于 MFCC 中分帧（每帧为 39-dim 的 MFCC 特征），且每帧仅包含 25 毫秒的语音，因此单帧不太可能代表完整的音素。

通常，一个音素会跨越多个帧。

将相邻的音素连接起来进行训练。

所以助教讲解中举了一个例子，例如选取了一个帧过去和未来各五帧的数据，然后将其连接起来，共 11 个帧，然后用其预测中心帧，如图所示即

数据集及数据格式

要求 & Hints

Kaggle 上任务

Simple

按它的要求只需要直接运行就行。

训练和验证集上结果：

测试集上结果：

Medium

由于 optimization 代码里已经用了 adamw，即已经有 rmsdrop+momentum+weight_decay，暂时不需要再额外考虑优化的问题，因此我们主要考虑 concat 几个 frames，和 hidden_layers 的设计。

将 hidden_layers 设计为 3，hidden_dim 设计为 1024，concat21 个 frames，训练和验证集上结果为：

测试集上结果：

为什么这样设计呢：选一个较大的 concat n frames 的值能让每个时间步都能感知其前后上下文信息，这对于语音识别等时序任务至关重要，模型的 hidden_layer 和 hidden_dim 就是选了个大一点的，就把 medium 过了。

Strong

首先将 hidden_layers 改成 6，让 train_acc 够大，同时再加入正则化方法。

有的帖子是将 relu 放在 batchnorm 前，实际上我觉得这是不对的，不仅是在很多网络架构上都不是这样的，同时我觉得把 batchnorm 放 relu 前有以下理由：

BN 的目的是对输入进行标准化（均值为 0，方差为 1），而 ReLU 是非线性激活函数。如果 BN 放在 ReLU 前，可以确保输入 ReLU 的数据分布更稳定，避免梯度消失 / 爆炸问题。

ReLU 对负值的截断（输出为 0）可能导致部分信息丢失。若先进行 BN，负值可能被保留（通过平移和缩放），从而让 ReLU 的激活更灵活。

具体参数为：

由于 num_epoch 有点大，为了加快训练速度，将 batch_size 改成了 2048。这个原理在李宏毅老师的课里有：

训练和验证集上结果为：

测试集上结果为：

刚好把 strong_baseline 给过了。

Boss

由于 boss_baseline 是要引入 RNN 等架构，目前的计划是更想有个通用的了解再去对某个方向深入，所以暂时搁置，日后有空再补。

Report Questions

question1

只修改模型结构，其他参数不变，结果分别为

narrower and deeper：

wider and shallower：

可以看出越宽越浅的表现略好训练时间略短，不过相差不大。

question2

在 BasicBlock 中加入 dropout 层，dropout rate 分别为 0.25、0.5、0.75，其余保持不变，结果分别为：

dropout rate=0.25：

dropout rate=0.5：

dropout rate=0.75：

随 dropout rate 升高，最好的 val_acc 都降低了，再对 dropout rate 低一点的时候看看：

dropout rate=0.2：

dropout rate=0.1：

貌似随着 dropout rate 升高，val_acc 都会降，猜想这可能是 simple code 的 train_acc 太低了，自己都没够好，model 的 bias 太大了，所以加入 dropout 之后，效果反而更差（train_acc 变得更小，所以减少泛化误差 val_acc 也没有比原来好，采取合适的 dropout rate 加几个 epoch 效果肯定比之前好）。