查看: 1177|回复: 0

AI视觉组仙人一步之模型调优

[复制链接]
  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3300

    主题

    6547

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32032
    最后登录
    2024-4-26
    发表于 2021-2-4 16:37:55 | 显示全部楼层 |阅读模式
    AI视觉组仙人一步之模型调优

    本文专为参加今年大学生智能车竞赛AI视觉组的同学们而写,也很适合其他对MCU上AI应用感兴趣的朋友。


    在前一篇推文,“智能车大赛AI视觉组参考答案”中,相信大家已经听说了Keras这员猛将。我们利用Keras中的Sequential模块构建模型,并最终利用NNCU工具将模型部署到了MCU上,成功实现了AI视觉组的其中一个任务目标:水果动物识别。
    今天,小编为大家带来的是构建模型的进阶篇,如何进行模型调优,以获得效果最好的模型。
    但是,这次我们将要抛弃Sequential这种串糖葫芦的方式,毕竟,模型的复杂程度在一定程度上对于识别的效果有着千丝万缕的联系,为了能够获得更加强大的模型,我们这次要改用更加灵活强大的函数式API进行模型的构建。


    函数式API


    首先简单介绍下何为函数式API,这是一种专用于定制复杂模型的方式,像是乐高积木,完全由用户设计,支持任意输入,任意输出,以及任意的静态图拓扑。
    看到三连发的任意这任意那,恐怕不少同学们都已经被唬住了,自信一点,他就是这样强,不要怀疑。


    下图就是利用这种方式搭建了一个包含输入层和三层全连接的模型。是不是看着很清爽?比起Sequential的方式,最大的改进就是,每一层不是通过modle.add进行添加,而是将每一层都当作一个带参函数,并且可以灵活指定其输入输出,以达到构建任意模型的目的。
    31.png
    这样一来,上一期的模型,就可以拿来重新构造了,实现方法也很简单,只需要将.add去掉,并合理安排各个层之间的输入输出向量的关系即可,小编在这里就当个引路人,更加复杂的模型就要靠同学们头脑风暴一下了:
    32.png
    深度学习的基础是模型没错,一个好的模型可以事半功倍。但是,不要忘了,这只是成功的前提,更加重要的是如何优化训练过程。真正发挥模型的潜力。小编在这里就给大家分享几点模型调优的方法,也希望同学们能够分享下自己在应用过程中所积累的经验。


    训练方式的权衡

    首先,介绍下Keras支持的两种训练方式,其一就是我们在“智能车大赛AI视觉组参考答案”推文中所用到的方法——集中式数据加载,这种方式(model.fit(xx))的好处是实现简单,可以实现发射后不管,用户需要关心的仅仅是数据集的准备以及epoch和batch_size参数的设置。
    其缺点也是显而易见,这种方式,Keras在进行模型训练的时候,会将数据集一次性装入内存,可是,地主家也有缺粮食的时候啊,如果遇到数据集巨大的情况,我们的内存可能就要哭诉“臣妾办不到啊”。
    33.png
    这个时候,我们就要考虑使用另一种方法了——分散式数据加载,这种方法(model.fit_generator(xx))的用法几乎与前者相同, 但是,此时data就不能直接传入数据集本身了,需要手动去定义一个data的generator,以迭代器的形式表示数据集,手动控制数据导入,每次仅装入一个batch,保护弱小的内存,详细的使用方法,可参考https://www.tensorflow.org/api_d ... Model#fit_generator
    34.png
    模型设计原则


    接下来,开始模型调优的正式篇。


    在这之前,我们要先明确,卷积神经网络的本质是特征的提取,如何提取高质量的特征,是重中之重,而不同深度的层对于特征的提取是不同的。其中,浅层网络负责提取基础特征,比如边缘,轮廓等,深层网络提取抽象特征,更像是基础特征的组合。对于分类网络,通常最后一层会跟着一个全连接层,对这些特征进行组合,以评分分类。
    针对此,我们在进行模型设计的原则,通俗点讲就是deeper and deeper,wider and wider,深度是针对于网络层而言,而宽度是指针对某一层所对应的模型输出通道数。
    一般而言,模型层数越多,所提取的抽象特征所具有的表达能力就会越强,因为他们能够学到更加复杂的表达。想象一下,如果模型只有一层,那就意味着所要学习的变换会非常的复杂,这很难做到。
    而模型越深,可以缓解每一层的压力,不必要去过度拟合。而如果模型更宽,可以让每一层学习到更加丰富的特征,比如不同方向,不同频率的纹理特征。
    更深、更宽一定好吗?

    当然,网络也不是越深越好,网络太深最容易导致的问题是梯度消失,解决方法是引入残差连接网络,例如mobilenet v2中的bottleneck块,引入通道间的高速通道,将梯度信息直接传递到下一层。
    而如果网络宽度过大,会大大影响系统的计算效率,因此,需要合理设计,达到最优效果。再补充说明一下,在进行模型构建的时候,可以引入一些经典的网络块,这些网络块本身已经被实践说明是很有帮助的,比如Inception:引入更宽的网络,参数更少;Densenet:强调特征的复用,善于检测小物体;还有提到的mobilenet v2:解决梯度消散问题。


    另外一个需要注意的是模型过拟合的存在,过拟合的最典型现象就是,发现模型本身在训练集上的效果很好,几乎能够达到100%的分类精度,而在测试集上的表现却是差强人意。究其原因,无非是两种,其一数据集体量过小,其二是模型过于复杂。


    针对模型本身存在的问题,可以考虑适当对模型结构进行精简,或是插入一些特殊的层,比如batchnorm层和dropout层,对于dropout层,其在训练期间会自动忽略一些层不参加训练,在不修改模型本体的基础上,间接的缩减模型尺寸。一般设置丢弃率为0.25-0.3,但是在模型推理中,不受影响,且一般插在Dense层之后。


    他山之石:迁移学习


    针对数据集问题,最简单的方式是采用数据增广的方式,对数据集进行扩充,有兴趣的同学可以自行调研。


    还有一个强烈推荐的方式,是迁移学习。正如其名,迁移学习就是把已经训练好的模型参数迁移到新的模型来帮助新模型进行训练。考虑到大部分数据或任务都是存在相关性的,所以通过迁移学习我们可以将已经学到的模型参数(也可理解为模型学到的知识),通过某种方式来分享给新模型,从而加快并优化模型的学习效率不用像大多数网络那样从零学习。


    这样做的好处是:


    站在巨人的肩膀:前人花费精力训练出来的模型可以直接拿来用,没必要重复造轮子
    训练成本降低:可以通过导出特征向量的方法进行学习,降低训练成本
    适用于小数据:小数据训练大型网络,往往力不从心,导致过拟合,但是,我们知道大的模型的能力很强,具有超强的特征提取能力,但是往往训练困难,此时就需要迁移学习进行参数的共享
    针对于不同数据集情况下,通常有以下一些迁移学习策略:
    数据量少,相似度高:一般只需要修改最后几层或最终的softmax层输出类别
    数据量少,相似度低:冻结前几层,对剩余层重新训练。由于新数据集相似度低,因此对较高层进行重新训练是有意义的
    数据量大,相似度低:有了大的数据集,利于重新训练,同时由于与用于训练的数据集相比又很大不同。直接使用预训练模型不会有效,可以考虑重新训练
    通常做法是阶段预训练模型的最后一层,按照分类类别进行修改。
    有了迁移学习,即便数据量很少,我们也可以借用大的网络模型应用于我们的任务中,
    不用再因巧妇难为无米之炊而烦恼了。不过,在使用时候,还是要尽量找到与当前任务比较近似的模型进行迁移学习,比如这次视觉组的识别动物和水果的模型,可以直接从网上找到一些针对CIFAR10或是imagenet的模型来进行迁移,毕竟他们本身都是一些分类模型,而且所属类别也很相似。


    小结
    至此,小编今天介绍了如何使用函数式API进行模型的搭建,并介绍了模型调优的一般方法,最后,针对于数据量少的情况,强烈建议大家能够站在巨人的肩膀上,利用迁移学习的方式进行模型的再训练,省时省力的同时,还能大大提高模型的训练效率以及模型的精度。


    如果大家遇到一些使用上的问题,欢迎在评论区留言。有一些想法的,也欢迎同学们积极分享。










    签到签到
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-27 05:49 , Processed in 0.116473 second(s), 20 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表