“老实人”处事容易遇到障碍,并不是因为“老实”本身,而是由于老实人缺乏成功的某些特质
所谓深度学习,是建立在神经网络的基础上,通过大量叠加层,构建出具有深度的网络。而大模型在某种意义上也是类似的思路,通过组建出具有大量参数、深度的模型,提高模型的表达能力。
一个典型的CNN网络——VGG
该网络用于手写数字识别,具有如下特点:
- 基于
3*3的小型滤波器的卷积层 - 激活函数是
ReLU - 全连接层后使用
Dropout层 - 基于
Adam的最优化 - 使用
He初始值作为权重初始值
通过组合以上手段,该网络在MNIST数据集上可以达到99.38%的准确率。
我认为深度学习的难点在于
网络层级的选择与构造,超参数的选择。对于一个全新的问题,如何才能设计出效果最好的网络?加上神经网络的运算过程可以看做是黑盒,具有无法预测的特点,更提升了设计网络的难度。 设计网络层数和结构是深度学习研究和应用中非常活跃的研究领域,没有固定的规则,往往需要根据具体情况反复试验和调整。
进一步提升识别精度
集成学习、学习率衰减、数据扩充(Data Augmentation)都是可以提高识别精度的技术。
Data Augmentation基于算法人为地扩充输入的训练图像,能够提升训练数据量,进而增强模型的表达能力。通过施加旋转、垂直或水平方向上的移动等微小变化,增加图像的数量。在数据集的图像有限时尤其有效。
图:Data Argumentation
可以采用的变换方式有:
- 旋转
- 移动
- 放大缩小
- 左右翻转flip
- 裁剪crop
- 亮度变化
- 颜色变换
加深层
从以往的大规模图像识别比赛结果中可以得出结论:层越深,识别性能也越好
加深层可以减少网络的参数数量
与没有加深层的网络相比,加深层的网络可以用更少的参数达到同等或者更强的表现力。比如在卷积运算中,同样是把5*5的输入数据计算得到1*1的输出,如果只有一层,则需要5*5=25个参数,如果是2层的话,就是3*3*2=18个参数。
图:
5*5卷积运算与重复两次的3*3卷积运算
通过叠加小型滤波器,可以减少参数数量,扩大感受野(receptive field,指给神经元施加变化的某个局部空间区域)。同时可以将ReLU等激活函数插入到卷积层中,进一步增强模型的非线性表达能力。
加深层的另一个好处是使学习更加高效,在CNN图像识别的例子中,多个层可以由小及大逐步进行学习,分层次地传递信息,将各层要学习的问题分解成容易解决的简单问题。
深度学习历史
图:ILSCRV优胜队伍的成绩演变,纵轴为错误识别率,横轴是年份,括号内为队名/方法名
- 2021年举办大规模图像识别大赛ILSVRC(ImageNet Large Scale Visual Recognition Challenge)中,基于深度学习的AlexNex逆袭夺冠,开启了深度学习为王的时代
- 2014年的VGG是把有权重的层(卷积层、全连接层)设置为16(称为VGG16)或者19(称为VGG19),多次重复了“卷积层重叠2~4次,在通过池化层将大小减半”的处理。其识别准确率虽然低于同年的GoogleNet,但由于结构简单应用性强,被很多技术人员所青睐
- 2014年夺冠的GoogLeNet,其网络不仅在纵向上有深度,在横向上也存在深度(广度),称为Inception结构
- 2015年ResNet(超过150层) 将错误识别率降低到3.5%,已经超过普通人的识别能力。其特征是具有比以前的网络更深的结构,为了解决网络过深带来的学习性能问题,导入了“快捷结构”(也称为“捷径”或“小路”),它跳过了输入数据的卷积层,将输入直接作为输出
图:VGG
图:GoogLeNet
图:ResNet
迁移学习与预训练
迁移学习 Transfer Learning
将他人模型的学习成果吸纳和改造,在此基础上,得出新的模型的过程,叫做迁移学习。迁移学习能够重用已经学到的知识而不必从零开始,节省大量的资源和时间。
迁移学习将一个完整的训练任务分为两个阶段:预训练和微调训练。
预训练模型 Pre-Trained Model
预训练模型是前人为了解决类似问题所创造出来的模型。在解决问题的时候,不用从零开始训练一个新模型,可以从在类似问题中训练过的模型入手。作用是节约大量的计算资源和计算时间,提高计算效率乃至准确率。
微调 Fine Tuning
在预训练模型的基础上,进行少数模型参数的调节,从而使预训练过得模型作用于自己的数据集,并使参数适应自己的数据集。
微调模型有以下几种方法:
- 特征提取:我们可以将预训练模型当做特征提取装置来使用。具体的做法是,将输出层去掉,然后将剩下的整个网络当做一个固定的特征提取机,从而应用到新的数据集中
- 采用预训练模型的结构:我们还可以采用预训练模型的结构,但先将所有的权重随机化,然后依据自己的数据集进行训练
- 训练特定层,冻结其它层:另一种使用预训练模型的方法是对它进行部分的训练。具体的做法是,将模型起始的一些层的权重保持不变,重新训练后面的层,得到新的权重。在这个过程中,我们可以多次进行尝试,从而能够依据结果找到frozen layers和retrain layers之间的最佳搭配
如何使用与训练模型,是由数据集大小和新旧数据集(预训练的数据集和我们要解决的数据集)之间数据的相似度来决定的。
下图表展示了在各种情况下应该如何使用预训练模型:
深度学习的高速化
GPU计算
在AlexNet等CNN网络中,大多数时间都被耗费在卷积层上,卷积层处理时间加起来占据了GPU整体的95%。因此,如何高速、高效地进行卷积层中的运算是深度学习的一大课题。更进一步,深度学习的高速化主要课题是如何高速、高效地进行乘积累加(大型矩阵相乘)运算。
GPU原本是作为图像专用的显卡使用,由于它可以高速地进行并行数值计算,因此GPU计算的目标就是将这种压倒性的计算能力应用于各种用途。
- GPU擅长于大量并行计算
- CPU擅长于连续、复杂的计算
GPU主要由NVIDIA和AMD两家公司提供。虽然两家的GPU都可以 用于通用的数值计算,但与深度学习比较“亲近”的是NVIDIA的GPU。实 际上,大多数深度学习框架只受益于NVIDIA的GPU。这是因为深度学习 的框架中使用了NVIDIA提供的CUDA这个面向GPU计算的综合开发环境。
分布式学习
深度学习伴随着很多试错。为了创建良好的网络,需要反复进行各种尝试,这样一来就必然会产生尽可能地缩短一次学习所需的时间的要求。于是,将深度学习的学习过程扩展开来的想法(也就是分布式学习)就变得重要起来。微软的CNTK,Google的TenserFlow都提供了分布式计算的功能。
分布式学习需要考虑机器间通信、数据的同步等多个无法轻易解决的问题。
量化
在深度学习的高速化过程中,除了计算量以外,内存容量、总线带宽等也有可能成为瓶颈。由于需要将大量权重参数或中间数据放在内存中,因此内存容量至关重要;同时,当刘静GPU/CPU总线的数据超过某个限制时,也会成为瓶颈。因此,需要尽可能减少流经网络的数据的位数。
深度学习并不那么需要数值精度的位数。这是神经网络的一个重要性质。这个性质是基于神经网络的健壮性而产生的。这里所说的健壮性是指,比如,即便输入图像附有一些小的噪声,输出结果也仍然保持不变。可以认为,正是因为有了这个健壮性,流经网络的数据即便有所“劣化”,对输出结果的影响也较小。
以往的深度学习实现中并没有注意数值的精度,Python中一般使用64位浮点数,NumPy中提供了16位版电竞赌浮点数类型(以16位存储,运算本身不以16位进行),即便使用半精度浮点数,识别精度也不会下降。
为了实现深度学习的高速化,位数缩减是今后必须关注的一个课题,特别是在面向嵌入式应用程序中使用深度学习时,位数缩减非常重要。
深度学习的应用与展望
物体检测
从图像中确定物体的位置并进行分类。
图像分割
在像素水平上对图像进行分类,即抠图。
图生文
如图像标题生成。
图像风格变换
将梵高的绘画风格应用于内容图像。
文生图
生成式AI的一个应用场景,如下是基于DCGAN生成的卧室图像。
自动驾驶
自动驾驶需要结合各种技术的力量来实现,比如决定行驶路线的路线计划(path plan)技术、照相机或激光等传感技术等,在这些技术中,正确识别周围环境的技术据说尤其重要。这是因为要正确识别时刻变化的环境、自由来往的车辆和行人是非常困难的。
强化学习 Reinforcement Learning
强化学习与监督学习不同。
强化学习的基本框架是,代理(Agent)根据环境选择行动,然后通过这个行动改变环境。根据环境的变化,代理获得某种报酬。强化学习的目的是决定代理的行动方针,以获得更好的报酬。
里需要注意的是,报酬并不是确定的,只是“预期报酬”。比如,在《超级马里奥兄弟》这款电子游戏中,让马里奥向右移动能获得多少报酬不一定是明确的。这时需要从游戏得分(获得的硬币、消灭的敌人等)或者游戏结束等明确的指标来反向计算,决定“预期报酬”。如果是监督学习的话,每个行动都可以从“教师”那里获得正确的评价。
图:强化学习的基本框架:代理自主地进行学习,以获得更好的报酬