李宏毅ML2022 Spring HW3解析

作业3是食品分类,可以在台大网站下载相关代码和PPT:ML 2022 Spring

参考了机器学习手艺人的李宏毅2022机器学习HW3解析_2022 hw3-CSDN博客【深度解析→博文总结】李宏毅机器学习2023作业03CNN(Image Classification) - 知乎的解析,因为很多概念都没学过,有点无从下手,想着还是要自己动手才能学会,于是便一个个知识点去学习应用。

Data augmentation(数据增强):

数据增强就是通过对原图进行各种变换再做训练,相当于训练的样本增加了,从而提升模型的泛化能力。这也是HW3的问题1要解答的。

我加的都是Random的变换,因为每次获取训练数据的时候,都是把所有的变换操作都执行一遍的,如果不是随机变换,那原图就永远不会参与训练,只有转换以后的图片才会参与训练,那训练效果可能就不好了。

train_tfm = transforms.Compose([
    # Resize the image into a fixed shape (height = width = 128)
    transforms.Resize((128, 128)),
    # You may add some transforms here.

    transforms.RandomResizedCrop(size=(128, 128), antialias=True),
    transforms.RandomHorizontalFlip(p=0.5), #50%的概率水平翻转
    transforms.RandomVerticalFlip(p=0.5), #50%的概率垂直翻转
    transforms.RandomRotation(degrees=(0, 180)),
    transforms.RandomAffine(degrees=(30, 70), translate=(0.1, 0.3), scale=(0.5, 0.75)),
    transforms.RandomCrop(128, padding=10),
    transforms.RandomGrayscale(p=0.1),  #根据概率转灰度
#     transforms.ColorJitter(brightness=0.5, contrast=0.5, saturation=0.5, hue=0.1), #修改亮度、对比度和饱和度,色调


    # ToTensor() should be the last one of the transforms.
    transforms.ToTensor(),
])

validate的时候要不要加入变换呢?我的理解是要加入,因为validate和train使用相同的样本数据才能保证保存下来的是合适的模型。如果只在train加入变换,validate不做变换,那相当于两者的样本空间不一样,train的时候表现最好的模型,在validate中表现不一定最好。

Test Time Augmentation(TTA):

TTA是在test阶段的数据增强,即在预测的时候将原图变换出来的多张图片分别进行分类,再综合分类结果的方法。

有一个开源的库可以做TTA:https://github.com/qubvel/ttach,但是似乎没有效果,不知道是不是我用错了或者理解错了。自己写了一个简单的函数实现TTA。

def mytta(model, data):
    tfm_list = [    
        transforms.RandomResizedCrop(size=(128, 128), antialias=True),
        transforms.RandomHorizontalFlip(p=0.5), #50%的概率水平翻转
        transforms.RandomVerticalFlip(p=0.5), #50%的概率垂直翻转
        transforms.RandomRotation(degrees=(0, 180)),
        transforms.RandomAffine(degrees=(30, 70), translate=(0.1, 0.3), scale=(0.5, 0.75)),
        transforms.RandomCrop(128, padding=10),
        transforms.RandomGrayscale(p=0.1),  #根据概率转灰度channel=1,CNN中in_channel=3,不可行
#         transforms.ColorJitter(brightness=0.5, contrast=0.5, saturation=0.5, hue=0.1) #修改亮度、对比度和饱和度,色调
    ]
    base_rate = 0.5
    pred = base_rate * model(data)
#     print(f'original pred shape: {pred.shape}')
    aug_rate = (1 - base_rate) / len(tfm_list)
    for tfm in tfm_list:
        pred += aug_rate * model(tfm(data))
    
    return pred

上面的代码在TPU可以正常运行,但是在GPU就会引发一个view函数异常,因为变换以后tensor变成不连续的,导致不能直接使用view函数操作。具体参见这篇文章CSDN

关于TTA有一个疑问,是不是在validation的时候也要增加Data Augmentation呢?因为如果没有变换,通过validation找到的最优模型不一定是真的最优模型。

ResNet(残差网络):

