【深度解析→博文总结】李宏毅机器学习2023作业02Classification(Framewise Phoneme Prediction)

【系列文章】

【专栏:深度解析李宏毅机器学习2023作业】

【简要说明】

1、本次博客总结记录作业02Classification的调参经验,如下图所示,最终本人的模型方案在Public Test和Private Test都达到了Boss Baseline【Public排名第6,分数0.85201>0.83017;Private排名第4,分数0.85240>0.83058】,欢迎入门和深入机器学习知识的朋友们能在评论区多多交流,共同进步。
在这里插入图片描述

2、本人是从事基于深度学习相关研究的一名博士,目前博士在读第5年。深感自己在机器学习/深度学习理论知识实际调参经验方面都不够系统,今年希望能够跟随李宏毅教授的机器学习2023的作业在理论和实践方面都得到提升。
3、本次博文总结主要记录3种模式的方法处理Framewise Phoneme Prediction问题时的调参心得与历程,3种方法的大致架构如下图所示,第1、2种为能够达到Strong Baseline的方法,第3种为能够达到Boss Baseline的方法。
在这里插入图片描述
4、第1种为助教样例代码里的全连接层堆叠的方法,第2种方法为将全连接层(除最后一层)替换为LSTM层提取时序特征,这种方法主要是把最后一层LSTM的最后时刻的隐层特征(Pytorch代码中表示为h_n)输入到全连接层映射到对应类别数,模型输入需要在第1种的助教样例代码里加入Reshape函数进行处理,是Frame-wise Classification的方法,第3种方法与第2种结构相似,不同之处在于是把最后一层LSTM的输出(Pytorch代码中表示为output)输入到全连接层映射到对应类别数,模型输入需要自行整理代码实现数据预处理(即把每一段语音序列切割成等长的子序列用于训练),是Sequence-wise Classification的方法。

【视频分享】

如果在文章上想把Boss Baseline的方法讲明白,那可能需要好几万甚至几十万字,因为可能需要先讲明白前两种方法,加上涉及的领域知识会有点多,字数太多了也不利于阅读。因此,录制了以下3期视频,系统梳理上述3种方法。

【深度解析→视频分享】李宏毅机器学习2023作业02Classification-第一期

【深度解析→视频分享】李宏毅机器学习2023作业02Classification-第二期

【深度解析→视频分享】李宏毅机器学习2023作业02Classification-第三期

【作业详情】

