-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paththesis.tex
2260 lines (2036 loc) · 222 KB
/
thesis.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\documentclass[
% anonymous,
% print,
]{shtthesis}
\shtsetup{
degree = {master},
degree-name = {工学硕士},
degree-name* = {Master~of~Science~in~Engineering},
title = {量化神经网络的训练方法及其在目标检测中的应用},
title* = {Training~Quantized~Neural~Networks\\and\\Its~Application~in~Object~Detection},
keywords = {高效深度学习,量化神经网络,目标检测},
keywords* = {Efficient~Deep~Learning, Quantized~Neural~Networks, Object~Detection},
author = {李润东},
author* = {Li~Rundong},
institution = {上海科技大学信息科学与技术学院},
institution* = {School~of~Information~Science~and~Technology\\ShanghaiTech~University},
supervisor = {范睿~副教授},
supervisor* = {Professor~Fan~Rui},
supervisor-institution = {上海科技大学信息科学与技术学院},
discipline-level-1 = {计算机科学与技术},
discipline-level-1* = {Computer~Science~and~Technology},
date = {2020~年~6~月},
date* = {June,~2020},
bib-resource = {thesis.bib},
}
% ==============================================================================
% Utility Macros
% ==============================================================================
% ------------------------------------------------------------------------------
% TODO notes
% ------------------------------------------------------------------------------
\usepackage{xargs}
\usepackage[
colorinlistoftodos,
prependcaption,
textsize = tiny,
textwidth = 2.6cm,
]{todonotes}
\setlength{\marginparwidth}{2.6cm}
\newcommandx{\unsure}[2][1=]{\todo[linecolor=red,backgroundcolor=red!25,bordercolor=red,#1]{#2}}
\newcommandx{\change}[2][1=]{\todo[linecolor=blue,backgroundcolor=blue!25,bordercolor=blue,#1]{#2}}
\newcommandx{\info}[2][1=]{\todo[linecolor=OliveGreen,backgroundcolor=OliveGreen!25,bordercolor=OliveGreen,#1]{#2}}
\newcommandx{\improvement}[2][1=]{\todo[linecolor=Plum,backgroundcolor=Plum!25,bordercolor=Plum,#1]{#2}}
\newcommandx{\thiswillnotshow}[2][1=]{\todo[disable,#1]{#2}}
% ------------------------------------------------------------------------------
% Machine learning related stuff
% ------------------------------------------------------------------------------
\usepackage{slashed}
\usepackage{esdiff}
\providecommand{\CE}[2]{\mathrm{CE}\left( #1 \| #2 \right)}
\providecommand{\KL}[2]{D_{\mathrm{KL}}\left( #1 \| #2 \right)}
\providecommand{\Round}[1]{\left\lfloor #1 \right\rceil}
\providecommand{\NoDiff}[1]{\slashed{\nabla} #1}
\providecommand{\FpNet}{f_{\mathcal{W}}}
\providecommand{\QuantNet}{\hat{f}_{\mathcal{W, Q}}}
\providecommand{\NormalDist}[1]{\mathcal{N} \left( #1 \right)}
\providecommand{\EMA}[1]{{ #1 }_{\mathrm{EMA}}}
\providecommand{\Batch}[1]{{ #1 }_{\mathrm{b}}}
\providecommand{\Fold}[1]{{ #1 }_{\mathrm{fold}}}
\providecommand{\Clamp}[1]{\mathrm{clamp}\left( #1 \right)}
\DeclareMathOperator{\sign}{sign}
\providecommand{\mAP}[1]{\mathrm{mAP}^{\mathrm{ #1 }}}
\providecommand{\mAR}[1]{\mathrm{mAR}^{\mathrm{ #1 }}}
\providecommand{\QP}{\texttt{QuantPack}}
% ------------------------------------------------------------------------------
% Drawing and table helpers
% ------------------------------------------------------------------------------
\usepackage{tikz}
\usetikzlibrary{
positioning,
arrows,
calc,
trees,
shapes.geometric,
}
\providecommand\boxit[1]{%
\smash{\color{red}\fboxrule=1pt\relax\fboxsep=2pt\relax%
\llap{\rlap{\fbox{\vphantom{0}\makebox[#1]{}}}~}}\ignorespaces%
}
\usepackage{forest}
\usepackage{circledsteps}
% ------------------------------------------------------------------------------
% Enhanced table, floats and code environments
% ------------------------------------------------------------------------------
\usepackage{ctable}
\usepackage{subcaption}
\usepackage{multirow}
\usepackage{arydshln}
\usepackage{minted}
\usepackage{mdframed}
\definecolor{ShtRed}{RGB}{146, 46, 23}
\definecolor{FriendlyBG}{RGB}{240, 240, 240}
\setminted{
fontsize=\small,
style=friendly,
breaklines,
breakbytoken,
}
\mdfsetup{
backgroundcolor=FriendlyBG,
linecolor=ShtRed,
linewidth=1pt,
topline=false,
bottomline=false,
rightline=false,
innertopmargin=2pt,
innerbottommargin=2pt,
}
\newminted[python]{Python3}{}
\newminted[yaml]{YAML}{}
\BeforeBeginEnvironment{minted}{%
\begin{mdframed}%
\linespread{1.3}%
}
\AfterEndEnvironment{minted}{\end{mdframed}}
\captionsetup{subrefformat=parens, font={small,bf}}
\captionsetup[sub]{font={small,bf}}
\begin{document}
\maketitle
\frontmatter
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% Abstract
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\begin{abstract}
量化神经网络使用低比特整数表示模型参数和激活,其存储和运行开销显著低于一般神经网络模型,从而特别适合部署至计算资源受限的终端设备上。然而在应用至诸如目标检测这类复杂任务时,现有量化神经网络的准确度不能满足要求。加之一般神经网络结构和训练方法在设计时并未考虑量化部署场景,使得量化神经网络在复杂任务上的训练更为困难。
本文指出量化神经网络在目标检测任务上准确度较低的关键原因在于其量化感知训练阶段存在诸多\emph{不稳定性},并提出适用于目标检测模型的量化函数及训练方案。本文称该套量化函数及训练方法为 Fully Quantized Networks for Object Detection (FQN)。FQN 可将目标检测模型参数及激活端到端量化至 4-bit 整数,并在 MS COCO 数据集上较先前最优方法减少 $3.84\times$ 相对 mAP 损失。
本文进一步探索了直接训练\emph{针对量化部署友好}的通用神经网络的方法,称为 Guided Quantization Networks (GQ-Nets)。GQ-Nets 通过在预训练过程中引入模型量化误差,使模型在训练后能直接被量化至 5-bit $\sim$ 2-bit 且保持足够准确度,从而不再需要额外的量化感知训练或微调等过程。在不同数值精度的完全量化及不完全量化场景下,GQ-Nets 在 CIFAR-10、ImageNet 数据集的准确度均能达到或超过先前最优方法。
量化神经网络仍然是一个充满着崭新挑战和机遇的研究领域。未来可能的探索方向包括对部署平台计算资源更合理分配、更高效的优化和训练算法,以及将模型量化技术与 AutoML 结合,在不同任务和硬件平台上最大化部署效率。
\end{abstract}
\begin{abstract*}
Quantized neural networks use low-bit integers to represent model weights and activations, and their storage and running costs are significantly lower than general neural networks, making them particularly suitable for deployment to edge devices with limited computing resources. However, when applied to complex tasks such as object detection, the accuracy of current quantized neural networks cannot meet the requirements. In addition, the general neural network structure and training methods are not designed with quantized deployment scenarios in mind, making the training of quantized neural networks on complex tasks more difficult.
We point out that the key reason for the low accuracy of quantized neural networks in object detection tasks is that there are many \emph{instabilities} in the quantization aware training phase. Quantization functions and training schemes suitable for object detection models are proposed. We refer to this set of quantization functions and training schemes as \emph{Fully Quantized Networks for Object Detection (FQN)}. FQN can quantize the object detection model weights and activations end-to-end to 4-bit integers, and reduce $3.84\times$ relative mAP loss on the MS COCO dataset compared to the state-of-the-art.
We further explore a method of directly training a general-purpose neural network that is \emph{friendly to quantization deployment}, called \emph{Guided Quantization Networks (GQ-Nets)}. GQ-Nets introduce model quantization errors during the pre-training phase so that the model can be directly quantized to 5-bit $\sim$ 2-bit after training and maintain sufficient accuracy, thereby eliminating the need for additional processes such as quantization aware training or fine-tuning. Under the scenarios of fully and partial quantization with different bit-width, the accuracy of GQ-Nets in the CIFAR-10 and ImageNet datasets can reach or exceed the state-of-the-art.
Neural network quantization is still a research area full of new challenges and opportunities. Possible future exploration directions include more reasonable allocation of computing resources on the deployment platform, more efficient optimization and training algorithms, and the combination of neural network quantization with AutoML to maximize deployment efficiency on different tasks and hardware platforms.
\end{abstract*}
\makeindices
\mainmatter
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% Introduction
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\chapter{引言} \label{chap:introduction}
在计算资源受限的智能手机~\citep{howard2019searching}、FPGA~\citep{zhang2019skynet}、自动驾驶控制系统~\citep{falcini2017deep} 等终端设备上部署基于深度学习的算法模型已成为目前工业界和学术界的研究热点之一。深度学习通过一系列非线性级联的参数化卷积、矩阵乘法等操作,在大量任务上展现了惊人的威力 \citep{lecun2015deep};但随着深度学习算法和模型的演进,其对部署设备计算力、存储的需求愈发高昂。终端设备算力、存储空间有限,电池供电的特性更导致了其对频繁访存的能耗开销敏感 \citep{han2017efficient}。因此对模型算力需求、存储需求的控制,是部署深度神经网络至终端设备的主要挑战。
本文旨在通过神经网络量化压缩技术解决上述挑战。深度神经网络一般通过单精度浮点格式(IEEE754 FP32)保存模型参数,并通过部署设备的浮点计算单元进行推理运算;而神经网络量化技术~\citep{qin2020binary} 则通过将模型参数和模型运行时的中间激活映射至相应的 8-bit、4-bit 甚至更低位宽的整数,减少模型存储空间且降低模型运行的复杂度。更低位宽的模型参数缓解了模型存储及运行时访存压力,且相同硬件资源下整数乘法、加法器运算速度高于浮点数值逻辑。目前很多移动端 SoC 包含 DSP、NPU 等专用的整数计算加速模块 \citep{qualcomm2019snapdragon},进一步提高了设备运行量化神经网络的性能。故神经网络量化压缩技术特别适合基于深度学习的终端模型的部署加速。
神经网络量化压缩技术在很多相对简单的任务和模型上获得了成功~\citep{zhou2016dorefanet, Zhang_2018, li2019additive};然而,现有工作很少探索该项技术能否应用于其他更复杂的任务和模型——实际部署至终端的算法通常需要在真实世界的数据上执行多种复杂任务,例如目标检测等。目标检测~\citep{zou2019object} 是众多实际落地的算法系统流程的第一环,例如在智能手机人脸解锁流程中,人脸关键点识别、活体识别等模块都依赖于人脸检测算法输出的人脸边界框;在 Google Translate app 的摄像头实时翻译应用中,文字 OCR、自然语言翻译等算法模块也都依赖于文字检测算法的输出结果。因此,探索对于目标检测算法模型的量化压缩技术,有重要的实际应用价值和学术价值,也是本文的研究重点。
在将现有的神经网络量化压缩技术应用至目标检测模型后,我们发现量化后的目标检测模型准确度显著降低,且量化训练难以收敛。通过观察目标检测模型在量化训练中模型参数、激活和各正则化层统计值的分布变化,本文指出目标检测模型参数通道间分布差异较大、量化后模型激活存在较多离群点、BN 等正则化层在量化训练中统计值不稳定是导致目标检测模型量化训练难以收敛的主要原因。根据上述观察,本文对目标检测模型的参数、激活量化函数进行相应改进,并调整了 BN 等正则化层的训练方法,成功地在可接受的检测准确度损失范围额内(4-bit ResNet-18 RetinaNet 检测模型~\citep{He_2016, lin2017focal} 在 MS COCO 数据集~\citep{lin2014microsoft} 上仅下降 0.031 mAP),将 RetinaNet、Faster RCNN~\citep{ren2015faster} 等目标检测模型的参数及激活量化压缩至 4-bit 整数。这一用于目标检测模型的量化压缩技术被称为 Fully Quantized Networks for Object Detection (下文简称 FQN,详见第~\ref{chap::fqn} 章)。
本文进一步指出量化目标检测模型出现上述训练、部署困难的原因之一在于模型主干网络(backbone network)及训练算法在设计时并未考虑量化部署场景,使得模型参数及激活量化误差累积而导致模型量化输出偏离原浮点输出。由于主干网络一般使用通用神经网络模型且与目标检测算法正交,故除针对量化目标检测算法的直接改进外,本文还研究了训练量化友好的通用神经网络模型的方法。
现有的神经网络量化工作大多使用“预训练——量化感知训练/微调”的流程~\citep{jacob2018quantization, krishnamoorthi2018quantizing, jung2019learning, li2019additive},即先按照一般神经网络的训练策略在目标数据集上训练得到高准确度的全精度神经网络模型,之后再采用量化感知训练等方法尽量恢复模型在量化部署后的准确度。这样的流程会导致两个主要问题:首先,此类方法为保证模型量化准确度,通常会增加量化感知训练/微调阶段的训练轮数,最终使得量化模型的累计训练开销远高于一般模型;其次是在实际场景中,模型部署阶段不一定能接触到预训练时的所有数据,导致很多方法只能在使用少量训练数据~\citep{he2018learning} 或完全没有训练数据~\citep{nagel2019data, meller2019same} 的情况下恢复量化模型准确度,使得量化模型的最终部署准确度并不理想。如果模型本身在预训练阶段就考虑对于量化部署的友好性,即其参数及激活被量化后仍能保持足够的准确度而不再需要量化感知训练/微调,那么上述问题自然就被解决。
在此思路启发下,本文通过对神经网络模型的量化误差整体建模,并提出反向蒸馏训练策略在预训练阶段消除此误差,最终在与原浮点模型相同的训练轮数下得到了量化友好模型。在 ImageNet 数据集~\citep{ILSVRC15} 上,使用此方法训练的 4-bit ResNet-18 模型能达到 $67.32\%$ Top-1 准确度,仅比全精度预训练模型准确度下降 $2.57\%$。更重要的是,本文提出的方法无需修改原模型预训练阶段的计算图,且对所用量化函数没有特殊要求,因此具有良好的通用性。这一在预训练阶段引入量化误差从而得到量化友好的神经网络的方法被称为 Guided Quantization Networks (下文简称 GQ-Nets,详见第~\ref{chap::gq_nets} 章)。
% ==============================================================================
% Motivations
% ==============================================================================
% \section{研究动机}
% TODO
% ==============================================================================
% Contributions
% ==============================================================================
\section{主要贡献}
\begin{enumerate}
\item 本文提出了一种适用于目标检测模型的量化压缩算法 FQN。FQN 可在接近原模型准确度的情况下将模型参数和激活端到端量化至 4-bit 整数,且不包含任何浮点操作,使得模型在部署时仅需整数数值逻辑即可完成推理。FQN 在 4-bit 下目标检测准确度相对损失较领域内其他方法低 $3.84\times$(第~\ref{chap::fqn} 章);
\item 本文提出了一种在预训练阶段减少模型量化误差,从而得到量化部署友好的神经网络模型的通用算法框架 GQ-Nets。GQ-Nets 能够将通用模型参数及激活量化至 5-bit $\sim$ 2-bit 整数,且无需额外的量化感知训练/微调环节。在完全量化和非完全量化场景下,GQ-Nets 物体分类准确度达到或超过领域内其他方法(第~\ref{chap::gq_nets} 章);
\item 本文在 PyTorch~\citep{paszke2019pytorch} 基础上开发了一套用于训练、测试量化神经网络的软件包 \verb|QuantPack|。\verb|QuantPack| 支持不同量化模式和数值精度,可自动完成全精度模型至量化模型的转换和训练,且易于修改和拓展(附录~\ref{chap::quant_pack} ,同时在 GitHub 开源:\url{https://github.com/lirundong/quant-pack})。
\end{enumerate}
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% Background
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\chapter{背景} \label{chap::background}
本章首先简要介绍深度学习和深度神经网络的基本原理,以及基于深度学习的现代目标检测算法。之后介绍现代深度学习普遍面临的存储、运算开销问题,以及随之兴起的高效深度学习的进展。最后介绍本文重点关注的神经网络量化压缩加速技术近年来在算法、软件及硬件方面的发展,面临的主要挑战,以及与后续章节讨论内容相关的其他工作。
深度学习是机器学习的子集,深度学习使用神经网络学习并解决一系列机器学习问题~\citep{lecun2015deep}。神经网络由一系列\emph{神经元}及神经元之间的\emph{连接}构成。\emph{神经元}是神经网络的基本感知单元,神经元根据其在神经网络拓扑中的位置被划归至不同\emph{层}。第一层神经元被称为网络输入,最后一层神经元被称为网络输出。每一神经元有各自的数值表示,其数值大小表示该感知单元对网络输入的响应强度。网络输入之后的神经网络每一层内,神经元与前一层部分或全部神经元相\emph{连接},且同一层内的神经元互不连接。每一连接有表示其连接强度的数值大小,同一神经网络内表示所有连接强度的数值组成的集合称为该模型的\emph{参数}。一般认为层数超过 8 层的神经网络为“深度”神经网络~\citep{krizhevsky2012imagenet}。
深度神经网络通过\emph{前向传播}和\emph{反向传播}在目标任务上进行推理和梯度计算,使用\emph{随机梯度下降}等算法对模型参数进行更新。以常见的有监督机器学习任务为例:在某一完整标注的数据集 $\mathcal{D} = \{x_i, y_i\}_{i=1\ldots N}$ 上,欲训练一包含参数 $\mathcal{W} = \{w_1, \ldots w_L\}$ 的 $L$ 层神经网络 $\FpNet$。首先需要以一定方法对模型参数 $\mathcal{W}$ 进行\emph{初始化},得到模型每一层在训练步数 $t=0$ 时的参数 $\{w_1^{t=0}, \ldots w_L^{t=0}\}$。随后采样一批量大小为 $B$ 的小批量数据 $\{x_j, y_j\}_{j=1\ldots B} \in \mathcal{D}$,按照一定流程 $p(\cdot)$ 将 $[x_{1, \ldots B}]$ 做预处理后,作为网络输入送入模型 $\FpNet$ 中,表示为 $a_0 = p(x_{1, \ldots B})$。之后从模型第 $l=1$ 层开始,根据当前层的参数 $w_l^t$ 计算层内各神经元的响应值 $\tilde{a}_{l, k}, k = 1, \ldots K_l$,其中 $K_l$ 表示当前层神经元数目。$\tilde{a}_{l, k}$ 被计算为与该神经元相连接的上一层神经元的响应数值与连接强度的乘积加和——以全连接网络为例,$\tilde{a}_l = w_l^t a_{l-1}$。每一神经元在实际更新其激活值前,还要先经过特定非线性函数 $g(\cdot)$,以增加网络的表达能力——即每一神经元的实际激活值被计算为 $a_{l, k} = g(\tilde{a}_{l, k})$。根据此过程从网络第 $1$ 层计算至网络第 $L$ 层,得到模型的最终输出 $a_L = \FpNet(a_0)$。上述过程即为模型的前向传播,又称为模型的\emph{推理}。
神经网络的输出 $a_L$ 在不同任务中,以不同方式被解释。例如在分类任务中,$a_L \in \mathbb{R}^{B \times C}$ 中的元素 $a_{L, b, c}$ 表示小批量中第 $b$ 个样本属于第 $c$ 类物体的概率;在回归任务中,$a_L \in \mathbb{R}^{B \times T}$ 中的元素 $a_{L, b, t}$ 表示第 $b$ 个样本在第 $t$ 个回归任务上的输出值。\footnote{注意此处 $a_{L, b, t}$ 的下标 $t$ (指代模型\emph{任务 task})与参数 $w_l^t$ 的上标 $t$ (指代训练的\emph{步数 time stamp})不一致,请读者根据上下文区分。}在模型训练过程中,前向传播过程结束后,需要根据学习任务定义的损失函数 $\mathcal{L}$ 和当前小批量输入的标注 $[y_{1, \ldots B}]$ 计算模型在 $t=0$ 步的\emph{损失}值 $\mathcal{L}(a_L, y_{1, \ldots B})$,并根据\emph{链式法则}计算模型参数的梯度 $\{\mathrm{d}w_1, \ldots \mathrm{d}w_L\}$。同样以全连接网络为例,在模型第 $l$ 层神经元对应的梯度 $\mathrm{d} a_l$ 计算就绪后,该层连接参数的梯度被计算为 $\mathrm{d} w_l = \mathrm{d} a_l \diff{g(\tilde{a}_l)}{\tilde{a}_l} a_{l-1}$。从网络第 $L$ 层开始,从后向前通过链式法则计算梯度 $\mathrm{d}w_L, \ldots \mathrm{d}w_1$ 至网络第 $1$ 层的过程即被称为模型的反向传播。
在模型反向传播完成后,则通过梯度下降等方法,从参数梯度的相反方向更新模型参数。也就是说,神经网络的训练一般使用一阶方法。模型参数更新的实际幅度与参数梯度成正比,梯度幅度与实际更新步长间的比值称为\emph{学习率}。具体地,在给定学习率 $\alpha$ 后,模型参数基本的梯度下降更新表示为 $w_l^{t+1} := w_l^t - \alpha \mathrm{d} w_l$。参数更新至 $w_{1, \ldots L}^{t+1}$ 之后,继续下一轮迭代。随机采样小批量数据直至训练集 $\mathcal{D}$ 耗尽的过程称为训练 1 \emph{轮},参数较多或数据集较为复杂的任务可能要训练数百轮,最终输出收敛后的模型 $f_{\mathcal{W}^*}$。
深度学习算法非常简明,但正是这些简单参数化操作的非线性组合,在近年来爆发增长的可用数据及计算力加持下,逐渐印证了 \emph{more is different}~\citep{anderson1972more} 的哲学原理——深度学习在计算机视觉、自然语言处理、推荐系统等方面取得了显著成功:在计算机视觉领域,深度学习被应用于语义分割~\citep{yuan2019object}、物体分类~\citep{xie2019self}、物体检测~\citep{liu2019cbnet}、图像生成~\citep{song2019generative}、姿态检测~\citep{bulat2020toward} 等任务;在自然语言处理领域,深度学习被应用于机器翻译~\citep{edunov2018understanding}、语言模型~\citep{shoeybi2019megatron}、提问——回答~\citep{zhang2020retrospective}、语义分析~\citep{raffel2019exploring}、文本生成~\citep{guo2018long} 等任务;在其他传统和新兴领域,深度学习还被应用于医学图像分割~\citep{ronneberger2015u}、药物研发~\citep{alperstein2019all}、强化学习~\citep{mnih2015human}、迁移学习~\citep{wang2019easy}、推荐系统~\citep{rendle2019difficulty}、点击率预测~\citep{deng2020sparse} 等任务。
% ==============================================================================
% Object Detection in Deep Learning Era
% ==============================================================================
\section{基于深度学习的目标检测}
目标检测是计算机视觉中最基本且重要的任务之一。给定一张输入图片,目标检测算法需要给出图片中目标物体边界框(bounding box)的精确坐标,并给出每一边界框对应的目标类别。因此,目标检测算法需要同时完成针对输入图片的回归和分类任务。在深度学习被应用到计算机视觉任务之前,目标检测算法一般依赖领域专家手工设计的图像特征提取算子,以及滑动窗口、多尺度级联、目标结构化拆分等准确度改进手段。这一阶段的代表性工作包括 Viola Jones 检测算法~\citep{viola2001rapid, viola2004robust}、HOG 检测算法(Histogram of Oriented Gradients, \citet{dalal2005histograms})、DPM 检测算法(Deformable Part-based Model, \citet{felzenszwalb2008discriminatively, felzenszwalb2009object, girshick2011object, girshick2012rigid})等。
由于深度神经网络——特别是深度卷积神经网络——在适当的模型结构及损失函数设计下,能够有效地提取图像的空间、语意特征,并能够有效学习分类、回归等任务,因此近年来被广泛运用于目标检测任务中。下文称基于深度学习的目标检测算法为\emph{现代目标检测算法}。现代目标检测算法肇始于 RCNN~\citep{girshick2015region},之后逐渐发展分化为\emph{二阶段检测算法(two-stage detectors)}和\emph{一阶段检测算法(one-stage detectors)}。
% ------------------------------------------------------------------------------
% Two-stage detectors
% ------------------------------------------------------------------------------
\subsection{二阶段检测算法}
二阶段检测算法的核心思路是:将目标检测拆分为两部分,算法第一阶段算法先提出一定数目的候选边界框,通过一定方法过滤明显错误的候选框后,算法第二阶段再对保留的候选框做细粒度修正和分类,最终达到输出准确度。算法第一阶段一般称为 proposal,第二阶段一般称为 refinement,其遵循的是“由粗到细”(from coarse to fine)的设计思想。本节介绍近年来有代表性的二阶检测算法。
\begin{figure}[htb]
\centering
\includegraphics[width=0.8\columnwidth]{img/Background/RCNN.pdf}
\caption{RCNN 的算法架构,图片来自~\citet{girshick2015region}}
\label{img::background::RCNN}
\end{figure}
RCNN (Regions with CNN features, \citet{girshick2015region})是最先使用深度卷积网络的现代目标检测算法。其架构如图~\ref{img::background::RCNN} 所示,首先在输入图片上使用 selective search~\citep{van2011segmentation} 选取一定数目的候选检测框(region of interests,下文简称 RoI)并裁剪得到子图,随后使用深度卷积网络在缩放至特定尺寸的子图上提取图片特征,最后使用 SVM 在图片特征上对候选框内容分类,以及后续的检测框坐标回归等任务。RCNN 算法在 Pascal VOC07 目标检测挑战~\citep{Everingham10} 上达到了 $58.5\%$ 平均准确度(mean average precision,下文简称 mAP),但其选取候选框的流程较为耗时,且在每一候选区域内分别提取特征的做法造成了大量重复冗余,因此 RCNN 算法的运行速度较慢(单张图片检测时长约 14 秒)。
\begin{figure}[htb]
\centering
\includegraphics[width=0.6\columnwidth]{img/Background/spm.pdf}
\caption{SPPNet 的算法架构,图片来自~\citet{he2015spatial}}
\label{img::background::SPPNet}
\end{figure}
针对 RCNN 存在的特征提取冗余问题,\citet{he2015spatial} 提出了针对图片的空间金字塔采样操作(spatial pyramid pooling layer),可以在不同尺寸的输入图片或子图上生成等长的特征表示(图~\ref{img::background::SPPNet})。借助于 SPP 算子,每张图片可以在检测模型训练前一次性完成特征采样,之后检测子区域的特征可从该等长全局特征上生成,从而避免了 RCNN 中重复提取图片特征的缺点。SPPNet 在 Pascal VOC07 上达到了 $59.2\%$ mAP,然而其主要问题是不能在均一的训练流程内同时训练 SPP 层和用于检测输出的全连接层,导致了可能的模型表达能力受限。
\begin{figure}[htb]
\centering
\includegraphics[width=0.7\columnwidth, trim=0 20em 18em 0, clip]{img/Background/fast_RCNN.pdf}
\caption{Fast RCNN 的算法架构,图片来自~\citet{girshick2015fast}}
\label{img::background::fast_RCNN}
\end{figure}
Fast RCNN~\citep{girshick2015fast} 使用深度全卷积网络在输入图片上直接提取全图特征,随后在各 RoI 对应的特征区域使用 RoI pooling 操作提取等长的 RoI 特征(图~\ref{img::background::fast_RCNN})。由于 RoI pooling 完全可导,加之 Fast RCNN 使用 Multi-task loss 将各任务子网络的训练规整至同一训练框架下,解决了 RCNN 和 SPPNet 算法各阶段参数需要分离训练的问题。Fast RCNN 在 Pascal VOC07 上达到了 $70.0\%$ mAP,但其运行速度仍然受限于 RoI 生成算法。
\begin{figure}[htb]
\centering
\begin{subfigure}[t]{0.35\columnwidth}
\centering
\includegraphics[width=\columnwidth]{img/Background/faster_RCNN.pdf}
\caption{Faster RCNN 的算法架构}
\label{img::background::faster_rcnn_arch}
\end{subfigure}
\quad
\begin{subfigure}[t]{0.6\columnwidth}
\centering
\includegraphics[width=\columnwidth, trim=0 0 13em 0, clip]{img/Background/rpn.pdf}
\caption{RPN 模型结构及预定义 anchor boxes}
\label{img::background::faster_rcnn_rpn}
\end{subfigure}
\caption{Faster RCNN 的算法架构~\subref{img::background::faster_rcnn_arch}及 RPN~\subref{img::background::faster_rcnn_rpn},图片来自~\citet{ren2015faster}}
\label{img::background::faster_rcnn}
\end{figure}
为加快 RoI 候选生成速率,Faster RCNN~\citep{ren2015faster} 提出了 region proposal network (RPN)直接在主干卷积网络的输出特征上生成候选 RoI (图~\ref{img::background::faster_rcnn_rpn})。具体地,RPN 在卷积特征每一空间位置按照预先定义的一系列不同尺寸和长宽比的锚框(anchor boxes)通过分类和回归子网络,生成一系列包含表示候选框内容为前景目标的\emph{目标性(objectness)}指标的候选 RoI,再将其送入 Faster RCNN 的 RoI pooling 框架中进行后续计算(图~\ref{img::background::faster_rcnn_arch})。由于 RPN 完全可导,使得 Faster RCNN 成为第一个能够完全端到端训练的二阶目标检测算法。Faster RCNN 在 Pascal VOC07 上达到 $73.2\%$ mAP,在 MS COCO~\citep{lin2014microsoft} 上达到 $21.9\%$ mAP。后续工作 RFCN~\citep{dai2016r}、Light-head RCNN~\citep{li2017light} 等在 Faster RCNN 框架内进一步减少了运算开销。
\begin{figure}[htb]
\centering
\includegraphics[width=0.4\columnwidth]{img/Background/FPN.pdf}
\caption{FPN 的算法架构,图片来自~\citet{lin2017feature}}
\label{img::background::FPN}
\end{figure}
Feature pyramid networks~\citep{lin2017feature} 是对二阶检测算法主干网络特征提取的加强(图~\ref{img::background::FPN})。一般认为深度卷积网络深层特征空间信息不足而语意信息丰富,浅层特征空间信息精确而语意信息缺乏。FPN 从主干网络不同深度提取特征,并通过上采样操作将深层特征放大叠加至浅层特征中,从而得到同时包含精确空间信息和丰富语意信息的图片特征。FPN 在 MS COCO 上达到了 $36.2\%$ mAP。
% ------------------------------------------------------------------------------
% One-stage detectors
% ------------------------------------------------------------------------------
\subsection{一阶段检测算法}
二阶段检测算法能带来较高的检测精度,且第一阶段的后处理可以在二阶段检测子模型中避免简单负样本过多导致难样本产生的梯度被噪声掩盖的问题。然而二阶段检测算法所需的计算量较大,会影响模型运行的实时性,因此注重模型端到端运行速度的一阶段检测算法应运而生。一阶段检测算法使用同一网络完成候选框分类、回归任务,直接输出最终结果。本节介绍近年来有代表性的一阶段检测算法。
\begin{figure}[htb]
\centering
\includegraphics[width=0.4\columnwidth]{img/Background/YOLO_bbox.pdf}
\caption{YOLOv2 所用的边界框回归算法,图片来自~\citet{redmon2017yolo9000}}
\label{img::background::yolo_bbox}
\end{figure}
YOLO~\citep{redmon2016you} 是第一个使用深度卷积网络的一阶目标检测算法。YOLO 是 you only look once 的缩写,即该算法仅使用单一网络对输入图片进行区域划分,并计算每一区域上检测框的位置和类别(图~\ref{img::background::yolo_bbox}),从而在保证 Pascal VOC07 上 $52.7\%$ mAP 的同时达到了 155 FPS 的运行效率。后续工作~\citet{redmon2017yolo9000, redmon2018yolov3} 进一步改进了 YOLO 的检测准确度和运行效率。
\begin{figure}[htb]
\centering
\includegraphics[width=0.8\columnwidth]{img/Background/ssd.pdf}
\caption{SSD 的算法架构,图片来自~\citet{liu2016ssd}}
\label{img::background::ssd}
\end{figure}
SSD~\citep{liu2016ssd} 是 Single Shot MultiBox Detector 的缩写。SSD 在主干网络不同深度提取不同尺寸的图片特征,并在特征每一位置分别计算与不同尺寸及长宽比的预定义锚框间的回归误差及分类置信度(图~\ref{img::background::ssd})。由于使用了多尺度特征,其检测准确度相较 YOLO 获得了显著提升。在运行速率达到 59 FPS 同时,能够在 Pascal VOC07 上达到 $76.8\%$ mAP。
\begin{figure}[htb]
\centering
\begin{subfigure}[t]{0.65\columnwidth}
\includegraphics[width=\columnwidth]{img/Background/retinanet.pdf}
\caption{RetinaNet 模型架构}
\label{img::background::retina_net}
\end{subfigure}
\quad
\begin{subfigure}[t]{0.3\columnwidth}
\includegraphics[width=\columnwidth]{img/Background/focal_loss.pdf}
\caption{RetinaNet 所用的 Focal loss}
\label{img::background::focal_loss}
\end{subfigure}
\caption{RetinaNet~\subref{img::background::retina_net} 及其使用的分类损失函数 Focal loss~\subref{img::background::focal_loss},图片来自~\citet{lin2017focal}}
\label{img::background::retinanet_focalloss}
\end{figure}
\citet{lin2017focal} 指出一阶段检测器准确度较二阶段检测器低的关键原因是训练过程中存在过多简单负样本,导致参数梯度被大量简单样本产生的噪声掩盖,而二阶段检测器由于 RPN 之后会通过非极大抑制(non-maximum suppression,下文简称 NMS)滤掉大量低置信度样本而不存在此问题。因此 \citet{lin2017focal} 通过减小分类交叉熵损失中简单样本的权重以避免生成过多梯度噪声,这种改进的损失函数即为 focal loss (图~\ref{img::background::focal_loss})。在此基础上训练的 RetinaNet (图~\ref{img::background::retina_net})是目前准确度最高的一阶段检测器之一,在 MS COCO 上达到了 $39.1\%$ mAP。
% ==============================================================================
% Efficient Deep Learning
% ==============================================================================
\section{高效深度学习}
Batch normalization~\citep{ioffe2015batch}、残差连接~\citep{He_2016}、大批量分布式训练~\citep{goyal2017accurate} 等技术的出现,使得我们能够在大量数据上训练深度超过 1000 层的超大型模型~\citep{He_2016}。数据量和模型容量的提升显著改进了深度学习的准确度,但也导致了其训练和部署过程开销愈发巨大。以使用 ResNet-101 主干网络且包含 FPN 的 Faster RCNN 目标检测模型为例:在 16 块 GPU 上进行分布式训练时,每次基于 all-reduce 的同步需要在集群内传输 14.52GB 梯度信息;在模型部署时需占用 60.52MB 内存,在常用的尺寸为 $1280 \times 800$ 像素的输入下,执行一次前向推理的运算量达到了 283.14G FLOPS。为降低深度学习模型的部署和训练开销,高效深度学习近年来成为了工业界和学术界的研究热点之一。本节从深度学习模型的高效结构设计、高效训练方法和高效部署方法三个维度介绍该领域的进展。
% ------------------------------------------------------------------------------
% Efficient architectures
% ------------------------------------------------------------------------------
\subsection{高效模型结构设计}
设计参数量和运行计算量都较少的轻量级网络模型对深度学习的训练、部署过程都有帮助:在训练过程中,较少的参数量使得分布式训练所需同步的梯度量等比例减小;在部署过程中,较小的参数量可减少运行时设备访存和缓存上下文交换,较少的运行计算量可提高模型实时性。更重要的是,轻量级网络的部署并不对部署平台的存储、运算单元有特殊需求,可部署至任意支持神经网络运行的平台上。本节介绍近年来有代表性的轻量级网络模型。
\begin{figure}[htb]
\centering
\includegraphics[width=0.5\columnwidth]{img/Background/fire_module.pdf}
\caption{SqueezeNet 所用的 Fire module 模块,图片来自~\citet{iandola2016squeezenet}}
\label{img::background::fire_module}
\end{figure}
SqueezeNet~\citep{iandola2016squeezenet} 是第一个在 ImageNet~\citep{krizhevsky2012imagenet} 这一大规模分类任务上达到 AlexNet~\citep{krizhevsky2012imagenet} 级别准确度的轻量模型。SqueezeNet 主要使用图~\ref{img::background::fire_module} 所示的 Fire module 减小模型参数及运算量:Fire module 首先通过 $1\times 1$ 卷积减少特征通道数,之后通过混合的 $1\times 1$、$3\times 3$ 卷积提取并扩充特征。SqueezeNet 将模型参数量从 AlexNet 的 240MB 减少至 4.8MB,同时在 ImageNet 上达到了 $57.5\%$ 的 Top-1准确度。
\begin{figure}[htb]
\centering
\begin{subfigure}[t]{0.4\columnwidth}
\centering
\includegraphics[width=\columnwidth]{img/Background/separable_conv.pdf}
\caption{通道分离卷积}
\label{img::background::separable_conv}
\end{subfigure}
\quad
\begin{subfigure}[t]{0.5\columnwidth}
\centering
\includegraphics[width=\columnwidth]{img/Background/expansion_conv.pdf}
\caption{通道扩展分离卷积}
\label{img::background::expansion_conv}
\end{subfigure}
\caption{MobileNet 所用的通道分离卷积~\subref{img::background::separable_conv} 和 MobileNet-v2 所用的通道扩展分离卷积~\subref{img::background::expansion_conv},图片来自~\citet{Sandler_2018}}
\label{img::background::mobile_nets}
\end{figure}
MobileNet~\citep{howard2017mobilenets} 是针对移动平台部署环境设计的轻量化网络。MobileNet 使用通道分离卷积(depth-wise separable convolution),不同于采样所有输入通道的常规 2D 卷积核,通道分离卷积每一卷积核仅采样输入的一个通道,且各卷积核对输入通道的采样不重叠,从而使模型卷积层参数数量和计算量都减少了 $C_{\mathrm{in}}$ 数量级(图~\ref{img::background::separable_conv})。MobileNet 参数量减少至 4.2MB,在 ImageNet 上 Top-1 准确度为 $70.6\%$。后续工作 MobileNet-v2~\citep{Sandler_2018} 使用反向 bottleneck 结构(图~\ref{img::background::expansion_conv}),在 $3\times 3$ 通道分离卷积前使用 $1\times 1$ 卷积扩展特征通道数以增强模型表现力,参数量为 3.4MB 情况下在 ImageNet 上达到 $72.0\%$ 准确度。MobileNet-v3~\citep{howard2019searching} 使用模型自动搜索技术~\citep{zoph2018learning} 进一步改善了模型的准确度/运算开销,标准通道数的 MobileNet-v3 参数量进一步减少至 2.5MB,在 ImageNet 上达到 $67.4\%$ 的 Top-1 准确度。
\begin{figure}[htb]
\centering
\begin{subfigure}[t]{0.45\columnwidth}
\centering
\includegraphics[width=\columnwidth]{img/Background/channelshuffle.pdf}
\caption{通道混合操作}
\label{img::background::channel_shuffle}
\end{subfigure}
\quad
\begin{subfigure}[t]{0.45\columnwidth}
\centering
\includegraphics[width=\columnwidth]{img/Background/shufflenet_unit.pdf}
\caption{ShuffleNet 组成单元}
\label{img::background::shufflenet_unit}
\end{subfigure}
\caption{ShuffleNet 所用的通道混合操作~\subref{img::background::channel_shuffle} 和基本组成单元~\subref{img::background::shufflenet_unit},图片来自~\citet{zhang2018shufflenet}}
\label{img::background::shuffle_net}
\end{figure}
ShuffleNet~\citep{zhang2018shufflenet} 使用分组卷积减少模型参数和计算量,并通过组间通道混合保持模型的表达能力。如图~\ref{img::background::channel_shuffle} 所示,ShuffleNet 将模型特征分为多组,计算量较大的 $3\times 3$ 卷积仅在同组通道内进行;同时在 $1 \times 1$ 卷积之后设置通道混合操作在各组间传递特征信息(图~\ref{img::background::shufflenet_unit}),以保证模型的表达能力。标准通道数的 ShuffleNet 针对 $224\times 224$ 尺寸输入的推理运算开销为 140M FLOPS,在 ImageNet 上 Top-1 准确度为 $67.6\%$。
\begin{figure}[htb]
\centering
\begin{subfigure}[t]{0.35\columnwidth}
\centering
\includegraphics[width=\columnwidth]{img/Background/MnasNet_overallflow.pdf}
\caption{MnasNet 平台相关模型搜索流程}
\label{img::background::mnasnet_overall_flow}
\end{subfigure}
\quad
\begin{subfigure}[t]{0.6\columnwidth}
\centering
\includegraphics[width=\columnwidth]{img/Background/MnasNet_searchspace.pdf}
\caption{MnasNet 搜索空间}
\label{img::background::mnasnet_search_space}
\end{subfigure}
\caption{MnasNet 以部署平台实际推理耗时作为搜索反馈~\subref{img::background::mnasnet_overall_flow},并使用了层次化搜索空间~\subref{img::background::mnasnet_search_space}。图片来自~\citet{tan2019mnasnet}}
\label{img::background::mnasnet}
\end{figure}
近两年来模型自动化搜索技术~\citep{zoph2018learning, liu2018darts, lu2019nsga} 在许多场景上超过了先前手工设计的模型,因此也被应用到了轻量化模型设计上。MnasNet~\citep{tan2019mnasnet} 以强化学习搜索方式为基础,将模型在目标平台上实际推理耗时作为搜索反馈的一部分(图~\ref{img::background::mnasnet_overall_flow}),并设计了部署至低算力设备的层次化搜索空间(图~\ref{img::background::mnasnet_search_space})。在 Pixel 1 手机上,使用 CPU 运行的 MnasNet 能够以 78ms 的单样本实际推理耗时在 ImageNet 上达到 $75.2\%$ Top-1 准确度。
\begin{figure}[htb]
\centering
\includegraphics[width=0.7\columnwidth]{img/Background/fbnet_flow.pdf}
\caption{FBNet 的搜索算法架构,图片来自~\citet{wu2019fbnet}}
\label{img::background::fbnet}
\end{figure}
FBNet~\citep{wu2019fbnet} 是基于随机超网络和可微分搜索的另一个注重部署平台推理性能的轻量化模型搜索工作。如图~\ref{img::background::fbnet} 所示,FBNet 将包含所有候选操作的搜索空间组成一个超网络,并在其上做随机参数化采样,采样的概率参数通过 Gumbel Softmax~\citep{jang2016categorical, maddison2016concrete} 在搜索训练过程中可导。同时在搜索前对所有候选操作在部署平台上测速,并通过查找表将被采样结构的推理延迟加入到搜索过程损失函数中。部署至 Samsung Galaxy S8 手机后,以 CPU 运行的 FBNet 能够以 19.8ms 的单样本实际推理耗时在 ImageNet 上达到 $73.0\%$ Top-1 准确度。
\begin{figure}[htb]
\centering
\includegraphics[width=0.75\columnwidth]{img/Background/scalecompare.pdf}
\caption{EfficientNet 在搜索时对候选模型通道数、深度、特征图分辨率做同一缩放,图片来自~\citet{tan2019efficientnet}}
\label{img::background::efficient_net}
\end{figure}
EfficientNet~\citep{tan2019efficientnet} 是目前轻量化模型中在准确度/运行开销间权衡最为出色的工作之一。EfficientNet 同样基于强化学习搜索算法~\citep{zoph2018learning},但引入了一个关键发现——高准确度模型在其通道数、深度、特征图分辨率统一向上或向下缩放后,相较分离缩放搜索的模型更容易保持较高准确度——从而极大地减少了搜索空间。EfficientNet-B0 模型能在 5.3MB 参数量、0.39G FLOPS 推理计算量下,在 ImageNet 上达到 $76.3\%$ Top-1 准确度。
% ------------------------------------------------------------------------------
% Efficient training
% ------------------------------------------------------------------------------
\subsection{高效模型训练方法}
除设计搜索轻量模型外,还有大量正交于模型结构的高效训练方法。深度神经网络的模型训练相较于模型推理,其额外的开销在于梯度的反向传播计算,以及分布式训练场景下各节点间梯度同步。本节分别介绍近年来针对训练过程中对于梯度反传和梯度同步的代表性加速方法。
\begin{figure}[htb]
\centering
\begin{subfigure}[t]{0.45\columnwidth}
\centering
\includegraphics[width=\columnwidth]{img/Background/mixed_prec_iteration.png}
\caption{FP16 训练流程}
\label{img::background::fp16_ops}
\end{subfigure}
\quad
\begin{subfigure}[t]{0.45\columnwidth}
\centering
\includegraphics[width=\columnwidth]{img/Background/ssd_ag_log_histo_coarse.png}
\caption{梯度分布与 FP16 数值范围}
\label{img::background::fp16_grads}
\end{subfigure}
\caption{模型训练时使用 FP16 精度进行前向反向计算,并将梯度缩放后更新底层的 FP32 精度模型参数~\subref{img::background::fp16_ops}。FP16 数值精度有限,需在反传开始前缩放 loss 值以确保梯度计算不会出现数值截断~\subref{img::background::fp16_grads}。图片来自~\citet{micikevicius2018mixed}}
\label{img::background::fp16_training}
\end{figure}
深度神经网络一般使用单精度浮点存储模型参数和进行数值计算,\citet{micikevicius2018mixed} 指出使用半精度浮点(FP16)也可在不影响模型准确度的前提下将大部分用于不同任务的深度神经网络训练至收敛。FP16 训练流程如图~\ref{img::background::fp16_ops} 所示,在前向传播过程中,模型参数和输入激活被截断转换至 FP16,之后通过 FP16 数值逻辑计算得出输出激活;在反向传播过程中,以 FP16 表示的梯度与以 FP16 缓存的前向过程临时变量通过 FP16 数值逻辑计算得出模型参数和输入激活的梯度,并继续以链式法则进行反向传播。模型参数梯度就绪后,转换至 FP32 格式对实际保存的 FP32 模型参数进行更新。注意如图~\ref{img::background::fp16_grads} 所示,由于 FP16 数值范围有限,幅度值较小的梯度在计算时可能会下溢为 0,因此需要在反向传播开始前适当缩放损失函数值 $\mathcal{L}$,使反向传播中所有梯度保持在 FP16 数值范围内;在将梯度转换至 FP32 时,再将梯度范围缩放至原有数值。
在大部分现代 GPU 及其他包含浮点计算单元的硬件上,同一设备的 FP16 算力一般是 FP32 算力的一倍以上。例如 NVIDIA RTX 2080Ti GPU 的 FP32 算力为 13.45T FLOPS,而其 FP16 算力高达 26.90T FLOPS \citep{nvidia2018turing}。除~\citet{micikevicius2018mixed} 外,\citet{abadi2016tensorflow, dean2012large} 也报告了使用 FP16 或 BFLOAT16 数值精度进行深度神经网络训练的结果。在实际应用中,FP16 一般能将模型训练时间缩短一倍左右。
\begin{figure}[htb]
\centering
\includegraphics[width=0.75\columnwidth]{img/Background/int8_training.pdf}
\caption{INT8 训练对前向过程和反向过程的修改,图片来自~\citet{zhu2019towards}}
\label{img::background::int8_training}
\end{figure}
另一个更激进的方法是将网络前向、后向传播中的参数、激活量化至带缩放因子的整数张量,从而将模型训练中计算量的大部分替换为整数数值逻辑(图~\ref{img::background::int8_training})。例如,\citet{das2018mixed} 报告了使用 INT16 数值精度训练深度卷积网络,可在不损失模型准确度的情况下获得 $1.8\times$ 训练吞吐量提升;\citet{zhu2019towards} 通过调整量化函数截断阈值和修改模型训练策略,可以在 INT8 数值精度下将 MobileNet~\citep{howard2017mobilenets, Sandler_2018} 系列模型训练收敛,且在 NVIDIA GTX 1080Ti GPU 上实际达到 $+22\%$ 的训练速度提升。
针对分布式训练中各节点间梯度同步问题,目前主要有两种加速方案。一种是使用梯度稀疏化、梯度量化、梯度信息编码等方式减少节点间的通讯量。例如 \citet{wen2017terngrad} 将节点间梯度三值化为 $\{-1, 0, 1\}$,并在不超过 $2\%$ 准确度损失的情况下将 GoogLeNet~\citep{szegedy2015going} 训练至收敛;\citet{aji2017sparse, lin2018deep} 通过幅度阈值对通讯梯度做稀疏化,\citet{lin2018deep} 报告了将 ResNet-50 训练梯度从 97MB 压缩至 0.35MB 而不损失模型准确度。另一种是利用反向传播逐层计算的特性,在模型计算某一层梯度时,同步以就绪的其他梯度,以实现“隐藏”通信时间的效果。\citet{abadi2016tensorflow, paszke2019pytorch} 利用 CUDA stream 异步执行的特性,将 NCCL~\citep{jeaugey2017nccl} 的通信原语与 cuDNN~\citep{chetlur2014cudnn} 的计算操作按调用顺序传递至训练 GPU 的 CUDA stream 中,从而实现对通信开销的隐藏。\citet{peng2019generic} 通过对神经网络不同层间通信的优先级调度以及根据集群网络环境对通信算法参数的优化,在 Parameter Server~\citep{li2014scaling}、基于 all-reduce 的同步训练等分布式训练范式上均获得了显著加速。
% ------------------------------------------------------------------------------
% Efficient deployment
% ------------------------------------------------------------------------------
\subsection{高效模型部署方法}
神经网络模型在部署时主要面临的挑战仍然是其过高的存储和推理计算开销。为减轻算法模型对计算资源的需求,提高计算资源的利用率,高效模型部署技术的发展主要分为两个方向:从\emph{算法}层面减少部署模型的存储和推理复杂度,从\emph{系统}层面根据部署环境优化模型推理运行时对计算资源的利用率。
\begin{figure}[htb]
\centering
\includegraphics[width=0.75\columnwidth]{img/Background/deep_compression.pdf}
\caption{DeepCompression 部署流程,图片来自~\citet{han2015deep}}
\label{img::background::deep_compression}
\end{figure}
近年来从算法层面提升模型部署运行效率的工作,几乎都可以归类至 \citet{han2015deep, han2017efficient} 提出的 DeepCompression 框架内(图~\ref{img::background::deep_compression})。DeepCompression 对模型部署的优化加速包含三个流程:通过\emph{剪枝}(pruning)技术减少模型参数量,通过\emph{量化}(quantization)技术降低模型参数和激活数值位宽,最后通过其他无损压缩技术进一步减小模型部署后的体积。剪枝技术主要包括:
{
\setlist[enumerate]{}
\begin{enumerate*}[1)]
\item 非结构化剪枝~\citep{han2015learning},即通过一定标准将模型中参数值置为 $0$ 而提高模型稀疏度,在支持稀疏操作的专有硬件上可降低能耗、提高推理效率;
\item 结构化剪枝~\citep{li2016pruning},即删除模型卷积层中的部分卷积核和全连接层中的部分通道,可直接地减小模型的存储和计算复杂度;
\item 层级剪枝~\citep{chen2018shallowing},直接删除网络模型中的部分冗余层。
\end{enumerate*}
}
模型部署时的量化技术主要包括:
{
\setlist[enumerate]{}
\begin{enumerate*}[1)]
\item 将模型参数量化或二值化至低比特表示~\citep{courbariaux2015binaryconnect, hou2018loss},从而减少模型部署后体积;
\item 将模型参数和激活同时量化至低比特~\citep{rastegari2016xnor, jacob2018quantization},从而利用整数数值逻辑加速模型部署后的推理过程。
\end{enumerate*}
}
DeepCompression 流程最后一步使用 Huffman 编码~\citep{van1976construction} 进一步减小模型体积。其他压缩加速算法还包括模型参数的低秩分解~\citep{sainath2013low}、高效矩阵乘法~\citep{lavin2016fast} 等。
\begin{figure}[htb]
\centering
\includegraphics[width=0.75\columnwidth]{img/Background/tvm_stack.pdf}
\caption{TVM 部署系统架构,图片来自~\citet{chen2018tvm}}
\label{img::background::tvm}
\end{figure}
从系统层面提高模型部署效率的代表性工作是 TVM~\citep{chen2018tvm}。在模型训练并压缩完成后,TVM 首先根据算子融合、内存布局重排列策略,在不改变模型输入——输出映射的情况下对模型进行\emph{计算图重写};随后 TVM 将计算图编译为与硬件无关的\emph{张量表达式},并根据部署环境对张量表达式进行并行化、循环展开、访存延时隐藏等优化,得到最优的\emph{调度策略};之后 TVM 根据模型调度策略和张量表达式生成\emph{字节码},并在部署硬件上实际测试字节码性能,并以此为反馈重新调节调度策略和字节码生成流程,最终在目标硬件上实现神经网络模型的高效部署。
% ==============================================================================
% Quantized Neural Networks: Algorithms, Softwares and Hardwares
% ==============================================================================
\section{量化神经网络}
量化神经网络~\citep{guo2018survey} 及其特例二值化神经网络~\citep{qin2020binary} 通过将神经网络模型参数、激活、梯度使用特定方法压缩至低比特定点数、整数,或根据某一查找表进行映射至离散值(例如根据数值符号和阈值映射至 $\{-1, 0, 1\}$ ),达到减少模型参数体积(量化模型参数)、加速模型运算(同时量化模型参数和激活)及减少模型分布式训练通信量(量化模型梯度)的目的。具体地,给定一待量化输入 $x\in \mathbb{R}$,量化函数 $Q(\cdot)$ 将其映射至一离散集合 $\mathbb{T}$ 中的对应值,即 $\hat{x} = Q(x): \mathbb{R} \to \mathbb{T}$;在反向传播阶段,则根据相应的求导原则 $\diff{\hat{x}}{x}$ 将上游梯度 $\diff{\mathcal{L}}{\hat{x}}$ 传递至 $x$ 以继续梯度的链式法则计算。近年来量化神经网络领域大量工作主要集中探讨两个话题:量化函数 $Q(\cdot)$ 的设计方式,以及在给定量化函数后对量化模型 $\QuantNet$ 的优化方法。本节将依次介绍量化函数设计和量化函数优化方面的代表性工作。最后,本节还将介绍用于训练部署量化神经网络的软件和硬件实现。
% ------------------------------------------------------------------------------
% Quantizers
% ------------------------------------------------------------------------------
% ○ Quantizers
% § BinaryConnect
% § BNN
% § XNOR-Net
% § DoReFa
% § HWGQ
% § PACT
% § ABC-Net
% § LQ-Nets
% § APoT
% ○ Training methods
% § QAT
% □ Integer-only
% □ Distillation Quantization / Apprentice
% □ Loss-aware binary/ternary
% □ LR-Nets / Probabilistic BNN
% □ LIQ
% □ DSQ
% § Post-training methods
% □ WhitePaper
% □ Few-data calibration
% □ Data-free / same but different
% § Allocate the bit budget
% □ AutoML methods (HWQ)
% □ Metric-based methods (Hessian aware quant)
\subsection{量化函数设计}
BinaryConnect~\citep{courbariaux2015binaryconnect} 是最早使用量化技术减少模型参数体积的工作。在前向传播时,BinaryConnect 根据模型参数 $w$ 的幅度大小,\emph{随机地}将其映射至 $\{-1, 1\}$;在反向传播过程中,使用 Straight Though Estimator (\citet{bengio2013estimating},下文简称 STE) 将量化函数的上游梯度直接复制至全精度输入。为防止模型参数由于前向过程中幅度信息 $|w|$ 丢失而造成过多偏移,每步参数更新会将参数范围限制在 $[-1, 1]$ 之间。具体地,
\begin{align}
\text{\textbf{Forward}: } & \hat{w} =
\begin{cases}
1 & \text{ with probability } p = \hat{\sigma}(w) \\
-1 & \text{ with probability } 1 - p
\end{cases} \\
\text{\textbf{Backward}: } & \diff{\mathcal{L}}{w} = \diff{\mathcal{L}}{\hat{w}} \label{eq::background::ste}
\end{align}
其中 $\diff{\mathcal{L}}{\hat{w}}$ 为损失函数 $\mathcal{L}$ 传导至 $\hat{w}$ 处的梯度,$\hat{\sigma}(w) = \max(0, \min(\frac{w+1}{2}, 1))$。在使用 $\diff{\mathcal{L}}{w}$ 更新 $w$ 后,再将 $w$ 范围限制在 $[-1, 1]$ 之间。
Binarized Neural Networks (\citet{hubara2016binarized}, 下文简称 BNN) 进一步将模型激活也映射至 $\{-1, 1\}$,以便使用\emph{算术位移}操作完成模型的前向传播。为减轻模型前向传播的计算开销,BNN 使用确定性量化处理模型激活:
\begin{align}
\text{\textbf{Forward}: } & \hat{x} =
\begin{cases}
1 & \text{ if } x \ge 0 \\
-1 & \text{ otherwise}
\end{cases}
\label{eq::background::sign}
\end{align}
同时 BNN 也提出了使用算术位移实现的 Batch normalization~\citep{ioffe2015batch} 和 AdaMax~\citep{kingma2014adam},并报告上述基于位移的实现在 GPU 上可节省 $60\%$ 的模型推理时间。
为进一步提高量化参数 $\hat{w}$ 针对全精度参数 $w$ 的近似准确性,XNOR-Net \citep{rastegari2016xnor} 为量化参数引入了浮点缩放 $\alpha$,并将量化过程视为针对量化后参数和缩放的最小二乘问题:
\begin{align}
\arg\min_{\hat{w}, \alpha} &= \| \alpha\hat{w} - w \|_2 \label{eq::background::xnor_opt}
\end{align}
\eqref{eq::background::xnor_opt} 存在闭式解 $\alpha^* = \frac{\|w\|_1}{n}$,$\hat{w}^* = \sign(w)$,其中 $n$ 为参数张量 $w$ 中所含元素个数,$\sign$ 即为 \eqref{eq::background::sign}。
值得注意的是,在 BNN 和 XNOR-Net 中,量化后的激活 $\hat{x}$ 和参数 $\hat{w}$ 满足 $\hat{x}, \hat{w} \in \{-1, 1\}$,因此它们之间的点积操作可用异或(XNOR)及 1-位计数(bitcount)完成:
\begin{align}
\hat{x} \cdot \hat{w} &= N - 2 \cdot \mathrm{bitcount}(\mathrm{xnor}(\hat{x}, \hat{w})) \label{eq::background::xnor_dot}
\end{align}
其中 $N$ 为向量 $\hat{w}, \hat{x}$ 中所含元素个数。
DoReFa-Net~\citep{zhou2016dorefanet} 引入了 k-bit 量化函数 $Q_k(\cdot)$,使得量化点集 $\mathbb{T}$ 中可用元素数目达到了 $2^k-1$。具体地,给定一全精度输入 $x\in [0, 1]$,k-bit 量化函数定义为:
\begin{align}
\text{\textbf{Forward}: } & \hat{x} = \frac{\lfloor (2^k - 1)x \rceil}{2^k - 1} \label{eq::background::dorefa_fwd} \\
\text{\textbf{Backward}: } & \diff{\mathcal{L}}{x} = \diff{\mathcal{L}}{\hat{x}}
\end{align}
其中 $\Round{\cdot}$ 为舍入操作符。对于模型参数 $w$,DoReFa-Net 使用 $\tanh$ 函数将其映射至 $[-1, 1]$,再线性映射至 $Q_k(\cdot)$ 的定义域内;对于经过非线性层后的模型激活 $x$,则直接将其截断至 $[0, 1]$;对于梯度 $g$ 的处理方式和 $w$ 类似,但是会在量化前叠加幅度范围在 $\pm \frac{|g|}{2}$ 之内的均匀噪声。
Half Wave Gaussian Quant (\citet{cai2017deep},下文简称 HWGQ)注意到非线性层之后的模型激活 $x$ 通常符合从 0 截断的半波高斯分布,故使用分段式函数定义 $Q(\cdot)$。在给定量化位宽 $k$ 之后,
\begin{align}
\text{\textbf{Forward}: } & \hat{x} =
\begin{cases}
q_i & \text{ if } x \in (t_i, t_{i+1}] \\
0 & \text{ } x \le 0
\end{cases}
\label{eq::background::hwgq}
\end{align}
其中 $\{q_1, \ldots q_{2^k-1}\}$ 为量化点集,$t_0=0, t_1, \ldots, t_{2^k-1}, t_{2^k}=\infty$ 为分段函数的边界。$\{q_i, t_j\}, i, j \in {1, \ldots 2^k-1}$ 的取值通过 Lloyd~\citep{lloyd1982least} 算法求解优化问题
\begin{align}
\arg\min_{q_i, t_j} \|\hat{x} - x\|_2
\end{align}
得出。
PArameterized Clipping acTivation (\citet{choi2018pact} 下文简称 PACT),为减少模型激活量化误差,设计了带可学习上界参数 $\beta$ 的线性截断函数代替 ReLU,并将截断后的激活值线性缩放至 $[0, 1]$ 之后传入 \eqref{eq::background::dorefa_fwd} 中。在模型反向传播过程中,$\beta$ 使用接收到的梯度进行更新。
DoReFa-Net 和 PACT 所用的 k-bit 线性均匀量化函数 \eqref{eq::background::dorefa_fwd} 实际是将量化后的 $\hat{x}$ 表示为其编码向量 $b_x = [b_1, \ldots b_k], b_i \in \{0, 1\}$ 与 2-幂基底 $v^{(2)} = [2^0, 2^1, \ldots 2^{k-1}]$ 和缩放因子 $\alpha$ 的点积,即 $\hat{x} = \alpha v^{(2)} b_x^T$。LQ-Nets~\citep{Zhang_2018} 指出量化函数所用基底可以不一定是 2-幂基底 $v^{(2)}$,而可以在训练过程中学习适合目标网络数值特性的基底 $v = [v_1, \ldots, v_k], v_i \in \mathbb{R}$。由基底 $v$ 同样可以在 k-bit 编码上生成 $2^k$ 个量化点 $[q_1, \ldots, q_{2^k}]$,其中 $q_1 = v [0, \ldots 0]^T, q_{2^k} = v [1, \ldots 1]^T$。具体地,LQ-Nets 所用量化函数 $\hat{x} = Q_{\mathrm{LQ}}(x, v)$ 实现为
\begin{align}
\text{\textbf{Forward}: } & \hat{x} = v b_x^T \label{eq::background::lq_fwd}
\end{align}
其中 $b_x$ 为 $q_i \le x < q_{i+1}$ 时 $i$ 对应的编码向量。使用 \eqref{eq::background::lq_fwd} 对实数向量点积 $wa^T, w, a \in \mathbb{R}^N$ 操作数量化后,点积操作可以用 \eqref{eq::background::xnor_dot} 在 $w, a$ 的编码向量上完成,即
\begin{align}
Q_{\mathrm{LQ}}(w, v^{(w)}) Q_{\mathrm{LQ}}(a, v^{(a)})^T &= \sum_{i=1}^{k_w} \sum_{j=1}^{k_a} v^{(w)}_i v^{(a)}_{j} (b^{(w)}_i b^{(a)}_j)
\end{align}
其中 $k_w, k_a$ 分别为操作数 $w, a$ 的量化位宽,$v^{(w)} \in \mathbb{R}^{k_w}, v^{(a)} \in \mathbb{R}^{k_a}$ 为 $w, a$ 在 LQ-Nets 量化模式中的基底,$b^{(w)}, b^{(a)}$ 间的点积可以由 \eqref{eq::background::xnor_dot} 完成。
\begin{figure}[htb]
\centering
\includegraphics[width=\columnwidth]{img/Background/APoT.pdf}
\caption{在 $[0, 1]$ 范围内,APoT 量化方式(右)与均匀量化(左)和 2-幂量化(中)的对比。图片来自 \citet{li2019additive}}
\label{img::background::apot}
\end{figure}
Additive Power-of-Two (\citet{li2019additive},下文简称 APoT)将量化位宽 $k$ 拆分为 $n$ 个位宽为 $m$ 的 2-幂量化子项,将输入编码为 $n$ 个子项的加和,以避免普通 2-幂量化的量化点过于集中在零点附近的问题。具体地,在给定实数输入 $x\in [0, \alpha)$ 后,其量化函数 $\hat{x} = Q_{\mathrm{APoT}}(x; \alpha, m, n)$ 实现为:
\begin{align}
Q_{\mathrm{APoT}}(x; \alpha, m, n) &= \gamma \times \{ \sum_{i=0}^{n-1} p_i \} \\
\text{where } p_i &\in \{0, \frac{1}{2^i}, \frac{1}{2^{i+n}}, \ldots \frac{1}{2^{i + 2^{m-1}n}}\} \notag
\end{align}
其中 $\gamma$ 为缩放因子,确保 $Q_{\mathrm{APoT}}(x; \alpha, m, n)$ 输出的最大项数值为 $\alpha$,各项位宽 $m$ 和项数 $n$ 满足 $k = mn$。在 $\alpha = 1, m = n = 2$ 时,APoT 量化方式与其他常见量化方式的对比见图~\ref{img::background::apot}。
% ------------------------------------------------------------------------------
% Training methods
% ------------------------------------------------------------------------------
\subsection{量化模型优化方法} \label{sec::background::train_qnn}
一般神经网络模型在量化后会遭受准确度损失,因此需要使用特定方法恢复量化模型的准确度。目前量化模型的优化方法主要分两类:需要在特定数据集上进行前向传播和反向传播计算,使用得到的梯度更新模型参数的\emph{量化感知训练}(\emph{Quantization-aware Training},下文简称 QAT)方法;以及不需要反向传播计算,在使用少量数据或完全没有训练数据情况下,进行模型量化参数标定及其他操作即可完成转换部署的\emph{量化后处理}(\emph{Post-training Quantization},下文简称 PTQ)方法。
\begin{figure}[htb]
\centering
\includegraphics[width=0.75\columnwidth]{img/Background/qat_ptq.png}
\caption{TensorFlow Lite 中模型参数量化(左)、量化后处理方法(中)和量化感知训练方法(右)的算法流程。图片来自~\citet{krishnamoorthi2018quantizing}}
\label{img::background::qat_ptq}
\end{figure}
PTQ 方法包含对模型激活的标定,对模型正则化参数的调整,以及在不使用梯度信息的情况下对模型参数进行微调。由于各类量化函数运行前需获知被量化输入的数值范围,故对神经网络模型参数、激活同时量化时,需要确定模型各层激活数值范围,即对模型激活进行\emph{标定}。TensorFlow Lite 的 PTQ 模块~\citep{abadi2016tensorflow, krishnamoorthi2018quantizing} 在标定数据集上运行待量化的模型,记录模型中每层参数的最大最小值,并通过动量 $M$ 以指数移动平均(Exponential Moving Average)方式更新每层激活的量化范围(图~\ref{img::background::qat_ptq} 中间部分流程)。\citet{he2018learning, peters2018probabilistic} 指出原模型中 BN 等正则化层的统计参数并不能有效地匹配量化模型的激活分布,因此提出在标定数据集上运行量化后的模型时,应根据量化激活的分布情况重新统计并更新模型中的正则化参数。在无法接触到训练数据或标定数据的情况下,\citet{nagel2019data, meller2019same} 通过调整量化模型参数分布,在不改变模型输入——输出映射关系的前提下减少模型量化误差,恢复量化模型准确度。
QAT 方法与一般神经网络训练方法类似,将量化后的模型在训练集上进行前向传播和反向传播计算,并按照特定策略对模型参数进行梯度下降更新(图~\ref{img::background::qat_ptq} 右侧流程)。QAT 方法的主要问题是量化函数对于量化输入并不可导,各类工作针对此问题提供了不同的解决方案:模型量化的早期工作 \citet{courbariaux2015binaryconnect, hubara2016binarized, rastegari2016xnor, zhou2016dorefanet} 使用 STE~\eqref{eq::background::ste} 将量化函数输出接受的梯度直接复制至其输入,以确保链式法则能继续进行。由于量函数的全精度输入与求导时所用的量化输出数值并不一定相同,所以使用 STE 反传梯度会出现梯度不匹配问题,且在量化数值精度较低时更为明显。为解决此问题,\citet{cai2017deep} 探索了 HWGQ 量化函数的可微分导数近似;\citet{louizos2018relaxed} 使用可微分的 Gumbel Softmax~\citep{jang2016categorical, maddison2016concrete} 算子,在全精度模型的训练过程中逐渐将模型参数和激活由连续分布“硬化”至离散分布;\citet{gong2019differentiable} 提出的 Differentiable soft quantization 算子将分段函数的导数使用可微分的类 $\tanh$ 函数近似,并在训练过程中逐渐接近实际分段函数。除改进 STE 的梯度准确度外,其他实现高精度 QAT 的方法包括:\citet{peters2018probabilistic, shayer2018learning} 将神经网络的量化操作视为随机过程,即量化后的参数或激活服从特定的参数化离散分布,在反向传播时即可针对分布参数求导;\citet{hou2016loss, hou2018loss} 利用 Adam 优化算法~\citep{kingma2014adam} 中的二阶动量信息作为 Hessian 近似,使用拟牛顿法直接对模型量化权重的缩放因子 $\alpha_w$ 和量化表示 $b_w$ 求导并优化;\citet{polino2018model, mishra2018apprentice} 使用知识蒸馏技术~\citep{hinton2015distilling} 将高准确度大模型的输出作为“软标签”引入 QAT 过程,以改善量化模型的准确度;\citet{jung2019learning} 使用参数化的量化函数,并在 QAT 阶段将量化函数参数引入模型任务损失计算,以此通过模型反向传播时的梯度优化量化函数。
% ------------------------------------------------------------------------------
% Softwares and hardwares
% ------------------------------------------------------------------------------
\subsection{相关软硬件实现}
现今大量底层数学计算库已支持整数通用矩阵乘法(integer general matrix multiplication,下文简称 IGEMM)以及整数卷积计算(integer convolution,下文简称 ICONV):gemmlowp~\citep{google2018gemmlowp}、qnnpack~\citep{facebook2018qnnpack}、fbgemm~\citep{facebook2018fbgemm}、DNNL~\citep{intel2019dnnl} 支持 INT8 数值精度的 IGEMM 及 ICONV 操作,cuBLAS~\citep{nvidia2008cublas}、CUTLAS~\citep{nvidia2019cutlass} 和 cuDNN~\citep{chetlur2014cudnn} 在包含 TensorCore~\citep{nvidia2018turing} 的 NVIDIA GPU 上支持 FP16、INT8、INT4 精度的 IGEMM 和 ICONV 操作。
在底层计算库加持下,目前的主流神经网络软件框架已支持量化神经网络的训练和部署:TensorFlow Lite~\citep{abadi2016tensorflow} 借助 gemmlowp 支持以 PTQ、QAT 方式转换和训练 INT8 量化神经网络,并通过 Android Neural Networks API~\citep{google2020neurl} 部署至移动设备;Caffe2~\citep{markham2017caffe2}、PyTorch~\citep{paszke2019pytorch} 通过 fbgemm 支持 INT8 神经网络在 x86 平台上的量化推理和 GPU 平台上的 QAT,并通过 qnnpack 支持将模型部署至移动端;onnx~\citep{onnx2019onnx} 在计算图规范中包含了线性量化、反量化等操作,能够作为量化神经网络的通用中间表示。
在量化神经网络通过 PTQ 或 QAT 训练完成并转换为 onnx 中间表示后,可通过不同工具软件进行部署至相应平台:TensorRT~\citep{migacz20178} 自身包含 PTQ 能力,支持将模型部署至包含 TenosrCore 的 NVIDIA 硬件上;Core ML~\citep{apple2020coreml} 支持将模型部署至包含 Apple Neural Engine 的移动设备上;SNPE~\citep{qualcomm2019snpe} 自身包含基于激活标定和 data-free quantization 的 PTQ 能力,支持将模型部署至包含 DSP 或 AIX 的 Qualcomm 移动设备上。
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% FQN
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\chapter{用于目标检测的全量化网络} \label{chap::fqn}
% ==============================================================================
% Introduction
% ==============================================================================
\section{引言}
正如第~\ref{chap::background} 章所介绍,基于深度学习的目标检测技术已在大量真实世界的任务上取得显著成功 \citep{lecun2015deep}。然而,高昂的运算和存储开销,是将目标检测技术广泛应用到诸如智能手机、智能安防相机、自动驾驶系统等计算资源受限场景的主要障碍。为减少深度学习模型的运算和存储开销,近年来学术界和工业界探索了多种解决路径,其中主要方向包括高效的模型算子和结构探索~\citep{howard2017mobilenets, Sandler_2018, iandola2016squeezenet, zhang2018shufflenet}、以部署平台模型推理时间为约束的模型结构自动搜索~\citep{wu2019fbnet, tan2019mnasnet, tan2019efficientnet}、模型剪枝~\citep{han2015learning, li2016pruning, chen2018shallowing} 和模型量化~\citep{rastegari2016xnor, zhou2016dorefanet, jacob2018quantization} 等。其中,模型量化技术由于可以显著减少模型尺寸,同时使用更高效的整数或定点运算逻辑代替一般深度学习模型所需的浮点运算逻辑而提高推理效率,近年来受到了较多关注,也是本章讨论的重点。
现有的模型量化技术在物体分类等相对简单的任务上表现出色~\citep{zhou2016dorefanet, Zhang_2018, li2019additive},然而将其应用到目标检测~\citep{zou2019object} 这一较为复杂的任务时,会在模型训练及硬件部署时面临额外的挑战:
\begin{enumerate}[1)]
\item 与只需学习模型输出间偏序关系的分类任务不同,目标检测还需要模型准确地将预设锚框(anchor box)准确地回归至检测物体的边界框(bounding box),低比特量化后的模型可能难以处理这一回归任务;
\item 检测模型为保持特征图(feature map)的空间信息,其输入图片尺寸较分类任务增大(一般检测模型输入图像短边尺寸为 $600\sim 800$ 像素)而占用更多 GPU 显存,导致训练时单 GPU 批量大小(batch size)缩小至 2 或 4,从而影响模型中部分正则化操作,例如批正则化(Batch Normalization~\citep{ioffe2015batch},下文简称 BN)层的效率,使得本身就难以训练的量化网络更不稳定、难以收敛;
\item 大部分运行量化模型的专有硬件,例如终端设备上嵌入的 FPGA 和 DSP 等,为保证硬件利用率和访存效率,并不包含浮点运算单元。这要求量化检测模型在训练后不包含任何浮点操作,而现有的大部分模型量化算法~\citet{zhou2016dorefanet, Zhang_2018, li2019additive} 为保证模型量化后准确度,会将模型的 BN 层等敏感部分数值精度保留为浮点。同时,一些模型量化方法对一般硬件部署并不友好,例如 \citet{zhu2016trained, cai2017deep}。
\end{enumerate}
针对上述挑战,本章提出了一种适用于目标检测任务且对于一般硬件友好的低比特量化神经网络训练及部署方法,称为\emph{用于目标检测的全量化网络}(\emph{Fully Quantized Network for Object Detection},下文简称 FQN)。FQN 可以在复杂的目标检测模型——例如 RetinaNet~\citep{lin2017focal} 和 Faster RCNN~\citep{ren2015faster} 上——将模型参数及激活的数值精度量化至 4 比特,并保持足够的准确度。FQN 使用对于一般硬件友好的非对称线性量化,且通过 BN 折叠技术,使模型训练后不包含任何浮点操作。为解决 FQN 的训练收敛问题,本章详细分析了其在 MS COCO 数据集~\citep{lin2014microsoft} 上的训练过程,指出其训练不稳定性的根源在于模型参数的通道间分布差异、模型激活量化的准确度不足以及小训练批量尺寸导致的 BN 统计量不稳定,并提出了相应的措施解决上述问题。
本章在 MS COCO 数据集上验证了 FQN 的有效性,所用的检测算法包括一阶检测算法 RetinaNet 和二阶检测算法 Faster RCNN,所用的模型包括使用特征金字塔(Feature Pyramid Network~\citep{lin2017feature},下文简称 FPN)的 ResNet-\{18, 34, 50\}~\citep{He_2016} 和 MobileNet-v2~\citep{Sandler_2018}。FQN 在上述实验中均保持了较高准确度,例如使用 4-bit ResNet-18 的 RetinaNet 检测模型应用 FQN 训练后,其 mAP 相较全精度模型仅下降 $0.031$ (4-bit $0.286$ mAP 相较于全精度 $0.317$ mAP),而之前被用于 TensorFlow Lite 中的 \citet{jacob2018quantization} 和 \citet{krishnamoorthi2018quantizing} mAP 下降分别为 $0.120$ 和 $0.091$,其相对准确度损失是 FQN 的 $3.87\times$ 和 $2.94\times$。
% ------------------------------------------------------------------------------
% Motivation
% ------------------------------------------------------------------------------
\subsection{工作动机}
\paragraph{对于一般硬件友好的全量化网络}
量化网络的大部分部署场景(包括软件及硬件)并不支持特殊的量化模式,例如 NVIDIA TensorRT~\citep{vanholder2016efficient} 在包含 Tensor Core 的 GPU 或加速卡上运行 8-bit/4-bit 模型时,只支持对称线性量化~\citep{migacz20178},Qualcomm SNPE~\citep{qualcomm2019snpe} 在 DSP 或 AIX 设备上运行 8-bit 模型时,只支持零点对齐的非对称线性量化。这意味着,目前许多使用特殊量化函数的模型量化研究~\citep{zhu2016trained, cai2017deep, Zhang_2018} 是对一般硬件不友好且难以实际部署的。同时,大部分现有研究过于关注量化模型的最终准确度,将量化模型中的敏感操作——例如模型第一层和最后一层、模型中的 BN 等正则化层等——保留为浮点数值精度~\citep{zhou2016dorefanet, Zhang_2018, li2019additive}。在实际的部署场景中,智能相机等终端设备内嵌的 FPGA 或 ASIC 等专有硬件为保证硬件利用率一般不会再额外设计浮点运算逻辑;移动设备端的神经网络推理库虽然支持将模型中部分操作从 DSP 或 AIX 等量化设备回调(fallback execution)至支持浮点运算的 CPU 或 GPU,但其中涉及的上下文切换会极大降低模型的运行效率。因此,探索针对一般硬件友好的、完全量化的模型量化方法有极大的潜在实际影响力。
\paragraph{适用于复杂任务的低比特量化网络}
目前神经网络模型量化研究主要集中在两个方向:
\begin{enumerate}[1)]
\item 在相对简单的模型、任务和数据集上,使用极低的数值精度量化模型参数及激活。例如 \citet{hubara2016binarized, zhou2016dorefanet} 报告了在 SVHN、CIFAR-10 等物体分类任务上,可将 small-VGG、AlexNet 等模型参数及激活压缩至 1-bit;
\item 使用较高的数值精度,量化用于相对复杂任务的模型。例如 \citet{jacob2018quantization} 报告了在人脸特征抽取、人脸检测、通用目标检测任务上,多种模型可在 8-bit 精度下保持可用准确度。
\end{enumerate}
由于定点或整数乘法逻辑的计算开销与量化位宽呈超线性,且占计算能耗大部分的访存开销正比于量化位宽~\citep{han2017efficient},8-bit 量化的资源开销对于计算资源非常受限的设备而言仍然过于高昂。因此一个自然的想法是,能否将 4-bit $\sim$ 1-bit 低比特压缩技术用于复杂任务和复杂模型上。然而,直接将 \citet{rastegari2016xnor, zhou2016dorefanet} 等量化训练方法用于复杂模型时,会出现量化训练无法收敛、最终模型准确度低的问题。本章通过观察复杂任务上量化模型的训练过程,发现其中存在 BN 层 EMA 统计值波动明显、量化激活存在较多离群点等不稳定现象。后续实验进一步发现消除这些不稳定性,可显著改善复杂任务上低比特量化模型的训练收敛性并提高模型最终准确度(详见第~\ref{sec::fqn::experiments} 节)。
% ------------------------------------------------------------------------------
% Contributions
% ------------------------------------------------------------------------------
\subsection{主要贡献}
\begin{enumerate}
\item 本章提出了 FQN,一种适用于目标检测模型的低比特量化方法。FQN 使用对一般硬件友好的线性量化方式,使量化后的目标检测模型可以使用整数计算逻辑进行推理,且量化后的模型不包含浮点操作,便于部署至计算资源受限的终端设备;
\item 本章分析了 FQN 的训练过程,指出其在低比特量化训练中不稳定性的主要来源,并提出了相应解决方案;
\item 本章在 MS COCO 数据集上,使用不同神经网络模型和目标检测算法验证了 FQN 的准确性。FQN 在实验中达到了高于先前领域最优方法的检测准确度。
\end{enumerate}
% ==============================================================================
% Method
% ==============================================================================
\section{目标检测模型的量化} \label{sec::fqn::methods}
本节详细描述 FQN 方法的各组成部分,包括对目标检测模型参数和激活的量化算法、量化模型的训练策略以及针对检测模型量化的实现细节。FQN 通过量化感知训练,可使检测模型在以低至 4-bit 的数值精度运行时仍保持足够的准确度。低比特量化目标检测模型的难点在于量化感知训练的不稳定性,而 FQN 通过对模型参数、激活、正则化层的量化算法和训练策略的改进以减少该不稳定性。FQN 对模型参数和激活使用线性量化,量化后仅需整数数值逻辑即可完成模型推理,从而便于部署至一般硬件平台上。
% ------------------------------------------------------------------------------
% Quantization aware training
% ------------------------------------------------------------------------------
\subsection{量化感知训练} \label{sec::fqn::qat_overview}
根据~\citet{krishnamoorthi2018quantizing} 提出的针对模型量化方法的分类标准,FQN 属于\emph{量化感知训练}(\emph{Quantization Aware (re-)Training},下文简称 QAT),即在模型训练时将模型参数及激活按照部署时的量化方式映射至离散浮点值,以模拟模型量化运行时的数值误差,从而训练得到在量化误差存在时仍能在目标任务上保持足够准确度的模型。采用 QAT 的模型量化训练部署流程依次包含下三个阶段:
\begin{description}
\item[模型预训练] 在没有预先提供全精度预训练参数时,需要对模型进行预训练。对于物体分类等相对简单的任务,模型在以特定方式初始化后直接在目标数据集上训练;对于目标检测、场景分割等相对复杂的任务,则一般先将其主干模型(backbone network)在分类任务上训练至收敛,再加入任务子模型在目标数据集上训练。模型参数和激活在预训练过程中保持全精度。对于包含 BN 等正则化操作的模型,模型每层在训练时会统计在当前的小批量输入下,该层输出各通道的均值、方差 $\{\Batch{\mu}, \Batch{\sigma}\}$,使用该组统计值将其输出正则化为近似标准高斯分布,并通过动量 $m$ 更新该层输出均值、方差的指数移动平均(Exponential Moving Average,下文简称 EMA)统计值 $\{\EMA{\mu}, \EMA{\sigma}\}$;
\item[模型量化感知训练] 在模型预训练结束,或事先已获得全精度预训练模型后,则对该全精度模型进行量化感知训练。量化感知训练在模型计算图中加入额外算子:对于模型各层参数和激活,在前向传播时将其离散化,以模拟量化部署运行时的数值误差;在反向传播时,则通过 Straight Though Estimator (下文简称 STE,详见第~\ref{sec::fqn::q_weight} 节)或其他方法,根据算子离散输出接收的梯度计算出其全精度输入的梯度,以便继续梯度传播。注意在此阶段,每组模型参数均保留一份全精度副本,以确保参数能被数值范围较小的梯度准确更新。
在此阶段,先前基于 QAT 的主要工作~\citet{jacob2018quantization, krishnamoorthi2018quantizing} 在量化后的模型激活上计算其小批量统计值 $\{\Batch{\mu}, \Batch{\sigma}\}$ 并继续更新各层 EMA 统计值 $\{\EMA{\mu}, \EMA{\sigma}\}$。我们发现这是导致目标检测模型 QAT 不稳定的原因之一,详见第~\ref{sec::fqn::q_bn} 节;
\item[模型量化部署] 在上一阶段完成后,所得模型已经可以在量化误差下保持足够准确度。在模型部署前,需将模型中 BN 层的参数——其 EMA 统计值 $\{\EMA{\mu}, \EMA{\sigma}\}$ 和仿射参数 $\{\alpha, \beta\}$ ——合并至前一层卷积或全连接层的参数 $\{W, b\}$ 中,消除额外的线性操作以提高模型推理效率。之后将模型中所有参数转换至部署平台所支持的量化格式,例如包含以 \verb|int32| 定点数表示量化缩放的 \verb|uint8| 矩阵,最终在目标平台上运行。注意量化后的模型也可以在 GPU 上以离散浮点形式使用 \verb|cuDNN| 等浮点计算库运行,以快速验证 QAT 后量化模型的准确度。
\end{description}
% ------------------------------------------------------------------------------
% Asymmetric linear quantization
% ------------------------------------------------------------------------------
\subsection{非对称线性量化} \label{sec::fqn::quant_scheme}
目前大多数神经网络模型使用单精度浮点格式存储其模型参数,并在运行时使用浮点数值逻辑计算中间激活和最终输出。模型量化方法将这些浮点值舍入至事先定义的一组离散数值中,以减少模型的存储开销;若这些离散数值以线性均匀或 2 的幂次均匀(power-of-two uniform)排布,则运行时的计算可在离散数值的\emph{秩}上以整数数值逻辑进行。具体地,给定一浮点格式的张量 $X^R = [x^R_{1, \ldots n}]$ 和量化位宽 $k$,量化函数 $Q_k(\cdot)$ 将每一浮点值 $x^R_i$ 映射至距其最近的量化点 $q_j$:
\begin{align}
X^Q = Q_k(X^R) \in \{q_1, \ldots q_{2^k-1}\}
\end{align}
FQN 使用\emph{非对称线性量化}模式,即任意相邻 $q_j, q_{j+1}$ 间等距,但 $\{q_0, \ldots q_{2^k-1}\}$ 不关于零点对称。因此在 FQN 中,$X^Q$ 按照
\begin{align}
X^Q = \Delta (X^I - z) \label{eq::fqn::asymm_linear_q}
\end{align}
计算得出。其中 $\Delta$ 表示任意 $q_j, q_{j+1}$ 间的距离(下文统称\emph{量化间距}),$X^I$ 是以无符号整数表示的、 $X^R$ 中各元素在量化点集中的秩,$z$ 表示实数零点对应至量化点集的秩。在给定量化数值范围 $[lb, ub]$ 和量化位宽 $k$ 后,$\Delta$ 按照
\begin{align}
ub &= \max(ub, lb + \epsilon) \\
\Delta &= \frac{ub - lb}{2^k - 1}
\end{align}
计算得出。其中 $\epsilon$ 为确保数值稳定性而设置的最小量化范围,一般设为 $10^{-2}$,且给定量化范围后 $q_1 = lb$,$q_{2^k-1} = ub$。在得到 $\Delta$ 后,$X^I$ 可按照
\begin{align}
\tilde{X}^R &= \Clamp{X^R, lb, ub} \\
X^I &= \Round{\frac{\tilde{X}^R - lb}{\Delta}}
\end{align}
计算得出。其中 $\Clamp{\cdot, a, b} = \max(a, \min(\cdot, b))$,将输入 $X^R$ 限制在量化范围内;$\Round{\cdot}: \mathbb{R}\to\mathbb{Z}$ 为舍入操作符。
当模型第 $l$ 层的参数 $W_l$ 和输入 $x_l$ 均被量化后,其数值操作变为
\begin{align}
y_l = Q_k(W_l) Q_k(x_l) = \Delta_{W_l}\Delta_{x_l} (W^I_l x^I_l) \label{eq::fqn::intmm}
\end{align}
由于 $W^I_l, x^I_l$ 均以无符号整数表示,该层的数值运算可用更为高效的整数数值逻辑进行。注意~\eqref{eq::fqn::intmm} 中省略了对零点 $z$ 的处理,以及使用非浮点数值逻辑处理 $\Delta_{W_l}\Delta_{x_l}$ 的讨论。关于零点和缩放的算法及部署细节的详细讨论见第~\ref{sec::fqn::q_misc} 节。% 和第~\ref{sec::fqn::deployment} 节。
因为包含舍入操作 $\Round{\cdot}$ 的量化函数 $Q_k(\cdot)$ 并不可导,因此 FQN 在训练时使用 STE~\citep{bengio2013estimating} 回传上游梯度 $\diff{y}{X^I}$。注意超出量化范围 $[lb, ub]$ 的输入元素不接收梯度:
\begin{align}
\diff{y}{x^R_i} =
\begin{cases}
\diff{y}{x^I_i} & \text{if } x^R_i \in [lb, ub] \\
0 & \text{otherwise}
\end{cases}
\end{align}
% ------------------------------------------------------------------------------
% Quantize weights
% ------------------------------------------------------------------------------
\subsection{模型参数量化} \label{sec::fqn::q_weight}
\begin{figure}[htb]
\centering
\begin{subfigure}[t]{0.45\columnwidth}
\centering
\includegraphics[width=\columnwidth]{img/FQN/res50_channels.pdf}
\caption{ResNet-50 模型参数各通道间最大/最小幅度比值的柱状统计,注意 x 轴单位为分贝}
\label{img::fqn::w_channels}
\end{subfigure}
\quad
\begin{subfigure}[t]{0.45\columnwidth}
\centering
\includegraphics[width=\columnwidth]{img/FQN/per_channel_quant.pdf}
\caption{模型参数逐通道量化策略,每层各卷积核 $w_c$ 有各自的量化范围 $[lb_c, ub_c]$}
\label{img::fqn::channel_quant}
\end{subfigure}
\caption{FQN 关于目标检测模型参数分布的分析~\subref{img::fqn::w_channels} 及对应的逐通道量化策略~\subref{img::fqn::channel_quant}。图~\subref{img::fqn::w_channels} 中分布在 60dB $\sim$ 80dB 之间的统计值说明模型中存在参数通道间幅度最大/最小比值达到 $10^6 \sim 10^8$ 的层,对这些层各通道使用同一量化边界将导致显著量化误差。因此,FQN 使用图~\subref{img::fqn::channel_quant} 所示的逐通道量化策略。}
\label{img::fqn::w_quant}
\end{figure}
基于深度卷积网络的目标检测模型中,主要的参数化算子为卷积操作和全连接操作。对于 2D 卷积层,其参数 $W \in \mathbb{R}^{c_{\mathrm{out}} \times c_{\mathrm{in}} \times k_{\mathrm{H}} \times k_{\mathrm{W}}}$,对于全连接层,其参数 $W \in \mathbb{R}^{c_{\mathrm{out}} \times c_{\mathrm{in}}}$。其中 $c_{\mathrm{out}}$ 表示输出通道数(或称卷积核数),$c_{\mathrm{in}}$ 表示输入通道数(或称卷积核通道数),$k_{\mathrm{H}} \times k_{\mathrm{W}}$ 表示 2D 卷积核高宽尺寸。我们发现在目标检测模型中,同一层模型参数在 $c_{\mathrm{out}}$ 维度,或者说同一层不同卷积核之间,幅度范围相差非常明显。例如,在 MS COCO 数据集上训练的 ResNet-50 RetinaNet 检测模型,其 \verb|layer2.0.conv1| 层包含的卷积核中,参数幅度范围从 $3.745 \times 10^{−8}$ 至 $0.727$ 不等。若统计该模型各卷积层中,参数幅度最大的卷积核与参数幅度最小的卷积核之比,即对于模型第 $l$ 层,计算
\begin{align}
\eta_l = \frac{\max(\mathrm{range} (W_l))}{\min(\mathrm{range}(W_l))} \label{eq::fqn::w_range_ratio}
\end{align}
其中 $\mathrm{range}(W_l)$ 返回第 $l$ 层中各卷积核参数 $W_{l, i}$ 的数值范围 $\max(W_{l, i}) - \min(W_{l, i})$。对 $\eta_{1, \ldots L}$ 做直方图统计,如图~\ref{img::fqn::w_channels} 所示,模型中存在大量参数通道间幅度差距悬殊的层。
如果模型每层参数共用一组量化范围,则数值范围较小的卷积核会因同层内其他数值范围较大的卷积核扩张量化范围,而产生巨大的相对数值误差,从而使 QAT 不稳定。为解决此问题,FQN 中同一层内各个卷积核使用各自的量化范围,如图~\ref{img::fqn::channel_quant} 所示,该量化方式称为\emph{逐通道量化}。具体地,模型第 $l$ 层参数 $W_l$ 各通道量化范围由该通道的最小值、最大值决定,即
\begin{align}
lb_l &= \min_{\mathrm{dim}=c_{\mathrm{out}}} W_l \\
ub_l &= \max_{\mathrm{dim}=c_{\mathrm{out}}} W_l
\end{align}
其中 $lb_l, ub_l \in \mathbb{R}^{c_{\mathrm{out}}}$。
% ------------------------------------------------------------------------------
% Quantize activations
% ------------------------------------------------------------------------------
\subsection{模型激活量化} \label{sec::fqn::q_act}
\begin{figure}[htb]
\centering
\includegraphics[width=0.5\columnwidth]{img/FQN/act_quant.pdf}
\caption{VGG16 主干模型第 12 层卷积输出的激活分布。注意该分布在 $[-1.5, -1.2]$ 和 $[1.2, 1.5]$ 范围内存在离群点,会导致激活量化范围过大而降低量化准确度,故 FQN 使用模型在标定集上激活分布的上下 $\gamma = 0.999$ 分位点作为该层激活的量化数值范围。}
\label{img::fqn::q_act}
\end{figure}
为保证对一般硬件部署友好,FQN 量化了从正则化后的模型输入至检测任务子网络最后一层输入间的所有中间激活。由于事先无从得知模型运行时各中间激活的数值范围,故需在 QAT 阶段模型激活被量化前,对模型每一层中间激活进行\emph{标定}(\emph{calibration})以确定其量化数值范围。\citet{jacob2018quantization, krishnamoorthi2018quantizing} 通过在模型激活被量化前的一部分训练步数中(\citet{jacob2018quantization} 在 ILSVRC 2012 分类任务中统计了 5K 个训练步数),使用 EMA 统计每层浮点激活在模型参数被量化后的数值范围,来作为该层激活被量化时的量化范围。我们在实验中发现,对于目标检测模型,使用 EMA 统计标定激活量化范围会有以下问题:
\begin{enumerate}[1)]
\item 激活范围的 EMA 统计值对于\emph{统计步数}和\emph{EMA 动量}这两个超参数很敏感,针对不同的检测算法、主干模型和量化数值精度,需要做超参调优;
\item 如图~\ref{img::fqn::q_act} 所示,目标检测模型的中间激活分布中容易包含\emph{离群点},特别是在 FPN 输出特征图等不经过非线性层的中间激活。这些离群点容易将 EMA 动量扩张至较大范围,从而降低量化精度、使 QAT 更难收敛。
\end{enumerate}
针对上述问题,FQN 使用模型每层激活在标定集上的特定分布分位数作为该层激活的量化数值范围。具体地,FQN 在训练集上随机抽取 $n_{\mathrm{cal}}$ 组小批量样本作为\emph{标定集},并将预训练得到的全精度模型以第~\ref{sec::fqn::q_weight} 节方法进行参数量化后,统计该模型在标定集上运行时各层激活分布的 $\gamma$、$1-\gamma$ 分位点,将其直接作为该层激活的量化范围,其中 $\gamma \in [0, 1]$。
我们在实验中发现,对于大部分目标检测模型 $n_{\mathrm{cal}} = 20, \gamma = 0.999$ 能使 QAT 训练得到最佳的效果。但更重要的是,第~\ref{sec::fqn::analysis} 节的实验说明,FQN 模型的最终准确度对超参数 $\gamma$ 的选取并不敏感。
% ------------------------------------------------------------------------------
% Quantize BN
% ------------------------------------------------------------------------------
\subsection{BN 层折叠及量化} \label{sec::fqn::q_bn}
模型中的各 BN 层在训练阶段,通过统计该层在每个小批量输入下的输出激活 $x^l$ 的均值 $\Batch{\mu}$、方差 $\Batch{\sigma}$,将该输出正则化至近似标准高斯分布,同时通过动量因子更新 EMA 统计量 $\{\EMA{\mu}, \EMA{\sigma}\}$ 以在模型推理时使用。注意该正则化过程,以及后续的通过参数 $\{\alpha, \beta\}$ 进行的仿射变换,均是对该 BN 层输入的\emph{线性变换}。由于 BN 层与其之前的卷积或全连接层之间并无非线性操作,故 $\{\Batch{\mu}, \Batch{\sigma}, \alpha, \beta\}$ 可作为线性变换的参数,\emph{折叠}进先前层的参数 $\{W, b\}$ 中,从而在模型部署前去除显式的 BN 层。具体地,BN 前一层卷积或全连接层折叠后的参数 $\Fold{W}, \Fold{b}$ 为
\begin{align}
\Fold{W} &= \frac{\alpha}{\sqrt{\Batch{\sigma}^2 + \epsilon}} W \label{eq::fqn::fold_w} \\
\Fold{b} &= \frac{\alpha}{\sqrt{\Batch{\sigma}^2 + \epsilon}} (b - \Batch{\mu}) + \beta \label{eq::fqn::fold_b}
\end{align}
其中 $\epsilon$ 为保持计算数值稳定性的常数。在~\citet{jacob2018quantization, krishnamoorthi2018quantizing} 中,模型在训练阶段的训练计算图按照~\eqref{eq::fqn::fold_w} 及~\eqref{eq::fqn::fold_b} 修改,以模拟模型在部署运行时 BN 折叠并对 $\Fold{W}, \Fold{b}$ 量化后的数值误差。修改后,模型预训练阶段和量化感知训练阶段的计算图分别如图~\ref{img::fqn::foldbn_train} 和图~\ref{img::fqn::foldbn_quant_train} 所示。
\begin{figure}[htb]
\centering
\includegraphics[width=\columnwidth]{img/FQN/bn_beta_mean_var.pdf}
\caption{4-bit ResNet-18 RetinaNet BN 层 \texttt{layer2.0.bn1} 在训练过程中仿射参数 $\beta$ (左)、逐批量激活均值 $\Batch{\mu}$ (中)和方差 $\Batch{\sigma}$ (右)分布的演化情况,其中 z 轴为训练步数。由于目标检测模型单 GPU 训练批量尺寸较小(每一 GPU 2 个样本)且模型激活被激进地量化,逐批量统计值 $\Batch{\mu}, \Batch{\sigma}$ 分布并不稳定。因此,FQN 在 QAT 阶段全程使用 EMA 统计值 $\EMA{\mu}, \EMA{\sigma}$ 对各 BN 层输入进行正则化。}
\label{img::fqn::bn_stat}
\end{figure}
然而在目标检测模型的训练过程中,我们发现在小批次输入上统计的激活均值方差 $\Batch{\mu}, \Batch{\sigma}$ 很不稳定。例如图~\ref{img::fqn::bn_stat} 展示了 ResNnet-18 RetinaNet 模型在 MS COCO 数据集上训练时,其 \verb|layer2.0.bn1| BN 层中参数和统计值随训练步数的分布变化。其中间子图和右侧子图分别表示 $\Batch{\mu}, \Batch{\sigma}$ 的分布,其分布在训练过程中剧烈变化。我们指出这是导致量化目标检测模型 QAT 不稳定的主要原因之一。
\begin{figure}[htb]
\centering
\includegraphics[width=0.7\columnwidth]{img/FQN/fold_bn.pdf}
\caption{FQN 在 QAT 阶段对 BN 层做稳定化折叠。EMA 统计参数 $\EMA{\mu}, \EMA{\sigma}$ 来自全精度预训练模型,在 QAT 阶段和仿射参数 $\alpha, \beta$ 一并折叠至前一卷积层或全连接层参数 $W, b$ 中。QAT 阶段不再通过动量更新 $\EMA{\mu}, \EMA{\sigma}$ ,而 $\alpha, \beta$ 仍然通过梯度更新。}
\label{img::fqn::foldbn_stable}
\end{figure}
FQN 通过一个简单的改进来处理此问题。注意在目标检测模型的训练流程中(见第~\ref{sec::fqn::qat_overview} 节的讨论),不论是事先提供的全精度模型或是在训练集上重新以全精度训练的模型,其中每一 BN 层均包含收敛模型的激活分布统计值 $\{\EMA{\mu}, \EMA{\sigma}\}$。我们发现使用该组在全精度下统计的 EMA 统计值也适用于 QAT 阶段的量化模型激活。因此在 FQN 的 QAT 阶段,模型各 BN 层均使用先前全精度模型的 EMA 统计值对该层激活做归一化操作。即在修改模型计算图时,将 $\{\EMA{\mu}, \EMA{\sigma}\}$ 而非 $\{\Batch{\mu}, \Batch{\sigma}\}$ 折叠至 BN 前一层的参数中。具体地,在 FQN 中 \eqref{eq::fqn::fold_w} 和 \eqref{eq::fqn::fold_b} 被修改为
\begin{align}
\Fold{W} &= \frac{\alpha}{\sqrt{\EMA{\sigma}^2 + \epsilon}} W \label{eq::fqn::fold_w_stable} \\
\Fold{b} &= \frac{\alpha}{\sqrt{\EMA{\sigma}^2 + \epsilon}} (b - \EMA{\mu}) + \beta \label{eq::fqn::fold_b_stable}
\end{align}
注意量化模型 BN 层的仿射参数 $\{\alpha, \beta\}$ 在 QAT 阶段仍保持更新。我们称这一方法为\emph{稳定化的 BN 折叠},修改后的模型计算图如图~\ref{img::fqn::foldbn_stable} 所示。
\begin{figure}[p]
\tikzstyle{nobox}=[text centered, text=blue!60, font=\sffamily\bfseries]
\tikzstyle{act}=[thick, rectangle, rounded corners, minimum width=2cm, minimum height=1cm, text centered, draw=black, fill=yellow!20, font=\sffamily\bfseries]
\tikzstyle{add}=[thick, ellipse, minimum width=1cm, minimum height=1cm, text centered, draw=black, fill=yellow!20, font=\sffamily\bfseries]
\tikzstyle{conv}=[thick, rectangle, rounded corners, minimum width=2cm, minimum height=1cm, text centered, draw=black, fill=green!20, font=\sffamily\bfseries]
\tikzstyle{params}=[thick, ellipse, minimum width=2cm, minimum height=1cm, text centered, draw=black, fill=blue!20, font=\sffamily\bfseries]
\tikzstyle{small_params}=[thick, ellipse, minimum width=1cm, minimum height=1cm, text centered, draw=black, fill=blue!20, font=\sffamily\bfseries]
\tikzstyle{quant}=[thick, ellipse, minimum width=2cm, minimum height=1cm, text centered, draw=black, fill=red!20, font=\sffamily\bfseries]
\tikzstyle{ma}=[thick, ellipse, minimum width=2cm, minimum height=1cm, text centered, draw=black, fill=gray!20, font=\sffamily\bfseries]
\tikzstyle{arrow} = [thick,->,>=stealth]
\centering
\begin{subfigure}[t]{0.45\columnwidth}
\centering
\begin{tikzpicture}[node distance=2cm,scale=0.7,transform shape]
\node (conv) [conv] {conv};
\node (weights) [params, below right of=conv] {weights};
\node (input) [nobox, below left of=weights] {input};
\node (moments) [act, above of=conv] {moments};
\node (ma) [ma, above of=moments] {EMA $\mathbf{\mu}$, $\mathbf{\sigma}$};
\node (fold_weights) [act, above left of=ma] {$\mathbf{w \gamma / \sigma}$};
\node (gamma) [small_params, below left of=fold_weights] {$\mathbf{\gamma}$};
\node (fold_conv) [conv, above of=fold_weights] {conv fold};
\node (fold_biases) [act, above right of=ma] {$\mathbf{\beta - \gamma \mu / \sigma}$};
\node (beta) [small_params, below right of=fold_biases] {$\mathbf{\beta}$};
\node (add) [add, above of=fold_conv] {+};
\node (ReLU6) [act, above of=add] {ReLU6};
\node (output) [nobox, above of=ReLU6] {output};
\draw [arrow] (input) -- (conv);
\draw [arrow] (weights) -- (conv);
\draw [arrow] (conv) -- (moments);
\draw [arrow] (moments) -- (ma);
\draw [arrow] (ma) -- (fold_weights);
\draw [arrow] (gamma) -- (fold_weights);
\draw [arrow] (ma) -- (fold_biases);
\draw [arrow] (beta) -- (fold_biases);
\draw [arrow] (fold_weights) -- (fold_conv);
\draw [arrow] (input) to [out=135,in=225,looseness=1.1] (fold_conv);
\draw [arrow] (fold_conv) -- (add);
\draw [arrow] (fold_biases) -- (add);
\draw [arrow] (add) -- (ReLU6);
\draw [arrow] (ReLU6) -- (output);
\end{tikzpicture}
\caption{BN 层折叠至卷积层的训练计算图}
\label{img::fqn::foldbn_train}
\end{subfigure}
\quad
\begin{subfigure}[t]{0.45\columnwidth}
\centering
\begin{tikzpicture}[node distance=2cm,scale=0.7,transform shape]
\node (conv) [conv] {conv};
\node (weights) [params, below right of=conv] {weights};
\node (input) [nobox, below left of=weights] {input};
\node (moments) [act, above of=conv] {moments};
\node (ma) [ma, above of=moments] {EMA $\mathbf{\mu}$, $\mathbf{\sigma}$};
\node (fold_weights) [act, above left of=ma] {$\mathbf{w \gamma / \sigma}$};
\node (gamma) [small_params, below left of=fold_weights] {$\mathbf{\gamma}$};
\node (wt_quant) [quant, above of=fold_weights] {wt quant};
\node (fold_conv) [conv, above of=wt_quant] {conv fold};
\node (fold_biases) [act, above right of=ma] {$\mathbf{\beta - \gamma \mu / \sigma}$};
\node (beta) [small_params, below right of=fold_biases] {$\mathbf{\beta}$};
\node (add) [add, above of=fold_conv] {+};
\node (ReLU6) [act, above of=add] {ReLU6};
\node (act_quant) [quant, above of=ReLU6] {act quant};
\node (output) [nobox, above of=act_quant] {output};
\draw [arrow] (input) -- (conv);
\draw [arrow] (weights) -- (conv);
\draw [arrow] (conv) -- (moments);
\draw [arrow] (moments) -- (ma);
\draw [arrow] (ma) -- (fold_weights);
\draw [arrow] (gamma) -- (fold_weights);
\draw [arrow] (ma) -- (fold_biases);
\draw [arrow] (beta) -- (fold_biases);
\draw [arrow] (fold_weights) -- (wt_quant);
\draw [arrow] (wt_quant) -- (fold_conv);
\draw [arrow] (input) to [out=135,in=225,looseness=1.1] (fold_conv);
\draw [arrow] (fold_conv) -- (add);
\draw [arrow] (fold_biases) to [out=90,in=315] (add);
\draw [arrow] (add) -- (ReLU6);
\draw [arrow] (ReLU6) -- (act_quant);
\draw [arrow] (act_quant) -- (output);
\end{tikzpicture}
\caption{BN 层折叠至卷积层中,且包含参数、激活量化算子的训练计算图}
\label{img::fqn::foldbn_quant_train}
\end{subfigure}
\caption{BN 折叠后的模型训练计算图。模型在部署时,其中 BN 层参数 $\alpha, \beta, \EMA{\mu}, \EMA{\sigma}$ 会被“吸收”进前一卷积或全连接层的参数 $W, b$ 中,从而消除部署模型的显式 BN 算子,提高推理效率。为了在模型预训练和 QAT 阶段模拟 BN 折叠的效果,FQN 对训练计算图进行了相应修改。图片来自~\citet{jacob2018quantization}。}
\label{img::fqn::foldbn_graphs}
\end{figure}
% ------------------------------------------------------------------------------
% Misc
% ------------------------------------------------------------------------------
\subsection{量化算法其他细节} \label{sec::fqn::q_misc}
\paragraph{零点对齐}
在模型 QAT 和量化部署时,需要将 $X^R$ 中的零点准确映射至 $X^Q$ 中,以避免量化模型在对中间特征补零等操作时引入额外误差。在 FQN 中,通过在 QAT 每次量化前微调量化范围 $lb, ub$ 来将实数零点对齐至量化表示~\eqref{eq::fqn::asymm_linear_q} 中的零点 $z$。具体地,微调后的量化边界 $\tilde{lb}, \tilde{ub}$ 及对应的零点在量化点集 $\{q_1, \ldots q_{2^k-1}\}$ 中的秩 $z$ 为
\begin{align}
z &= \Round{\frac{|lb|}{\Delta}} \\
\tilde{lb} &= \sign(lb) \cdot \Delta z \\
\tilde{ub} &= \sign(ub) \cdot \Delta (2^k - 1 - z)
\end{align}
\paragraph{上采样操作和元素间操作}
在包含 FPN~\citep{lin2017feature} 的目标检测模型中,主干网络多级特征由深至浅,依次通过上采样扩展至前一层特征尺寸大小后叠加输出,以使图片特征同时包含深层特征语意信息和浅层特征精确的空间信息。为确保不引入浮点操作,FQN 中所有上采样操作均使用最近邻插值完成。对于逐元素相加操作 $\Delta_a a^I + \Delta_b b^I = \Delta_c c^I$,需要将输入向量的缩放因子 $\Delta_a, \Delta_b$ 统一缩放至 $\Delta_c$,再对缩放后的 $c^I = \frac{\Delta_a}{\Delta_c}a^{I} + \frac{\Delta_b}{\Delta_c}b^{I}$ 使用整数数值逻辑相加。在 QAT 过程中,这一操作可以通过对逐元素操作的输入输出分别添加激活量化函数模拟。
% ==============================================================================
% Deployment considerations
% ==============================================================================
% \section{真实世界硬件部署的考量} \label{sec::fqn::deployment}
% TODO
% ==============================================================================
% Experiments
% ==============================================================================
\section{主要实验结果} \label{sec::fqn::experiments}
为验证 FQN 在目标检测任务上的有效性,本章报告使用不同目标检测算法和主干网络模型的 FQN 在 MS COCO 数据集上的实验结果。由于其标注类别的丰富性和样本场景的复杂性,MS COCO 是现今目标检测模型的主要评测数据集。在本章的所有实验中,模型准确性以其在 MS COCO 数据集\emph{物体边界框检测}(\emph{object bounding box detection})任务上的多类别平均准确度(mean average precession,下文简称 mAP)和多类别平均召回率(mean average recall,下文简称 mAR)。实验结果中 mAP 和 mAR 计算方式按照 MS COCO 标准,报告了不同交并比(intersection over union,下文简称 IoU)阈值下的平均准确度 $\mAP{\{0.5:0.95, 0.5, 0.75\}}$,不同候选检测输出数目下的平均召回率 $\mAR{\{1, 10, 100\}}$,分别对于大、中、小尺寸目标的平均准确度和平均召回率 $\mAP{\{L, M, S\}}, \mAR{\{L, M, S\}}$。
\paragraph{训练策略}
本章中所有实验使用相同的训练策略。所有模型的预训练及 QAT 均在 MS COCO 数据集 \verb|coco-2017-train| 数据集上进行。在预训练阶段,模型主干网络使用 ImageNet 上预训练模型的参数作为初始化。预训练在 16 块 NVIDIA GTX 1080 Ti 上以同步(all-reduce)数据并行方式进行,每块 GPU 上训练的批量尺寸为 2。学习率线性 warmup 至 0.04,之后在训练第 30K 和第 80K 步分别将学习率衰减 $0.1\times$,并在 90K 步时结束。
在得到预训练至收敛的全精度模型后,QAT 阶段在相同的数据集上进行。模型参数和激活的数值精度被量化至 4-bit,各层激活量化范围在由 20 个从训练集上随机采样的小批量输入标定,量化上下界分别标定为每层激活分布的 $0.999\%$ 和 $0.001\%$ 分位点。QAT 阶段其他设置与预训练阶段一致,除了学习率被固定为 $0.004$。QAT 阶段持续 40K 步。
% ------------------------------------------------------------------------------
% Numerical results
% ------------------------------------------------------------------------------
\subsection{数值结果} \label{sec::fqn::main_exp}
\begin{table}[p]
\centering
\caption{使用不同主干网络的一阶检测模型 RetinaNet FQN 在 MS COCO 数据集上的实验结果。表格中以 -FP32 结尾的数据表示作为基准的全精度模型的实验结果,以 -INT4 结尾的数据表示模型参数和激活数值精度被量化至 4-bit 的实验结果。注意由于 GPU 显存限制,训练 MobileNet-v2 模型时,输入图片短边尺寸为 600 像素。}
\label{tab::fqn::retina_coco}
\begin{subtable}[t]{\columnwidth}
\centering
\caption{RetinaNet 模型在 MS COCO 数据集上的平均准确率}
\label{tab::fqn::retina_coco_mAP}
\begin{tabular}{lc*{6}{c}}
\toprule
\multirow{2}{*}{模型} & \multirow{2}{*}{输入尺寸} & \multicolumn{6}{c}{mAP} \\
& & $\mathrm{AP}$ & $\mathrm{AP}^{0.5}$ & $\mathrm{AP}^{0.75}$ &
$\mathrm{AP} ^ {\mathrm{S}}$ & $\mathrm{AP} ^ {\mathrm{M}}$ & $\mathrm{AP} ^ {\mathrm{L}}$ \\
\midrule
R50-FP32 & 800 & 0.356 &0.551 &0.382 &0.203 &0.393 &0.465 \\
R50-INT4 & 800 & 0.325 &0.515 &0.347 &0.173 &0.356 &0.426 \\
\hdashline
R34-FP32 & 800 & 0.348 &0.538 &0.371 &0.192 &0.381 &0.460 \\
R34-INT4 & 800 & 0.313 &0.504 &0.333 &0.161 &0.344 &0.416 \\
\hdashline
R18-FP32 & 800 & 0.317 &0.503 &0.337 &0.164 &0.346 &0.424 \\
R18-INT4 & 800 & 0.286 &0.469 &0.299 &0.149 &0.312 &0.387 \\
\hdashline
MN2-FP32 & 600 & 0.275 &0.448 &0.290 &0.154 &0.289 &0.365 \\
MN2-INT4 & 600 & 0.255 &0.425 &0.269 &0.134 &0.271 &0.345 \\
\bottomrule
\end{tabular}
\end{subtable}
\newline
\vspace*{0.5 cm}
\newline
\begin{subtable}[t]{\columnwidth}
\centering
\caption{RetinaNet 模型在 MS COCO 数据集上的平均召回率}
\label{tab::fqn::retina_coco_mAR}
\begin{tabular}{lc*{6}{c}}
\toprule
\multirow{2}{*}{模型} & \multirow{2}{*}{输入尺寸} & \multicolumn{6}{c}{mAR} \\
% \cline{3-14}
& & $\mathrm{AR}^{1}$ & $\mathrm{AR}^{10}$ & $\mathrm{AR}^{100}$ &
$\mathrm{AR} ^ {\mathrm{S}}$ & $\mathrm{AR} ^ {\mathrm{M}}$ & $\mathrm{AR} ^ {\mathrm{L}}$ \\
\midrule
R50-FP32 & 800 &0.308 &0.498 &0.529 &0.335 &0.569 &0.680 \\
R50-INT4 & 800 &0.286 &0.463 &0.493 &0.298 &0.530 &0.643 \\
\hdashline
R34-FP32 & 800 &0.306 &0.493 &0.523 &0.319 &0.564 &0.686 \\
R34-INT4 & 800 &0.284 &0.457 &0.487 &0.284 &0.524 &0.647 \\
\hdashline
R18-FP32 & 800 &0.288 &0.464 &0.495 &0.297 &0.529 &0.652 \\
R18-INT4 & 800 &0.268 &0.433 &0.461 &0.269 &0.491 &0.621 \\
\hdashline
MN2-FP32 & 600 &0.267 &0.441 &0.470 &0.283 &0.492 &0.615 \\
MN2-INT4 & 600 &0.253 &0.417 &0.445 &0.256 &0.468 &0.596 \\
\bottomrule
\end{tabular}
\end{subtable}
\end{table}
\begin{table}[p]
\centering
\caption{使用不同主干网络的二阶目标检测模型 Faster RCNN FQN 在 MS COCO 数据集上的实验结果。与表~\ref{tab::fqn::retina_coco} 一致,表格中以 -FP32 结尾的数据表示作为基准的全精度模型的实验结果,以 -INT4 结尾的数据表示模型参数和激活数值精度被量化至 4-bit 的实验结果。注意由于 GPU 显存限制,训练 MobileNet-v2 模型时,输入图片短边尺寸为 600 像素。}
\label{tab::fqn::faster_rcnn_coco}
\begin{subtable}[t]{\columnwidth}
\centering