残差网络的思想比较简单,就是在网络输出中加上网络输入,这样做可以在最差的情况下(网络训练不好),还能保证输出跟输入一样的数据。通过这种技术使训练多层的网络变得容易起来。放上一张原文的图片就很清晰了。

因为作业不能采用预训练的模型,我尝试了ResNet18,发现要训练的次数比一般自己拼凑的CNN要多得多,计算资源都不太够了,最后用cross validation只训练了3个模型,都跑了600 epochs。

这里又有一个小插曲,前两个模型都没有接全连接层,直接就拿来用了,在assemble的时候才发现,resnet的输出维度是batch*1000。神奇的是,它不用接全连接层也是可以训练和测试的,通过tensor的广播机制蒙混过去了。因为分类是11类,所以最终输出结果里,只有前11列是正数,其他都是负数。因为计算资源有限,所以只能凑合着用了,效果也还行。

Cross Validation + Ensemble

在机器学习里常用的k折交叉验证,这里也派上用场,这里是通过k折,将数据拆分成k份从而训练出k个相对独立的模型,再采用Ensemble方法提升精度。Ensemble说穿了也很简单,就是把多个模型输出的结果做一个整合,有很多方法可选,我用的是输出平均。

我采用k=10,但是因为计算资源有限,只训练了几个模型,用90%的数据训练,再用10%的数据做validation。这两种方法都可以有效提升精度。

Accelerator:

因为要使用多个GPU训练,所以要考虑并行,默认情况下训练只在一个GPU进行。有一个HuggingFace这个项目很好用https://github.com/huggingface/accelerate,不用对原来的代码进行大的调整就可以使代码在多个GPU并行。

有几个踩过的坑记录一下:

(1)Accelerator(mixed_precision='fp16'),带了这个参数就训练不起来,可能是因为数据精度太低,不太确定。

(2)用了set_seed就要把其他配置seed的地方注释掉,否则会报错,re-init  重复初始化问题(RuntimeError: Cannot re-initialize CUDA in forked subprocess. To use CUDA with multiprocessing, you must use the 'spawn' start method)。

(3)还有一个疑问:我的理解是一个epoch里的batch分到两个GPU上计算梯度,计算累加起来做更新,更新的频率可能是两个batch一次,不知道理解得对不对,还是一个epoch只更新一次?

最终结果:

按照网上的资料,学习ResNet,训练ResNet18,600epochs,达到Score: 0.82569。
训练普通的cnn网络,用10-fold训练了2个model,做assemble,也达到了0.82586

尝到甜头以后,尝试训练更多的model,做assemble,最终达到0.88047,还没有达到boss line 0.88446。不过预计多加几个模型或者微调一下就可以达到了,就不继续刷了。

  • 26
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
李宏毅ML2021春季课程的第三个作业是一个关于自然语言处理任务的实践项目。这个作业涵盖了文本分类、情感分析和命名实体识别等主题。 学生们的任务是使用提供的数据集,通过实现机器学习算法,对文本进行分类和情感分析。对于命名实体识别,学生们需要利用已有的工具和技术来提取文本中的实体,例如人名、地名、组织名等。 在这个作业中,学生们需要掌握一些基本的自然语言处理技术和算法。他们需要了解常用的特征提取方法,例如词袋模型和TF-IDF。此外,学生们还需要学习基本的分类算法,如朴素贝叶斯和支持向量机。在情感分析任务中,学生们需要了解情感词典和情感分析的基本原理。 此外,学生们还需要使用Python编程语言和相关的自然语言处理工具库,如NLTK和SpaCy。通过实践项目,学生们将获得与自然语言处理相关的实际经验,并加深对机器学习模型和算法的理解。 完成这个作业需要一定的时间和努力。学生们需要仔细阅读作业要求和相关文档,并按照要求完成代码实现和实验报告。他们还需要参考课程讲义和推荐的学习资源,以加深对自然语言处理领域的理解。 总的来说,李宏毅ML2021春季课程的HW3是一个涉及自然语言处理任务的实践作业。通过完成这个作业,学生们将掌握基本的自然语言处理技术和算法,并获得与自然语言处理相关的实际经验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值