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 效果肯定比之前好)。