深度学习的硬件和方法
目前面临的挑战
1.模型的尺寸
越来越大,很难用在移动设备上 对于自动驾驶,只能在线更新模型,对大小也比较敏感
2.速度
巨大模型的训练速度很慢 ResNet152 的准确率仅仅比 ResNet101 高 0.1%,但是训练时间几乎是后者的 1.5 倍
3.能耗问题
alphaGO 打败李世石,仅仅电费就花了 3000 美元
什么造成了如此大的能耗?
越大的模型->对存储器的访问越多->能耗越大 比较可以看出,对 DRAM 的访问能耗比其他操作(算数运算)要大很多
解决办法——改进算法和硬件(算法和硬件的联动设计)
硬件主要有两个分支,通用硬件(可以用于任何领域)、专用硬件(为某领域内特定的应用服务) 通用硬件:CPU(延时导向,单线程,一头大象)、GPU(吞吐量导向、有很多弱小的线程,一群小蚂蚁) 专用硬件:FPGA(现场可编程门阵列)、ASIC(特定用途集成电路,有固定逻辑,就为某种用途所涉及) Google 的 TPU 就是一中 ASIC
计算机中的数,不是用纯数表示,它实际上是离散的(有一定的分辨率,也就是精度) TPU 使用的是 int8,之所以不选择传统的 32 位浮点数,是因为运算开销太大
高效推断的算法
1. 修剪神经网络(剪枝)
移除一些权重,同时保证准确度不变,去掉冗余的连接 训练---剪枝---重新训练----剪枝----重新训练 上述循环,使得参数不断减少,但是重新训练又使得准确率再次升高 但是剪枝的时候,有一个阈值,超过阈值会使得准确率很低
2. 权值共享
不是所有的参数都需要准确值,有些近似就可以,太精准的数字只会导致过拟合 思路是把所有权重聚类,如果相近,就用一个聚类质心来表示这个数(而不是把精度完全保留) 权值共享后,参数变得离散化
上面两种方法结合,甚至可以将模型缩小到原来的 3%且准确率不降低,压缩比更好
3. 哈夫曼编码
用哈夫曼编码,用更多的位数表示不经常出现的权重,更少的位数表示经常出现的权重
前面这些,是精简现有的复杂模型,还有种思路,是直接设计精简的模型
SqueezeNet
在 3×3 卷积之前,先使用通道数更少的层 进过Squeeze层挤压通道,之后进入expend分支层,再concat连接起来 即使不压缩,squeezeNet 也比 AlexNet 小 50 倍,且准确率相同 压缩 510 倍也还有同样的准确率
上面的是非线性量化方法,下面是被广泛用于 TPU 设计中的量化理论,所有的 TPU 设计仅使用 8 位来推断
量化
比如用
- 用浮点数训练
- 收集每一层的权重和激活值,来量化权重和激活值(比如收集最大、最小,来决定用多少位表示权重和激活值比较合适)
- 微调浮点数的格式
- 使用定点数前向传播,用浮点数反向传播并更新权值
#### 低秩近似 low rank approximation 可以把一个卷积,拆分成两步卷积(前面一个卷积,后面一个1 × 1卷积) 把一个复杂问题,分成了两个独立的小问题
全连接层中,用奇异值分解(SVG),把一个矩阵拆分成两个矩阵 使用一个张量树,将一个全连接层分成许多全连接层的树
二元/三元权重
\(-1,0,1\) 训练时,保留完全正确的权重,但在推断时,仅保留尺度因子和三元权值
Winograd 交换
进行一个3 × 3卷积,得到4个输出
- 直接卷积需要3 × 3 × C × 4=36 × C
- winograd 交换需要4 × 4 × C,得到的4 × 4矩阵,分割成4个输出
高效推断的硬件
目标:最小化访存能耗 TPU 的核心是巨大的矩阵乘法运算器 视频中是90万亿次/s 的浮点运算,现在3.0已经 100 千万亿次/s 但是为了实时,分批计算,达不到理论速度
EIE,稀疏性,不考虑0,
高效的训练算法
#### 并行化 单核性能进入瓶颈,但是线程数不断增加 数据并行:多张图片一起输入(每次批处理数量更多)---权值之间协同更新 有一个参数服务器,分别训练把更新的参数传回服务器 模型并行:一张图片切成多块,每一块分别在一个内核中计算 超参数并行化:在不同机器上调整学习速率和权值衰减,这是一个很粗略的并行
混合精度训练
一部分用 32 位,一部分用 16 位。16 位进行乘法运算,32 位输入累加器进行加法运算,保证输出的权值是 32 位
模型精馏
迁移学习,模型压缩 大型深度神经网络作为老师,去教小的模型 不使用硬标签,而是用软标签,就是用可能性概率,概率大的是真,就预测对。软标签使得 lable 的信息大大增加,不再是普通的是狗是猫,而是一个分布概率,熵值更大
密-疏-密训练(更好的正则化)
剪枝之后,再复原删掉的连接
高效训练的硬件
专门计算矩阵的组件