1、【作业简介】李宏毅教授的助教也将作业02Classification进行了详细的介绍,包括:作业内容解读、Kaggle提交介绍、代码调参提示和样例代码详解,视频已搬运至知乎和B站,详情见【知乎】【B站】。
2、【先修视频】:该作业在李宏毅教授课程官网列了五个先修视频(是李宏毅老师2021年的机器学习课程视频,课程网页:https://speech.ee.ntu.edu.tw/~hylee/ml/2021-spring.php),但我个人觉得其视频整理的有点问题,包括2021年的课程网址上整理的也有问题,因为我仔细看过了,认为先修视频应该是共有六个,【建议】按照我整理的顺序进行观看。因为B站上转载视频总是撞车导致无法上传,我只能按顺序整理到知乎上了【先修视频01】【先修视频02】【先修视频03】【先修视频04】【先修视频05】【先修视频06】。
3、【强烈建议】:以上六个先修视频建议在做作业二之前全部认真看一遍,并建议在做作业过程中调参无法继续有效时,返回去反复观看以上六个先修视频,这样是有助于在实践中掌握如何有效调参。作为过来人,本人非常不建议按照所谓打卡的形式对机器学习/深度学习系列的视频进行机械式的观看(哪怕是李宏毅老师这么趣味性的讲解都会容易坚持不下去),务必注意理论知识观看顺序、动手实践作业调参,这样有助于系统掌握机器学习/深度学习。
4、【Boss Baseline先修视频】:在本人的知乎主页还上传了另外7个先修视频,2个是李宏毅老师2020年课程网页的RNN讲解视频(实际录制时间是2017年,最后一次正式出现在课程网址是2020年了),另外5个是之前学习看到过的王树森老师的RNN相关讲解视频。如果想要本次作业达到Boss Baseline的话,建议按顺序过一下这些视频:【先修视频07】【先修视频08】【先修视频09】【先修视频10】【先修视频11】【先修视频12】【先修视频13】。

【调参记录】

【Simple Baseline:0.49798】

1、第1种模式的方法下:直接跑通助教的样例代码,这里concat_nframes在样例代码中为3,即可达到Simple Baseline,下图是我的提交记录截图在这里插入图片描述2、第2种模式的方法下:这里将concat_nframes设置为11了(模型输入需要在第1种的助教样例代码里加入Reshape函数进行处理,其它保持与样例代码一致),即可达到Simple Baseline,下图是我的提交记录截图在这里插入图片描述

【Medium Baseline:0.66440】

1、第1种模式的方法下:修正样例代码错误&concat_nframes设置为11&Epoch数为30&使用Report Question提示的Wider模型(设置hidden_layers = 2,hidden_dim = 1750)即可达到Medium Baseline,下图是我的提交记录截图在这里插入图片描述2、第2种模式的方法下:修正样例代码错误&concat_nframes设置为11&Epoch数为30&使用双向LSTM(模型输入需要在第1种的助教样例代码里加入Reshape函数进行处理,其它保持与样例代码一致),即可达到Medium Baseline,下图是我的提交记录截图在这里插入图片描述

【Stong Baseline:0.74944】

1、第1种模式的方法下:concat_nframes设置为43&Epoch数为3000&设置hidden_layers = 6,hidden_dim = 1750&学习率初始值为1e-3&添加BN和Dropout(设置drop_rate为0.5),即可达到Stong Baseline,下图是我的提交记录截图在这里插入图片描述2、第2种模式的方法下:concat_nframes设置为35&Epoch数为30&使用双向GRU&hidden_layers = 8,hidden_dim = 256&dropout_rate=0.5,(模型输入需要在第1种的助教样例代码里加入Reshape函数进行处理,其它保持与样例代码一致),即可达到Stong Baseline,下图是我的提交记录截图在这里插入图片描述第2种模式的方法对应的核心代码如下:Reshape函数位于Classifier定义中forward()函数的第二行,其它部分均与样例代码保持一致即可。

import torch.nn as nn
import torch


class BasicBlock(nn.Module):
    def __init__(self, input_dim, output_dim):
        super(BasicBlock, self).__init__()

        # TODO: apply batch normalization and dropout for strong baseline.
        # Reference: https://pytorch.org/docs/stable/generated/torch.nn.BatchNorm1d.html (batch normalization)
        #       https://pytorch.org/docs/stable/generated/torch.nn.Dropout.html (dropout)
        self.block = nn.Sequential(
            nn.Linear(input_dim, output_dim),
            nn.ReLU(),
        )

    def forward(self, x):
        x = self.block(x)
        return x


class Classifier(nn.Module):
    def __init__(self, input_dim, output_dim=41, hidden_layers=1, hidden_dim=256, drop_rate=0):
        super(Classifier, self).__init__()
        self.lstm = nn.GRU(input_size=39, hidden_size=hidden_dim, num_layers=hidden_layers, bidirectional=True,
                            batch_first=True, dropout=drop_rate)
        self.fc = nn.Linear(hidden_dim*2, output_dim)

        # self.fc = nn.Sequential(
        #     BasicBlock(input_dim, hidden_dim),
        #     *[BasicBlock(hidden_dim, hidden_dim) for _ in range(hidden_layers)],
        #     nn.Linear(hidden_dim, output_dim)
        # )

    def forward(self, x):
        b = x.shape[0]
        x = x.view(b, -1, 39)  # b,l*hin ==>b,l,hin
        x, h_n = self.lstm(x, None)  # x:b,l,h  h_n:d*num_layer,b,h
        # x = x[:, -1, :]  # final state of final layer  ==>  x:b,h
        x_fd = h_n[-2, :, :]  # forward final state of final layer  ==>  x:b,h
        x_bd = h_n[-1, :, :]  # backward final state of final layer  ==>  x:b,h
        out = self.fc(torch.cat([x_fd, x_bd], dim=-1))
        return out

一键式执行Strong Baseline完整代码已整理好,并上传至百度网盘,提取码:2023。

【Boss Baseline:0.83017】

1、根据验证集的指标看(这次的作业根据计算的验证集的Acc和测试集的Acc进行对比,发现两者基本是相等的,当我没有在验证集上获得大幅提升的更好的结果时,比如0.8,我就没有去进行提交),第1种模式的方法下,我这边预计能调到最佳的结果为0.773左右;第2种模式的方法下,我这边预计能调到最佳的结果为0.789左右。
2、第3种模式的方法下,模型输入需要自行整理代码实现数据预处理(即把每一段语音序列切割成等长的子序列用于训练):切割子序列长度为100&切割步长为40&&Epoch数为300&使用双向GRU&hidden_layers = 10,hidden_dim = 115&dropout_rate=0.4&学习率初始值为1e-3&使用CosineAnnealingLR策略&train_ratio=0.85&使用标签平滑正则化,最终提交结果为0.83205,下图是我的提交记录截图在这里插入图片描述使用3个模型Ensemble策略提交的记录如博客最上方的图所示,结果是0.85201(Public Test排名第6),如果切割子序列长度继续增加、顺着hidden_layers = 10,hidden_dim = 115继续微调模型、Ensemble模型个数再增加一两个,应该可以继续提升分数,当然,如果升级模型采用Transformer的结构,应该分数也会得到进一步提升。

【资源链接】

【2023机器学习】的系列资料包括 视频、课件、代码 等资源已经系统顺序命名并整理到百度网盘:https://pan.baidu.com/s/1-zfs0wn5rccTRVk34YZWaA,提取码:2023。

【写在最后】

原创&整理不易,我的是文章如果有帮到你,或者你觉得还不错,麻烦点赞支持下!

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

22世纪冲刺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值