-
Notifications
You must be signed in to change notification settings - Fork 9.1k
/
Copy pathdeep_feedforward_networks.tex
1876 lines (1559 loc) · 130 KB
/
deep_feedforward_networks.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
% !Mode:: "TeX:UTF-8"
% Translator: Kai Li
\chapter{\glsentrytext{deep_feedforward_network}}
\label{chap:deep_feedforward_networks}
\firstgls{deep_feedforward_network},也叫作\firstgls{feedforward_neural_network}或者\firstall{MLP},是典型的深度学习模型。\gls{feedforward_network}的目标是近似某个函数$f^*$。
例如,对于分类器,$y = f^*(\Vx)$将输入$\Vx$映射到一个类别$y$。
\gls{feedforward_network}定义了一个映射$\Vy = f(\Vx; \Vtheta)$,并且学习参数$\Vtheta$的值,使它能够得到最佳的函数近似。
这种模型被称为\firstgls{feedforward}的,是因为信息流过$\Vx$的函数,流经用于定义$f$的中间计算过程,最终到达输出$\Vy$。
%这里的feedforward是翻译成前向的,还是前馈的?
在模型的输出和模型本身之间没有\firstgls{feedback}连接。
当前馈神经网络被扩展成包含\gls{feedback}连接时,它们被称为\firstgls{RNN},在\chapref{chap:sequence_modeling_recurrent_and_recursive_nets}介绍。
\gls{feedforward_network}对于机器学习的从业者是极其重要的。
它们是许多重要商业应用的基础。
例如,用于对照片中的对象进行识别的\gls{CNN}就是一种专门的\gls{feedforward_network}。
\gls{feedforward_network}是通往\gls{recurrent_network}之路的概念基石,后者在自然语言的许多应用中发挥着巨大作用。
\gls{feedforward_neural_network}被称作\firstgls{network}是因为它们通常用许多不同函数复合在一起来表示。
该模型与一个有向无环图相关联,而图描述了函数是如何复合在一起的。
例如,我们有三个函数$f^{(1)}, f^{(2)}$和$f^{(3)}$连接在一个链上以形成$f(\Vx) = f^{(3)}(f^{(2)}(f^{(1)}(\Vx)) )$。
这些链式结构是神经网络中最常用的结构。
在这种情况下,$f^{(1)}$被称为网络的\firstgls{first_layer},$f^{(2)}$被称为\firstgls{second_layer},以此类推。
链的全长称为模型的\firstgls{depth}。
正是因为这个术语才出现了``深度学习''这个名字。
\gls{feedforward_network}的最后一层被称为\firstgls{output_layer}。
在神经网络训练的过程中,我们让$f(\Vx)$去匹配$f^*(\Vx)$的值。
训练数据为我们提供了在不同训练点上取值的、含有噪声的$f^*(\Vx)$的近似实例。
每个样本$\Vx$都伴随着一个标签$y\approx f^*(\Vx)$。
训练样本直接指明了输出层在每一点$\Vx$上必须做什么;它必须产生一个接近$y$的值。
但是训练数据并没有直接指明其他层应该怎么做。
学习算法必须决定如何使用这些层来产生想要的输出,但是训练数据并没有说每个单独的层应该做什么。
相反,学习算法必须决定如何使用这些层来最好地实现$f^*$的近似。
因为训练数据并没有给出这些层中的每一层所需的输出,所以这些层被称为\firstgls{hidden_layer}。
% -- 163 --
最后,这些网络被称为\emph{神经网络}是因为它们或多或少地受到神经科学的启发。
网络中的每个\gls{hidden_layer}通常都是向量值的。这些\gls{hidden_layer}的维数决定了模型的\firstgls{width}。
向量的每个元素都可以被视为起到类似一个神经元的作用。
除了将层想象成向量到向量的单个函数,我们也可以把层想象成由许多并行操作的\firstgls{unit}组成,每个单元表示一个向量到标量的函数。
每个单元在某种意义上类似一个神经元,它接收的输入来源于许多其他的单元,并计算它自己的激活值。
使用多层向量值表示的想法来源于神经科学。
用于计算这些表示的函数$f^{(i)}(\Vx)$的选择,也或多或少地受到神经科学观测的指引,这些观测是关于生物神经元计算功能的。
然而,现代的神经网络研究受到更多的是来自许多数学和工程学科的指引,并且神经网络的目标并不是完美地给大脑建模。
我们最好将\gls{feedforward_neural_network}想成是为了实现统计\gls{generalization}而设计出的函数近似机,它偶尔从我们了解的大脑中提取灵感,但并不是大脑功能的模型。
一种理解\gls{feedforward_network}的方式是从线性模型开始,并考虑如何克服它的局限性。
线性模型,例如\gls{logistic_regression}和线性回归,是非常吸引人的,因为无论是通过闭解形式还是使用凸优化,它们都能高效且可靠地拟合。
线性模型也有明显的缺陷,那就是该模型的能力被局限在线性函数里,所以它无法理解任何两个输入变量间的相互作用。
为了扩展线性模型来表示$\Vx$的非线性函数,我们可以不把线性模型用于$\Vx$本身,而是用在一个变换后的输入$\phi(\Vx)$上,这里$\phi$是一个非线性变换。
同样,我们可以使用\secref{sec:support_vector_machines}中描述的\gls{kernel_trick},来得到一个基于隐含地使用$\phi$映射的非线性学习算法。
我们可以认为$\phi$提供了一组描述$\Vx$的特征,或者认为它提供了$\Vx$的一个新的表示。
% -- 164 --
剩下的问题就是如何选择映射$\phi$。
\begin{enumerate}
\item 其中一种选择是使用一个通用的$\phi$,例如无限维的$\phi$,它隐含地用在基于~\glssymbol{RBF}~核的\gls{kernel_machines}上。
如果$\phi(\Vx)$具有足够高的维数,我们总是有足够的能力来拟合训练集,但是对于测试集的\gls{generalization}往往不佳。
非常通用的特征映射通常只基于局部光滑的原则,并且没有将足够的先验信息进行编码来解决高级问题。
\item 另一种选择是手动地设计$\phi$。
在深度学习出现以前,这一直是主流的方法。
这种方法对于每个单独的任务都需要人们数十年的努力,从业者各自擅长特定的领域(如语音识别或计算机视觉),并且不同领域之间很难迁移(transfer)。
\item 深度学习的策略是去学习$\phi$。
在这种方法中,我们有一个模型$y = f(\Vx;\theta, \Vw) = \phi(\Vx; \theta)^\top \Vw$。
我们现在有两种参数:用于从一大类函数中学习$\phi$的参数$\Vtheta$,以及用于将$\phi(\Vx)$映射到所需的输出的参数$\Vw$。
这是\gls{deep_feedforward_network}的一个例子,其中$\phi$定义了一个\gls{hidden_layer}。
这是三种方法中唯一一种放弃了训练问题的凸性的,但是利大于弊。
在这种方法中,我们将表示参数化为$\phi(\Vx; \Vtheta)$,并且使用优化算法来寻找$\Vtheta$,使它能够得到一个好的表示。
如果我们想要的话,这种方法也可以通过使它变得高度通用以获得第一种方法的优点——我们只需使用一个非常广泛的函数族$\phi(\Vx; \Vtheta)$。
这种方法也可以获得第二种方法的优点。
人类专家可以将他们的知识编码进网络来帮助\gls{generalization},他们只需要设计那些他们期望能够表现优异的函数族$\phi(\Vx; \Vtheta)$即可。
这种方法的优点是人类设计者只需要寻找正确的函数族即可,而不需要去寻找精确的函数。
\end{enumerate}
这种通过学习特征来改善模型的一般化原则不仅仅适用于本章描述的\gls{feedforward_neural_network}。
它是深度学习中反复出现的主题,适用于全书描述的所有种类的模型。
\gls{feedforward_neural_network}是这个原则的应用,它学习从$\Vx$到$\Vy$的确定性映射并且没有反馈连接。
后面出现的其他模型会把这些原则应用到学习随机映射、学习带有反馈的函数以及学习单个向量的概率分布。
% -- 165 --
本章我们先从\gls{feedforward_network}的一个简单例子说起。
接着,我们讨论部署一个\gls{feedforward_network}所需的每个设计决策。
首先,训练一个\gls{feedforward_network}至少需要做和线性模型同样多的设计决策:选择一个优化模型、代价函数以及输出单元的形式。
我们先回顾这些基于梯度学习的基本知识,然后去面对那些只出现在\gls{feedforward_network}中的设计决策。
\gls{feedforward_network}已经引入了\gls{hidden_layer}的概念,这需要我们去选择用于计算\gls{hidden_layer}值的\firstgls{activation_function}。
我们还必须设计网络的结构,包括网络应该包含多少层、这些层应该如何连接,以及每一层包含多少单元。
在深度神经网络的学习中需要计算复杂函数的梯度。
我们给出\firstgls{back_propagation}算法和它的现代推广,它们可以用来高效地计算这些梯度。
最后,我们以某些历史观点来结束这一章。
\section{实例:学习XOR}
\label{sec:example_learning_xor}
为了使\gls{feedforward_network}的想法更加具体,我们首先从一个可以完整工作的\gls{feedforward_network}说起。
这个例子解决一个非常简单的任务:学习XOR函数。
XOR函数(``异或''逻辑)是两个二进制值$x_1$和$x_2$的运算。
当这些二进制值中恰好有一个为1时,XOR函数返回值为1。
其余情况下返回值为0。
XOR函数提供了我们想要学习的目标函数$y = f^*(\Vx)$。
我们的模型给出了一个函数$y=f(\Vx; \Vtheta)$并且我们的学习算法会不断调整参数$\Vtheta$来使得$f$尽可能接近$f^*$。
在这个简单的例子中,我们不会关心统计\gls{generalization}。
我们希望网络在这四个点$\SetX =\{[0, 0]^\top, [0, 1]^\top, [1, 0]^\top, [1, 1]^\top\}$上表现正确。
我们会用全部这四个点来训练我们的网络,唯一的挑战是拟合训练集。
我们可以把这个问题当作是回归问题,并使用\gls{mean_squared_error}损失函数。
我们选择这个损失函数是为了尽可能简化本例中用到的数学。
在应用领域,对于二进制数据建模时,\glssymbol{mean_squared_error}通常并不是一个合适的损失函数。
更加合适的方法将在\secref{sec:sigmoid_units_for_bernoulli_output_distributions}中讨论。
% -- 166 --
评估整个训练集上表现的~\glssymbol{mean_squared_error}~损失函数为
\begin{equation}
J(\Vtheta) = \frac{1}{4} \sum_{\Vx\in \SetX} (f^*(\Vx) - f(\Vx; \Vtheta))^2.
\end{equation}
我们现在必须要选择我们模型$f(\Vx; \Vtheta)$的形式。
假设我们选择一个线性模型,$\Vtheta$包含$\Vw$和$b$,那么我们的模型被定义成
\begin{equation}
f(\Vx; \Vw, b) = \Vx^\top \Vw + b.
\end{equation}
我们可以使用\gls{normal_equations}关于$\Vw$和$b$最小化$J(\Vtheta)$,来得到一个闭式解。
解\gls{normal_equations}以后,我们得到$\Vw = 0$以及$b = \frac{1}{2}$。
线性模型仅仅是在任意一点都输出0.5。
为什么会发生这种事?
\figref{fig:chap6_xor_space_gray}演示了线性模型为什么不能用来表示XOR函数。
解决这个问题的其中一种方法是使用一个模型来学习一个不同的特征空间,在这个空间上线性模型能够表示这个解。
% fig 6.1
\begin{figure}[!htb]
\ifOpenSource
\centerline{\includegraphics{figure.pdf}}
\else
\centerline{\includegraphics{Chapter6/figures/xor_space_gray}}
\fi
\captionsetup{singlelinecheck=off}
\caption{通过学习一个表示来解决XOR问题。
图上的粗体数字标明了学得的函数必须在每个点输出的值。
\emph{(左)}直接应用于原始输入的线性模型不能实现XOR函数。
当$x_1 = 0$时,模型的输出必须随着$x_2$的增大而增大。
当$x_1 = 1$时,模型的输出必须随着$x_2$的增大而减小。
线性模型必须对$x_2$使用固定的系数$w_2$。
因此,线性模型不能使用$x_1$的值来改变$x_2$的系数,从而不能解决这个问题。
\emph{(右)}在由神经网络提取的特征表示的变换空间中,线性模型现在可以解决这个问题了。
在我们的示例解决方案中,输出必须为1的两个点折叠到了特征空间中的单个点。
换句话说,非线性特征将$\Vx = [1, 0]^\top$和$\Vx = [0, 1]^\top$都映射到了特征空间中的单个点$\Vh = [1, 0]^\top$。
线性模型现在可以将函数描述为$h_1$增大和$h_2$减小。
在该示例中,学习特征空间的动机仅仅是使得模型的能力更大,使得它可以拟合训练集。
在更现实的应用中,学习的表示也可以帮助模型\gls{generalization}。}
\label{fig:chap6_xor_space_gray}
\end{figure}
具体来说,我们这里引入一个非常简单的\gls{feedforward_neural_network},它有一层\gls{hidden_layer}并且\gls{hidden_layer}中包含两个单元。
见\figref{fig:chap6_example_mlp}中对该模型的解释。
这个\gls{feedforward_network}有一个通过函数$f^{(1)}(\Vx;\MW, \Vc)$计算得到的\gls{hidden_unit}的向量$\Vh$。
这些\gls{hidden_unit}的值随后被用作第二层的输入。
第二层就是这个网络的输出层。
输出层仍然只是一个线性回归模型,只不过现在它作用于$\Vh$而不是$\Vx$。
网络现在包含链接在一起的两个函数:$\Vh=f^{(1)}(\Vx; \MW, \Vc)$和$y = f^{(2)}(\Vh; \Vw, b)$,完整的模型是$f(\Vx; \MW, \Vc, \Vw, b) = f^{(2)}(f^{(1)}(\Vx))$。
% fig 6.2
\begin{figure}[!htb]
\ifOpenSource
\centerline{\includegraphics{figure.pdf}}
\else
\centerline{\includegraphics{Chapter6/figures/example_mlp}}
\fi
\captionsetup{singlelinecheck=off}
\caption{使用两种不同样式绘制的\gls{feedforward_network}的示例。
具体来说,这是我们用来解决XOR问题的\gls{feedforward_network}。
它有单个\gls{hidden_layer},包含两个单元。
\emph{(左)}在这种样式中,我们将每个单元绘制为图中的一个节点。
这种风格是清楚而明确的,但对于比这个例子更大的网络,它可能会消耗太多的空间。
\emph{(右)}在这种样式中,我们将表示每一层激活的整个向量绘制为图中的一个节点。
这种样式更加紧凑。
有时,我们对图中的边使用参数名进行注释,这些参数是用来描述两层之间的关系的。
这里,我们用矩阵$\MW$描述从$\Vx$到$\Vh$的映射,用向量$\Vw$描述从$\Vh$到$y$的映射。
当标记这种图时,我们通常省略与每个层相关联的截距参数。}
\label{fig:chap6_example_mlp}
\end{figure}
$f^{(1)}$应该是哪种函数?线性模型到目前为止都表现不错,让$f^{(1)}$也是线性的似乎很有诱惑力。
可惜的是,如果$f^{(1)}$是线性的,那么\gls{feedforward_network}作为一个整体对于输入仍然是线性的。
暂时忽略截距项,假设$f^{(1)}(\Vx)= \MW^\top \Vx$并且$f^{(2)}(\Vh)=\Vh^\top \Vw$,那么$f(\Vx) = \Vw^\top\MW^\top \Vx$。
我们可以将这个函数重新表示成$f(\Vx) = \Vx^\top\Vw'$其中$\Vw' = \MW\Vw$。
% -- 167 --
显然,我们必须用非线性函数来描述这些特征。
大多数神经网络通过仿射变换之后紧跟着一个被称为激活函数的固定非线性函数来实现这个目标,其中仿射变换由学得的参数控制。
我们这里使用这种策略,定义$\Vh=g(\MW^\top \Vx+\Vc)$,其中$\MW$是线性变换的权重矩阵,$\Vc$是偏置。
此前,为了描述线性回归模型,我们使用权重向量和一个标量的偏置参数来描述从输入向量到输出标量的仿射变换。
现在,因为我们描述的是向量$\Vx$到向量$\Vh$的仿射变换,所以我们需要一整个向量的偏置参数。
激活函数$g$通常选择对每个元素分别起作用的函数,有$h_i =g(\Vx^\top \MW_{:, i} + c_i)$。
在现代神经网络中,默认的推荐是使用由激活函数$g(z)=\max\{0, z\}$定义的\firstgls{ReLU}或者称为~\glssymbol{ReLU}~\citep{Jarrett-ICCV2009-small,Nair-2010-small,Glorot+al-AI-2011-small},如\figref{fig:chap6_relu_color}所示。
% fig 6.3
\begin{figure}[!htb]
\ifOpenSource
\centerline{\includegraphics{figure.pdf}}
\else
\centerline{\includegraphics{Chapter6/figures/relu_color}}
\fi
\caption{\gls{rectified_linear}激活函数。
该激活函数是被推荐用于大多数\gls{feedforward_neural_network}的默认激活函数。
将此函数用于线性变换的输出将产生非线性变换。 然而,函数仍然非常接近线性,在这种意义上它是具有两个线性部分的分段线性函数。
由于\gls{ReLU}几乎是线性的,因此它们保留了许多使得线性模型易于使用基于梯度的方法进行优化的属性。 它们还保留了许多使得线性模型能够\gls{generalization}良好的属性。 计算机科学的一个通用原则是,我们可以从最小的组件构建复杂的系统。
就像图灵机的内存只需要能够存储0或1的状态,我们可以从\gls{rectified_linear}函数构建一个\gls{universal_function_approximator}。}
\label{fig:chap6_relu_color}
\end{figure}
我们现在可以指明我们的整个网络是
\begin{equation}
f(\Vx; \MW, \Vc, \Vw, b) = \Vw^\top \max\{ 0, \MW^\top \Vx + \Vc \} +b.
\end{equation}
% -- 168 --
% -- 169 --
我们现在可以给出XOR问题的一个解。
令
\begin{align}
\MW &= \begin{bmatrix}
1 & 1\\
1 & 1
\end{bmatrix},\\
\Vc &= \begin{bmatrix}
0\\
-1
\end{bmatrix},\\
\Vw &= \begin{bmatrix}
1\\
-2
\end{bmatrix},
\end{align}
以及$b=0$。
我们现在可以了解这个模型如何处理一批输入。
令$\MX$表示设计矩阵,它包含二进制输入空间中全部的四个点,每个样本占一行,那么矩阵表示为:
\begin{equation}
\MX = \begin{bmatrix}
0 & 0\\
0 & 1\\
1 & 0\\
1 & 1
\end{bmatrix}.
\end{equation}
神经网络的第一步是将输入矩阵乘以第一层的权重矩阵:
\begin{equation}
\MX\MW = \begin{bmatrix}
0 & 0\\
1 & 1\\
1 & 1\\
2 & 2
\end{bmatrix}.
\end{equation}
然后,我们加上偏置向量$\Vc$,得到
\begin{equation}
\begin{bmatrix}
0 & -1\\
1 & 0\\
1 & 0\\
2 & 1
\end{bmatrix}.
\end{equation}
在这个空间中,所有的样本都处在一条斜率为1的直线上。
当我们沿着这条直线移动时,输出需要从0升到1,然后再降回0。
线性模型不能实现这样一种函数。
为了用$\Vh$对每个样本求值,我们使用\gls{rectified_linear_transformation}:
\begin{equation}
\begin{bmatrix}
0 & 0\\
1 & 0\\
1 & 0\\
2 & 1
\end{bmatrix}.
\end{equation}
% -- 170 --
这个变换改变了样本间的关系。它们不再处于同一条直线上了。
如\figref{fig:chap6_xor_space_gray}所示,它们现在处在一个可以用线性模型解决的空间上。
我们最后乘以一个权重向量$\Vw$:
\begin{equation}
\begin{bmatrix}
0\\
1\\
1\\
0
\end{bmatrix}.
\end{equation}
神经网络对这一批次中的每个样本都给出了正确的结果。
在这个例子中,我们简单地指定了解决方案,然后说明它得到的误差为零。
在实际情况中,可能会有数十亿的模型参数以及数十亿的训练样本,所以不能像我们这里做的那样进行简单地猜解。
与之相对的,基于梯度的优化算法可以找到一些参数使得产生的误差非常小。
我们这里给出的XOR问题的解处在损失函数的全局最小点,所以梯度下降算法可以收敛到这一点。
梯度下降算法还可以找到XOR问题一些其他的等价解。
梯度下降算法的收敛点取决于参数的初始值。
在实践中,梯度下降通常不会找到像我们这里给出的那种干净的、容易理解的、整数值的解。
\section{基于梯度的学习}
\label{sec:gradient_based_learning}
设计和训练神经网络与使用梯度下降训练其他任何机器学习模型并没有太大不同。
在\secref{sec:building_a_machine_learning_algorithm}中,我们描述了如何通过指定一个优化过程、代价函数和一个模型族来构建一个机器学习算法。
我们到目前为止看到的线性模型和神经网络的最大区别,在于神经网络的非线性导致大多数我们感兴趣的\gls{cost_function}都变得非凸。
这意味着神经网络的训练通常使用迭代的、基于梯度的优化,仅仅使得代价函数达到一个非常小的值;而不是像用于训练线性回归模型的线性方程求解器,或者用于训练\gls{logistic_regression}或~\glssymbol{SVM}~的凸优化算法那样保证全局收敛。
凸优化从任何一种初始参数出发都会收敛(理论上如此——在实践中也很鲁棒但可能会遇到数值问题)。
用于非凸损失函数的随机梯度下降没有这种收敛性保证,并且对参数的初始值很敏感。
对于\gls{feedforward_neural_network},将所有的权重值初始化为小随机数是很重要的。
偏置可以初始化为零或者小的正值。
这种用于训练\gls{feedforward_neural_network}以及几乎所有深度模型的迭代的基于梯度的优化算法会在\chapref{chap:optimization_for_training_deep_models}详细介绍,参数初始化会在\secref{sec:parameter_initialization_strategies}中具体说明。
就目前而言,只需要懂得,训练算法几乎总是基于使用梯度来使得代价函数下降的各种方法即可。
一些特别的算法是对梯度下降思想的改进和提纯(在\secref{sec:gradient_based_optimization}中介绍)还有一些更特别的,大多数是对随机梯度下降算法的改进(在\secref{sec:stochastic_gradient_descent_chap5}中介绍)。
% -- 171 --
我们当然也可以用梯度下降来训练诸如线性回归和\gls{SVM}之类的模型,并且事实上当训练集相当大时这是很常用的。
从这点来看,训练神经网络和训练其他任何模型并没有太大区别。
计算梯度对于神经网络会略微复杂一些,但仍然可以很高效而精确地实现。
\secref{sec:back_propagation_and_other_differentiation_algorithms}将会介绍如何用\gls{BP}算法以及它的现代扩展算法来求得梯度。
和其他的机器学习模型一样,为了使用基于梯度的学习方法我们必须选择一个代价函数,并且我们必须选择如何表示模型的输出。
现在,我们重温这些设计上的考虑,并且特别强调神经网络的情景。
\subsection{代价函数}
\label{sec:cost_functions}
深度神经网络设计中的一个重要方面是代价函数的选择。
幸运的是,神经网络的代价函数或多或少是和其他的参数模型例如线性模型的代价函数相同的。
在大多数情况下, 我们的参数模型定义了一个分布$p(\Vy\mid\Vx;\Vtheta)$并且我们简单地使用最大似然原理。
这意味着我们使用训练数据和模型预测间的\gls{cross_entropy}作为代价函数。
有时,我们使用一个更简单的方法,不是预测$\Vy$的完整概率分布,而是仅仅预测在给定$\Vx$的条件下$\Vy$的某种统计量。
某些专门的损失函数允许我们来训练这些估计量的预测器。
用于训练神经网络的完整的代价函数,通常在我们这里描述的基本代价函数的基础上结合一个正则项。
我们已经在\secref{sec:regularization}中看到正则化应用到线性模型中的一些简单的例子。
用于线性模型的权重衰减方法也直接适用于深度神经网络,而且是最流行的正则化策略之一。
用于神经网络的更高级的正则化策略将在\chapref{chap:regularization_for_deep_learning}中讨论。
% -- 172 --
\subsubsection{使用最大似然学习条件分布}
\label{sec:learning_conditional_distributions_with_maximum_likelihood}
大多数现代的神经网络使用最大似然来训练。
这意味着代价函数就是负的对数似然,它与训练数据和模型分布间的\gls{cross_entropy}等价。
这个代价函数表示为
\begin{equation}
J(\Vtheta) = -\SetE_{\RVx, \RVy \sim \hat{p}_\text{data}} \log p_\text{model} (\Vy \mid \Vx).
\end{equation}
代价函数的具体形式随着模型而改变,取决于$\log p_\text{model}$的具体形式。
上述方程的展开形式通常会有一些项不依赖于模型的参数,我们可以舍去。
例如,正如我们在\secref{sec:the_task_t}中看到的,如果$p_\text{model}(\Vy\mid\Vx) = \CalN(\Vy;f(\Vx;\Vtheta), \MI)$,那么我们就重新得到了\gls{mean_squared_error}代价,
\begin{equation}
J(\theta) = \frac{1}{2} \SetE_{\RVx, \RVy \sim \hat{p}_\text{data}} || \Vy - f(\Vx; \Vtheta) ||^2 + \text{const},
\end{equation}
至少系数$\frac{1}{2}$和常数项不依赖于$\Vtheta$。
舍弃的常数是基于\gls{gaussian_distribution}的方差,在这种情况下我们选择不把它参数化。
之前,我们看到了对输出分布的最大似然估计和对线性模型\gls{mean_squared_error}的最小化之间的等价性,但事实上,这种等价性并不要求$f(\Vx; \Vtheta)$用于预测\gls{gaussian_distribution}的均值。
使用最大似然来导出代价函数的方法的一个优势是,它减轻了为每个模型设计代价函数的负担。
明确一个模型$p(\Vy\mid\Vx)$则自动地确定了一个代价函数$\log p(\Vy\mid\Vx)$。
贯穿神经网络设计的一个反复出现的主题是代价函数的梯度必须足够的大和具有足够的预测性,来为学习算法提供一个好的指引。
饱和(变得非常平)的函数破坏了这一目标,因为它们把梯度变得非常小。
这在很多情况下都会发生,因为用于产生\gls{hidden_unit}或者输出单元的输出的激活函数会饱和。
负的对数似然帮助我们在很多模型中避免这个问题。
很多输出单元都会包含一个指数函数,这在它的变量取绝对值非常大的负值时会造成饱和。
负对数似然代价函数中的对数函数消除了某些输出单元中的指数效果。
我们将会在\secref{sec:output_units}中讨论代价函数和输出单元的选择间的相互作用。
% -- 173 --
用于实现最大似然估计的\gls{cross_entropy}代价函数有一个不同寻常的特性,那就是当它被应用于实践中经常遇到的模型时,它通常没有最小值。
对于离散型输出变量,大多数模型以一种特殊的形式来参数化,即它们不能表示概率零和一,但是可以无限接近。
\gls{logistic_regression}是其中一个例子。
对于实值的输出变量,如果模型可以控制输出分布的密度(例如,通过学习\gls{gaussian_output_distribution}的方差参数),那么它可能对正确的训练集输出赋予极其高的密度,这将导致\gls{cross_entropy}趋向负无穷。
\chapref{chap:regularization_for_deep_learning}中描述的正则化技术提供了一些不同的方法来修正学习问题,使得模型不会通过这种方式来获得无限制的收益。
\subsubsection{学习条件统计量}
\label{sec:learning_conditional_statistics}
有时我们并不是想学习一个完整的概率分布$p(\Vy\mid\Vx; \Vtheta)$,而仅仅是想学习在给定$\Vx$时$\Vy$的某个条件统计量。
例如,我们可能有一个预测器$f(\Vx; \Vtheta)$,我们想用它来预测$\Vy$的均值。
如果我们使用一个足够强大的神经网络,我们可以认为这个神经网络能够表示一大类函数中的任何一个函数$f$,这个类仅仅被一些特征所限制,例如连续性和有界,而不是具有特殊的参数形式。
从这个角度来看,我们可以把代价函数看作是一个\firstgls{functional}而不仅仅是一个函数。
泛函是函数到实数的映射。我们因此可以将学习看作是选择一个函数而不仅仅是选择一组参数。
我们可以设计代价泛函在我们想要的某些特殊函数处取得最小值。
例如,我们可以设计一个代价泛函,使它的最小值处于一个特殊的函数上,这个函数将$\Vx$映射到给定$\Vx$时$\Vy$的期望值。
对函数求解优化问题需要用到\firstgls{calculus_of_variations}这个数学工具,我们将在\secref{sec:calculus_of_variations}中讨论。
理解\gls{calculus_of_variations}对于理解本章的内容不是必要的。
目前,只需要知道\gls{calculus_of_variations}可以被用来导出下面的两个结果。
% -- 174 --
我们使用\gls{calculus_of_variations}导出的第一个结果是解优化问题
\begin{equation}
f^* = \underset{f}{\argmin} \ \SetE_{\RVx, \RVy \sim p_\text{data}} ||\Vy-f(\Vx)||^2
\end{equation}
得到
\begin{equation}
f^*(\Vx) = \SetE_{\RVy\sim p_\text{data}(\Vy|\Vx)} [\Vy],
\end{equation}
要求这个函数处在我们要优化的类里。
换句话说,如果我们能够用无穷多的、来源于真实的数据生成分布的样本进行训练,最小化\gls{mean_squared_error}代价函数将得到一个函数,它可以用来对每个$\Vx$的值预测出$\Vy$的均值。
不同的代价函数给出不同的统计量。
第二个使用\gls{calculus_of_variations}得到的结果是
\begin{equation}
f^* = \underset{f}{\argmin} \ \SetE_{\RVx, \RVy \sim p_\text{data}} ||\Vy - f(\Vx)||_1
\end{equation}
将得到一个函数可以对每个$\Vx$预测$\Vy$取值的\emph{中位数},只要这个函数在我们要优化的函数族里。
这个代价函数通常被称为\firstgls{mean_absolute_error}。
可惜的是,\gls{mean_squared_error}和\gls{mean_absolute_error}在使用基于梯度的优化方法时往往成效不佳。
一些饱和的输出单元当结合这些代价函数时会产生非常小的梯度。
这就是为什么\gls{cross_entropy}代价函数比\gls{mean_squared_error}或者\gls{mean_absolute_error}更受欢迎的原因之一了,即使是在没必要估计整个$p(\Vy\mid\Vx)$分布时。
\subsection{输出单元}
\label{sec:output_units}
代价函数的选择与输出单元的选择紧密相关。
大多数时候,我们简单地使用数据分布和模型分布间的\gls{cross_entropy}。
选择如何表示输出决定了\gls{cross_entropy}函数的形式。
任何可用作输出的神经网络单元,也可以被用作\gls{hidden_unit}。
这里,我们着重讨论将这些单元用作模型输出时的情况,不过原则上它们也可以在内部使用。
我们将在\secref{sec:hidden_units}中重温这些单元,并且给出当它们被用作\gls{hidden_unit}时一些额外的细节。
在本节中,我们假设\gls{feedforward_network}提供了一组定义为$\Vh=f(\Vx;\Vtheta)$的隐藏特征。
输出层的作用是随后对这些特征进行一些额外的变换来完成整个网络必须完成的任务。
% -- 175 --
\subsubsection{用于\glsentrytext{gaussian_output_distribution}的线性单元}
\label{sec:linear_units_for_gaussian_output_distributions}
一种简单的输出单元是基于仿射变换的输出单元,仿射变换不具有非线性。
这些单元往往被直接称为线性单元。
给定特征$\Vh$,线性输出单元层产生一个向量$\hat{\Vy} = \MW^\top \Vh+\Vb$。
线性输出层经常被用来产生条件\gls{gaussian_distribution}的均值:
\begin{equation}
p(\Vy\mid\Vx) = \CalN(\Vy; \hat{\Vy}, \MI ).
\end{equation}
最大化其对数似然此时等价于最小化\gls{mean_squared_error}。
最大似然框架也使得学习\gls{gaussian_distribution}的协方差矩阵更加容易,或更容易地使\gls{gaussian_distribution}的协方差矩阵作为输入的函数。
然而,对于所有输入,协方差矩阵都必须被限定成一个正定矩阵。
线性输出层很难满足这种限定,所以通常使用其他的输出单元来对协方差参数化。
对协方差建模的方法将在\secref{sec:other_output_types}中简要介绍。
因为线性模型不会饱和,所以它们易于采用基于梯度的优化算法,甚至可以使用其他多种优化算法。
\subsubsection{用于\glsentrytext{bernoulli_output_distribution}的\glsentrytext{sigmoid}单元}
\label{sec:sigmoid_units_for_bernoulli_output_distributions}
许多任务需要预测二值型变量$y$的值。
具有两个类的分类问题可以归结为这种形式。
此时最大似然的方法是定义$y$在$\Vx$条件下的~\gls{bernoulli_distribution}。
\gls{bernoulli_distribution}仅需单个参数来定义。
神经网络只需要预测$P(y =1\mid\Vx)$即可。
为了使这个数是有效的概率,它必须处在区间$[0, 1]$中。
为满足该约束条件需要一些细致的设计工作。
假设我们打算使用线性单元,并且通过阈值来限制它成为一个有效的概率:
\begin{equation}
P(y=1 \mid \Vx) = \max \left \{ 0, \min \{1, \Vw^\top \Vh+b \} \right \}.
\end{equation}
这的确定义了一个有效的条件概率分布,但我们无法使用梯度下降来高效地训练它。
当$\Vw^\top \Vh+b$处于单位区间外时,模型的输出对其参数的梯度都将为$\bm{0}$。
梯度为$\bm{0}$通常是有问题的,因为学习算法对于如何改善相应的参数不再具有指导意义。
% -- 176 --
相反,最好是使用一种新的方法来保证无论何时模型给出了错误的答案时,总能有一个较大的梯度。
这种方法是基于使用~\gls{sigmoid}~输出单元结合最大似然来实现的。
\gls{sigmoid}~输出单元定义为
\begin{equation}
\hat{y} = \sigma \left (\Vw^\top \Vh + b \right ),
\end{equation}
这里$\sigma$是\secref{sec:useful_properties_of_common_functions}中介绍的~\gls{logistic_sigmoid}~函数。
我们可以认为~\gls{sigmoid}~输出单元具有两个部分。
首先,它使用一个线性层来计算$z=\Vw^\top \Vh+b$。
接着,它使用~\gls{sigmoid}~激活函数将$z$转化成概率。
我们暂时忽略对于$\Vx$的依赖性,只讨论如何用$z$的值来定义$y$的概率分布。
\gls{sigmoid}~可以通过构造一个非归一化(和不为1)的概率分布$\tilde{P}(y)$来得到。
我们可以随后除以一个合适的常数来得到有效的概率分布。
如果我们假定非归一化的对数概率对$y$ 和$z$是线性的,可以对它取指数来得到非归一化的概率。
我们然后对它归一化,可以发现这服从~\gls{bernoulli_distribution},该分布受$z$的~\gls{sigmoid}~变换控制:
\begin{align}
\log \tilde{P}(y) &= yz,\\
\tilde{P}(y) &= \exp(yz),\\
P(y) &= \frac{\exp(yz)}{\sum_{y' = 0}^1 \exp(y' z)},\\
P(y) &= \sigma((2y-1)z).
\end{align}
基于指数和归一化的概率分布在统计建模的文献中很常见。
用于定义这种二值型变量分布的变量$z$被称为\firstgls{logit}。
% -- 177 --
这种在对数空间里预测概率的方法可以很自然地使用最大似然学习。
因为用于最大似然的代价函数是$-\log P(y\mid\Vx)$,代价函数中的log抵消了~\gls{sigmoid}~中的exp。
如果没有这个效果,\gls{sigmoid}~的饱和性会阻止基于梯度的学习做出好的改进。
我们使用最大似然来学习一个由~\gls{sigmoid}~参数化的~\gls{bernoulli_distribution},它的损失函数为
\begin{align}
J(\Vtheta) &= -\log P(y\mid\Vx)\\
&= -\log \sigma ((2y-1)z)\\
&= \zeta((1-2y)z).
\end{align}
这个推导使用了\secref{sec:useful_properties_of_common_functions}中的一些性质。
通过将损失函数写成~\gls{softplus_function}的形式,我们可以看到它仅仅在$(1-2y)z$取绝对值非常大的负值时才会饱和。
因此饱和只会出现在模型已经得到正确答案时——当$y=1$且$z$取非常大的正值时,或者$y=0$且$z$取非常小的负值时。
当$z$的符号错误时,\gls{softplus_function}的变量$(1-2y)z$可以简化为$|z|$。
当$|z|$变得很大并且$z$的符号错误时,\gls{softplus_function}渐近地趋向于它的变量$|z|$。
对$z$求导则渐近地趋向于$\text{sign}(z)$,所以,对于极限情况下极度不正确的$z$,\gls{softplus_function}完全不会收缩梯度。
这个性质很有用,因为它意味着基于梯度的学习可以很快地改正错误的$z$。
当我们使用其他的损失函数,例如\gls{mean_squared_error}之类的,损失函数会在$\sigma(z)$饱和时饱和。
\gls{sigmoid}~激活函数在$z$取非常小的负值时会饱和到0,当$z$取非常大的正值时会饱和到1。
这种情况一旦发生,梯度会变得非常小以至于不能用来学习,无论此时模型给出的是正确还是错误的答案。
因此,最大似然几乎总是训练~\gls{sigmoid}~输出单元的优选方法。
理论上,\gls{sigmoid}~的对数总是确定和有限的,因为~\gls{sigmoid}~的返回值总是被限制在开区间$(0, 1)$上,而不是使用整个闭区间$[0, 1]$的有效概率。
在软件实现时,为了避免数值问题,最好将负的对数似然写作$z$的函数,而不是$\hat{y}=\sigma(z)$的函数。
如果~\gls{sigmoid}~函数下溢到零,那么之后对$\hat{y}$取对数会得到负无穷。
\subsubsection{用于
\glsentrytext{multinoulli_output_distribution}的softmax单元}
\label{sec:softmax_units_for_multinoulli_output_distributions}
任何时候当我们想要表示一个具有$n$个可能取值的离散型随机变量的分布时,我们都可以使用softmax函数。
它可以看作是~\gls{sigmoid}~函数的扩展,其中~\gls{sigmoid}~函数用来表示二值型变量的分布。
% -- 178 --
softmax函数最常用作分类器的输出,来表示$n$个不同类上的概率分布。
比较少见的是,softmax函数可以在模型内部使用,例如如果我们想要在某个内部变量的$n$个不同选项中进行选择。
在二值型变量的情况下,我们希望计算一个单独的数
\begin{equation}
\hat{y} = P(y=1\mid\Vx).
\end{equation}
因为这个数需要处在0和1之间,并且我们想要让这个数的对数可以很好地用于对数似然的基于梯度的优化,我们选择去预测另外一个数$z=\log \hat{P}(y=1\mid\Vx)$。
对其指数化和归一化,我们就得到了一个由~\gls{sigmoid}~函数控制的~\gls{bernoulli_distribution}。
为了推广到具有$n$个值的离散型变量的情况,我们现在需要创造一个向量$\hat{\Vy}$,它的每个元素是$\hat{y}_i = P(y=i\mid\Vx)$。
我们不仅要求每个$\hat{y}_i$元素介于0和1之间,还要使得整个向量的和为1,使得它表示一个有效的概率分布。
用于~\gls{bernoulli_distribution}的方法同样可以推广到~\gls{multinoulli_distribution}。
首先,线性层预测了未归一化的对数概率:
\begin{equation}
\Vz = \MW^\top \Vh+\Vb,
\end{equation}
其中$z_i=\log \hat{P}(y=i\mid\Vx)$。
softmax函数然后可以对$z$指数化和归一化来获得需要的$\hat{\Vy}$。
最终,softmax函数的形式为
\begin{equation}
\text{softmax}(\Vz)_i = \frac{\exp(z_i)}{\sum_j \exp(z_j)}.
\end{equation}
和~\gls{logistic_sigmoid}一样,当使用最大化对数似然训练softmax来输出目标值$\RSy$时,使用指数函数工作地非常好。
这种情况下,我们想要最大化$\log P(\RSy =i; \Vz)=\log \text{softmax}(\Vz)_i$。
将softmax定义成指数的形式是很自然的因为对数似然中的log可以抵消softmax中的exp:
\begin{equation}
\log \text{softmax}(\Vz)_i = z_i - \log \sum_j \exp(z_j).
\label{eq:6.30}
\end{equation}
% -- 179 --
\eqnref{eq:6.30}中的第一项表示输入$z_i$总是对代价函数有直接的贡献。
因为这一项不会饱和,所以即使$z_i$对\eqnref{eq:6.30}的第二项的贡献很小,学习依然可以进行。
当最大化对数似然时,第一项鼓励$z_i$被推高,而第二项则鼓励所有的$\Vz$被压低。
为了对第二项$\log \sum_j \exp(z_j)$有一个直观的理解,注意到这一项可以大致近似为$\max_j z_j$。
这种近似是基于对任何明显小于$\max_j z_j$的$z_k$,$\exp(z_k)$都是不重要的。
我们能从这种近似中得到的直觉是,负对数似然代价函数总是强烈地惩罚最活跃的不正确预测。
如果正确答案已经具有了softmax的最大输入,那么$-z_i$项和$\log\sum_j \exp(z_j) \approx \max_j z_j = z_i$项将大致抵消。
这个样本对于整体训练代价贡献很小,这个代价主要由其他未被正确分类的样本产生。
到目前为止我们只讨论了一个例子。
总体来说,未正则化的最大似然会驱动模型去学习一些参数,而这些参数会驱动softmax函数来预测在训练集中观察到的每个结果的比率:
\begin{equation}
\text{softmax}(\Vz(\Vx; \Vtheta))_i \approx \frac{\sum_{j=1}^m \bm{1}_{y^{(j)}=i, \Vx^{(j)} = \Vx} }{ \sum_{j=1}^{m} \bm{1}_{\Vx^{(j)} = \Vx} }.
\end{equation}
因为最大似然是一致的估计量,所以只要模型族能够表示训练的分布,这就能保证发生。
在实践中,有限的模型能力和不完美的优化将意味着模型只能近似这些比率。
除了对数似然之外的许多目标函数对softmax函数不起作用。
具体来说,那些不使用对数来抵消softmax中的指数的目标函数,当指数函数的变量取非常小的负值时会造成梯度消失,从而无法学习。
特别是,平方误差对于softmax单元来说是一个很差的损失函数,即使模型做出高度可信的不正确预测,也不能训练模型改变其输出\citep{Bridle90}。
要理解为什么这些损失函数可能失败,我们需要检查softmax函数本身。
像~\gls{sigmoid}~一样,softmax激活函数可能会饱和。
\gls{sigmoid}~函数具有单个输出,当它的输入极端负或者极端正时会饱和。
对于softmax的情况,它有多个输出值。
当输入值之间的差异变得极端时,这些输出值可能饱和。
当softmax饱和时,基于softmax的许多代价函数也饱和,除非它们能够转化饱和的激活函数。
% -- 180 --
为了说明softmax函数对于输入之间差异的响应,观察到当对所有的输入都加上一个相同常数时softmax的输出不变:
\begin{equation}
\text{softmax}(\Vz) = \text{softmax}(\Vz+c).
\end{equation}
使用这个性质,我们可以导出一个数值方法稳定的softmax函数的变体:
\begin{equation}
\text{softmax}(\Vz) = \text{softmax}(\Vz- \max_i z_i).
\end{equation}
变换后的形式允许我们在对softmax函数求值时只有很小的数值误差,即使是当$z$包含极正或者极负的数时。
观察softmax数值稳定的变体,可以看到softmax函数由它的变量偏离$\max_i z_i$的量来驱动。
当其中一个输入是最大($z_i = \max_i z_i$)并且$z_i$远大于其他的输入时,相应的输出$\text{softmax}(\Vz)_i$会饱和到1。
当$z_i$不是最大值并且最大值非常大时,相应的输出$\text{softmax}(\Vz)_i$也会饱和到0。
这是~\gls{sigmoid}~单元饱和方式的一般化,并且如果损失函数不被设计成对其进行补偿,那么也会造成类似的学习困难。
softmax函数的变量$\Vz$可以通过两种方式产生。
最常见的是简单地使神经网络中softmax之前的层输出$\Vz$的每个元素,就像先前描述的使用线性层$\Vz={W}^\top\Vh+\Vb$。
虽然很直观,但这种方法是对分布的过度参数化。
$n$个输出总和必须为1的约束意味着只有$n-1$个参数是必要的;第$n$个概率值可以通过1减去前面$n-1$个概率来获得。
因此,我们可以强制要求$\Vz$的一个元素是固定的。
例如,我们可以要求$z_n=0$。
事实上,这正是~\gls{sigmoid}~单元所做的。
定义$P(y=1\mid\Vx)=\sigma(z)$等价于用二维的$\Vz$以及$z_1=0$来定义$P(y=1\mid\Vx)=\text{softmax}(\Vz)_1$。
无论是$n-1$个变量还是$n$个变量的方法,都描述了相同的概率分布,但会产生不同的学习机制。
在实践中,无论是过度参数化的版本还是限制的版本都很少有差别,并且实现过度参数化的版本更为简单。
从神经科学的角度看,有趣的是认为softmax是一种在参与其中的单元之间形成竞争的方式:softmax输出总是和为1,所以一个单元的值增加必然对应着其他单元值的减少。
这与被认为存在于皮质中相邻神经元间的侧抑制类似。
在极端情况下(当最大的$a_i$和其他的在幅度上差异很大时),它变成了\firstgls{winner_take_all}的形式(其中一个输出接近1,其他的接近0)。
``softmax''的名称可能会让人产生困惑。
这个函数更接近于argmax函数而不是max函数。
``soft''这个术语来源于softmax函数是连续可微的。
``argmax''函数的结果表示为一个\gls{one_hot}向量(只有一个元素为1,其余元素都为0的向量),不是连续和可微的。
softmax函数因此提供了argmax的``软化''版本。max函数相应的软化版本是$\text{softmax}(\Vz)^\top \Vz$。
可能最好是把softmax函数称为``softargmax'',但当前名称已经是一个根深蒂固的习惯了。
% -- 181 --
\subsubsection{其他的输出类型}
\label{sec:other_output_types}
之前描述的线性、\gls{sigmoid}~和softmax输出单元是最常见的。
神经网络可以推广到我们希望的几乎任何种类的输出层。
最大似然原则给如何为几乎任何种类的输出层设计一个好的代价函数提供了指导。
一般的,如果我们定义了一个条件分布$p(\Vy\mid\Vx; \Vtheta)$,最大似然原则建议我们使用$-\log p(\Vy\mid \Vx;\Vtheta)$作为代价函数。
一般来说,我们可以认为神经网络表示函数$f(\Vx;\Vtheta)$。
这个函数的输出不是对$\Vy$值的直接预测。
相反,$f(\Vx;\Vtheta)=\Vomega$提供了$y$分布的参数。
我们的损失函数就可以表示成$-\log p(\RVy; \Vomega(\Vx))$。
例如,我们想要学习在给定$\RVx$时,$\RVy$的条件\gls{gaussian_distribution}的方差。
简单情况下,方差$\sigma^2$是一个常数,此时有一个解析表达式,这是因为方差的最大似然估计量仅仅是观测值$\RVy$与它们的期望值的差值的平方平均。
一种计算上代价更加高但是不需要写特殊情况代码的方法是简单地将方差作为分布$p(\RVy\mid\Vx)$的其中一个属性,这个分布由$\Vomega=f(\Vx;\Vtheta)$控制。
负对数似然$-\log p(\Vy;\Vomega(\Vx))$将为代价函数提供一个必要的合适项来使我们的优化过程可以逐渐地学到方差。
在标准差不依赖于输入的简单情况下,我们可以在网络中创建一个直接复制到$\Vomega$中的新参数。
这个新参数可以是$\sigma$本身,或者可以是表示$\sigma^2$的参数$v$,或者可以是表示$\frac{1}{\sigma^2}$的参数$\beta$,取决于我们怎样对分布参数化。
我们可能希望模型对不同的$\RVx$值预测出$\RVy$不同的方差。
这被称为\firstgls{heteroscedastic}模型。
在异方差情况下,我们简单地把方差指定为$f(\RVx;\Vtheta)$其中一个输出值。
实现它的典型方法是使用精度而不是方差来表示\gls{gaussian_distribution},就像\eqnref{eq:3.22}所描述的。
在多维变量的情况下,最常见的是使用一个对角精度矩阵
\begin{equation}
\text{diag}(\Vbeta).
\end{equation}
这个公式适用于梯度下降,因为由$\Vbeta$参数化的\gls{gaussian_distribution}的对数似然的公式仅涉及$\beta_i$的乘法和$\log \beta_i$的加法。
乘法、加法和对数运算的梯度表现良好。
相比之下,如果我们用方差来参数化输出,我们需要用到除法。
除法函数在零附近会变得任意陡峭。
虽然大梯度可以帮助学习,但任意大的梯度通常导致不稳定。
如果我们用标准差来参数化输出,对数似然仍然会涉及除法,并且还将涉及平方。
通过平方运算的梯度可能在零附近消失,这使得学习被平方的参数变得困难。
无论我们使用的是标准差,方差还是精度,我们必须确保\gls{gaussian_distribution}的协方差矩阵是正定的。
因为精度矩阵的特征值是协方差矩阵特征值的倒数,所以这等价于确保精度矩阵是正定的。
如果我们使用对角矩阵,或者是一个常数乘以单位矩阵\footnote{译者注:这里原文是``If we use a diagonal matrix, or a scalar times the diagonal matrix...''即``如果我们使用对角矩阵,或者是一个标量乘以对角矩阵...'',但一个标量乘以对角矩阵和对角矩阵没区别,结合上下文可以看出,这里原作者误把``identity''写成了``diagonal matrix'',因此这里采用``常数乘以单位矩阵''的译法。},那么我们需要对模型输出强加的唯一条件是它的元素都为正。
如果我们假设$\Va$是用于确定对角精度的模型的原始激活,那么可以用softplus 函数来获得正的精度向量:$\Vbeta=\Vzeta(\Va)$。
这种相同的策略对于方差或标准差同样适用,也适用于常数乘以单位阵的情况。
% -- 182 --
学习一个比对角矩阵具有更丰富结构的协方差或者精度矩阵是很少见的。
如果协方差矩阵是满的和有条件的,那么参数化的选择就必须要保证预测的协方差矩阵是正定的。
这可以通过写成$\VSigma(\Vx)=\MB(\Vx)\MB^\top (\Vx)$来实现,这里$\MB$是一个无约束的方阵。
如果矩阵是满秩的,那么一个实际问题是计算似然的代价是很高的,计算一个$d\times d$的矩阵的行列式或者$\VSigma(\Vx)$的逆(或者等价地并且更常用地,对它特征值分解或者$\MB(\Vx)$的特征值分解)需要$O(d^3)$的计算量。
% -- 183 --
我们经常想要执行多峰回归(multimodal regression),即预测条件分布$p(\Vy\mid\Vx)$的实值,该条件分布对于相同的$\Vx$值在$\Vy$空间中有多个不同的峰值。
在这种情况下,高斯混合是输出的自然表示\citep{Jacobs-nc91,bishop1994mixture}。
将高斯混合作为其输出的神经网络通常被称为\firstgls{mixture_density_network}。
具有$n$个分量的高斯混合输出由下面的条件分布定义:
\begin{equation}
p(\Vy\mid\Vx) = \sum_{i=1}^n p(\RSc = i \mid \Vx) \CalN(\Vy; \Vmu^{(i)}(\Vx), \VSigma^{(i)}(\Vx)).
\end{equation}
神经网络必须有三个输出:定义$p(\RSc=i\mid\Vx)$的向量,对所有的$i$给出$\Vmu^{(i)}(\Vx)$的矩阵,以及对所有的$i$给出$\VSigma^{(i)}(\Vx)$的张量。
这些输出必须满足不同的约束:
\begin{enumerate}
\item 混合组件$p(\RSc=i\mid\Vx)$:它们由\gls{latent_variable}\footnote{我们之所以认为$\RSc$是\gls{latent}的,是因为我们不能直接在数据中观测到它:给定输入$\RVx$和目标$\RVy$,不可能确切地知道是哪个高斯组件产生$\RVy$,但我们可以想象$\RVy$是通过选择其中一个来产生的,并且将那个未被观测到的选择作为随机变量。}~$\RSc$关联着,在$n$个不同组件上形成~\gls{multinoulli_distribution}。
这个分布通常可以由$n$维向量的softmax来获得,以确保这些输出是正的并且和为1。
\item 均值$\Vmu^{(i)}(\Vx)$:它们指明了与第$i$个高斯组件相关联的中心或者均值,并且是无约束的(通常对于这些输出单元完全没有非线性)。
如果$\RVy$是个$d$维向量,那么网络必须输出一个由$n$个这种$d$维向量组成的$n\times d$ 的矩阵。
用最大似然来学习这些均值要比学习只有一个输出模式的分布的均值稍稍复杂一些。我们只想更新那个真正产生观测数据的组件的均值。
在实践中,我们并不知道是哪个组件产生了观测数据。
负对数似然表达式将每个样本对每个组件的贡献进行赋权,权重的大小由相应的组件产生这个样本的概率来决定。
\item 协方差$\VSigma^{(i)}(\Vx)$:它们指明了每个组件$i$的协方差矩阵。
和学习单个高斯组件时一样,我们通常使用对角矩阵来避免计算行列式。
和学习混合均值时一样,最大似然是很复杂的,它需要将每个点的部分责任分配给每个混合组件。
如果给定了混合模型的正确的负对数似然,梯度下降将自动地遵循正确的过程。
\end{enumerate}
有报告说基于梯度的优化方法对于混合条件高斯(作为神经网络的输出)可能是不可靠的,部分是因为涉及到除法(除以方差)可能是数值不稳定的(当某个方差对于特定的实例变得非常小时,会导致非常大的梯度)。
一种解决方法是\firstgls{clip_gradients}(见\secref{sec:clipping_gradients}),另外一种是启发式缩放梯度\citep{Uria+al-ICML2014}。
% -- 184 --
高斯混合输出在语音生成模型\citep{schuster1999supervised}和物理运动\citep{Graves-arxiv2013}中特别有效。
混合密度策略为网络提供了一种方法来表示多种输出模式,并且控制输出的方差,这对于在这些实数域中获得高质量的结果是至关重要的。
混合密度网络的一个实例如\figref{fig:chap6_mdn_color}所示。
% fig 6.4
\begin{figure}[!htb]
\ifOpenSource
\centerline{\includegraphics{figure.pdf}}
\else
\centerline{\includegraphics{Chapter6/figures/mdn_color}}
\fi
\captionsetup{singlelinecheck=off}
\caption{从具有混合密度输出层的神经网络中抽取的样本。
输入$x$从\gls{uniform_distribution}中采样,输出$y$从$p_{\text{model}}(y\mid x)$中采样。 神经网络能够学习从输入到输出分布的参数的非线性映射。 这些参数包括控制三个组件中的哪一个将产生输出的概率,以及每个组件各自的参数。
每个混合组件都是\gls{gaussian_distribution},具有预测的均值和方差。 输出分布的这些方面都能够相对输入$x$变化,并且以非线性的方式改变。}
\label{fig:chap6_mdn_color}
\end{figure}
一般的,我们可能希望继续对包含更多变量的、更大的向量$\Vy$来建模,并在这些输出变量上施加更多更丰富的结构。
例如,我们可能希望神经网络输出字符序列形成一个句子。
在这些情况下,我们可以继续使用最大似然原理应用到我们的模型$p(\Vy;\Vomega(\Vx))$上,但我们用来描述$\Vy$的模型会变得非常复杂,超出了本章的范畴。
\chapref{chap:sequence_modeling_recurrent_and_recursive_nets}描述了如何使用循环神经网络来定义这种序列上的模型,第\ref{part:deep_learning_research}部分描述了对任意概率分布进行建模的高级技术。
\section{\glsentrytext{hidden_unit}}
\label{sec:hidden_units}
到目前为止,我们集中讨论了神经网络的设计选择,这对于使用基于梯度的优化方法来训练的大多数参数化机器学习模型都是通用的。
现在我们转向一个\gls{feedforward_neural_network}独有的问题:该如何选择\gls{hidden_unit}的类型,这些\gls{hidden_unit}用在模型的\gls{hidden_layer}中。
% -- 185 --
\gls{hidden_unit}的设计是一个非常活跃的研究领域,并且还没有许多明确的指导性理论原则。
\gls{ReLU}是\gls{hidden_unit}极好的默认选择。
许多其他类型的\gls{hidden_unit}也是可用的。
决定何时使用哪种类型的\gls{hidden_unit}是困难的事(尽管\gls{ReLU}通常是一个可接受的选择)。
我们这里描述对于每种\gls{hidden_unit}的一些基本直觉。
这些直觉可以用来建议我们何时来尝试一些单元。
通常不可能预先预测出哪种\gls{hidden_unit}工作得最好。
设计过程充满了试验和错误,先直觉认为某种\gls{hidden_unit}可能表现良好,然后用它组成神经网络进行训练,最后用验证集来评估它的性能。
这里列出的一些\gls{hidden_unit}可能并不是在所有的输入点上都是可微的。
例如,\gls{ReLU} $g(z)=\max\{0, z\}$在$z=0$处不可微。
这似乎使得$g$对于基于梯度的学习算法无效。
在实践中,梯度下降对这些机器学习模型仍然表现得足够好。
部分原因是神经网络训练算法通常不会达到代价函数的局部最小值,而是仅仅显著地减小它的值,如\figref{fig:chap4_approx_opt_color}所示。
这些想法会在\chapref{chap:optimization_for_training_deep_models}中进一步描述。
因为我们不再期望训练能够实际到达梯度为$\bm{0}$的点,所以代价函数的最小值对应于梯度未定义的点是可以接受的。
不可微的\gls{hidden_unit}通常只在少数点上不可微。
一般来说,函数$g(z)$具有左导数和右导数,左导数定义为紧邻在$z$左边的函数的斜率,右导数定义为紧邻在$z$右边的函数的斜率。
只有当函数在$z$处的左导数和右导数都有定义并且相等时,函数在$z$点处才是可微的。
神经网络中用到的函数通常对左导数和右导数都有定义。
在$g(z)=\max\{0,z\}$的情况下,在$z=0$处的左导数是0,右导数是1。
神经网络训练的软件实现通常返回左导数或右导数的其中一个,而不是报告导数未定义或产生一个错误。
这可以通过观察到在数字计算机上基于梯度的优化总是会受到数值误差的影响来启发式地给出理由。
当一个函数被要求计算$g(0)$时,底层值真正为0 是不太可能的。
相对的,它可能是被舍入为0的一个小量$\epsilon$。
在某些情况下,理论上有更好的理由,但这些通常对神经网络训练并不适用。
重要的是,在实践中,我们可以放心地忽略下面描述的\gls{hidden_unit}激活函数的不可微性。
% -- 186 --
除非另有说明,大多数的\gls{hidden_unit}都可以描述为接受输入向量$\Vx$,计算仿射变换$\Vz=\MW^\top \Vx+\Vb$,然后使用一个逐元素的非线性函数$g(\Vz)$。
大多数\gls{hidden_unit}的区别仅仅在于激活函数$g(\Vz)$的形式。
\subsection{\glsentrytext{ReLU}及其扩展}
\label{sec:rectified_linear_units_and_their_generalizations}
\gls{ReLU}使用激活函数$g(z)=\max\{0, z\}$。
\gls{ReLU}易于优化,因为它们和线性单元非常类似。
线性单元和\gls{ReLU}的唯一区别在于\gls{ReLU}在其一半的定义域上输出为零。
这使得只要\gls{ReLU}处于激活状态,它的导数都能保持较大。
它的梯度不仅大而且一致。
整流操作的二阶导数几乎处处为0,并且在\gls{ReLU}处于激活状态时,它的一阶导数处处为1。
这意味着相比于引入二阶效应的激活函数来说,它的梯度方向对于学习来说更加有用。
\gls{ReLU}通常作用于仿射变换之上:
\begin{equation}
\Vh = g(\MW^\top \Vx + \Vb).
\end{equation}
当初始化仿射变换的参数时,可以将$\Vb$的所有元素设置成一个小的正值,例如0.1。
这使得\gls{ReLU}很可能初始时就对训练集中的大多数输入呈现激活状态,并且允许导数通过。
有很多\gls{ReLU}的扩展存在。
大多数这些扩展的表现比得上\gls{ReLU},并且偶尔表现得更好。
\gls{ReLU}的一个缺陷是它们不能通过基于梯度的方法学习那些使它们激活为零的样本。
\gls{ReLU}的各种扩展保证了它们能在各个位置都接收到梯度。
\gls{ReLU}的三个扩展基于当$z_i<0$时使用一个非零的斜率$\alpha_i$:$h_i =g(\Vz, \Valpha)_i = \max(0, z_i) + \alpha_i \min(0, z_i)$。
\firstgls{absolute_value_rectification}固定$\alpha_i=-1$来得到$g(z)=|z|$。
它用于图像中的对象识别\citep{Jarrett-ICCV2009},其中寻找在输入照明极性反转下不变的特征是有意义的。
\gls{ReLU}的其他扩展比这应用地更广泛。
\firstgls{leaky_ReLU}\citep{Maas-et-al-ICML2013}将$\alpha_i$固定成一个类似0.01的小值,\firstgls{PReLU}或者~\textbf{\glssymbol{PReLU}}~将$\alpha_i$作为学习的参数\citep{He-et-al-arxiv2015}。
% -- 187 --
\firstgls{maxout_unit}\citep{Goodfellow_maxout_2013}进一步扩展了\gls{ReLU}。
\gls{maxout_unit}将$\Vz$划分为每组具有$k$个值的组,而不是使用作用于每个元素的函数$g(z)$。
每个\gls{maxout_unit}则输出每组中的最大元素:
\begin{equation}
g(\Vz)_i = \underset{j\in \SetG^{(i)}}{\max} z_j
\end{equation}
这里$\SetG^{(i)}$是组$i$的输入索引集$\{(i-1)k+1, \ldots, ik\}$。
这提供了一种方法来学习对输入$\Vx$空间中多个方向响应的分段线性函数。
\gls{maxout_unit}可以学习具有多达$k$段的分段线性的凸函数。
\gls{maxout_unit}因此可以视为\emph{学习激活函数}本身而不仅仅是单元之间的关系。
使用足够大的$k$,\gls{maxout_unit}可以以任意的精确度来近似任何凸函数。
特别地,具有两块的maxout层可以学习实现和传统层相同的输入$\Vx$的函数,这些传统层可以使用\gls{rectified_linear}激活函数、\gls{absolute_value_rectification}、\gls{leaky_ReLU} 或\gls{PReLU},或者可以学习实现与这些都不同的函数。
maxout层的参数化当然也将与这些层不同,所以即使是maxout学习去实现和其他种类的层相同的$\Vx$的函数这种情况下,学习的机理也是不一样的。
每个~\gls{maxout_unit}现在由$k$个权重向量来参数化,而不仅仅是一个,所以~\gls{maxout_unit}通常比\gls{ReLU}需要更多的正则化。
如果训练集很大并且每个单元的块数保持很低的话,它们可以在没有正则化的情况下工作得不错\citep{cai2013deep}。
\gls{maxout_unit}还有一些其他的优点。
在某些情况下,要求更少的参数可以获得一些统计和计算上的优点。
具体来说,如果由$n$个不同的线性过滤器描述的特征可以在不损失信息的情况下,用每一组$k$个特征的最大值来概括的话,那么下一层可以获得$k$倍更少的权重数 。
因为每个单元由多个过滤器驱动,\gls{maxout_unit}具有一些冗余来帮助它们抵抗一种被称为\firstgls{catastrophic_forgetting}的现象,这个现象是说神经网络忘记了如何执行它们过去训练的任务\citep{Goodfellow+al-ICLR2014-small}。
\gls{ReLU}和它们的这些扩展都是基于一个原则,那就是如果它们的行为更接近线性,那么模型更容易优化。
使用线性行为更容易优化的一般性原则同样也适用于除深度线性网络以外的情景。
循环网络可以从序列中学习并产生状态和输出的序列。
当训练它们时,需要通过一些\gls{time_step}来传播信息,当其中包含一些线性计算(具有大小接近1的某些方向导数)时,这会更容易。
作为性能最好的循环网络结构之一,LSTM通过求和在时间上传播信息,这是一种特别直观的线性激活。
它将在\secref{sec:the_long_short_term_memory_and_other_gated_rnns}中进一步讨论。
% -- 188 --
\subsection{\gls{logistic_sigmoid}与双曲正切函数}
\label{sec:logistic_sigmoid_and_hyperbolic_tangent}
在引入\gls{ReLU}之前,大多数神经网络使用~\gls{logistic_sigmoid}~激活函数
\begin{equation}
g(z) = \sigma(z)
\end{equation}
或者是双曲正切激活函数
\begin{equation}
g(z) = \text{tanh}(z).
\end{equation}
这些激活函数紧密相关,因为$\text{tanh}(z)=2\sigma(2z)-1$。
我们已经看过~\gls{sigmoid}~单元作为输出单元用来预测二值型变量取值为1的概率。
与分段线性单元不同,\gls{sigmoid}~单元在其大部分定义域内都饱和——当$z$取绝对值很大的正值时,它们饱和到一个高值,当$z$取绝对值很大的负值时,它们饱和到一个低值,并且仅仅当$z$接近0时它们才对输入强烈敏感。
\gls{sigmoid}~单元的广泛饱和性会使得基于梯度的学习变得非常困难。
因为这个原因,现在不鼓励将它们用作前馈网络中的\gls{hidden_unit}。
当使用一个合适的代价函数来抵消~\gls{sigmoid}~的饱和性时,它们作为输出单元可以与基于梯度的学习相兼容。
当必须要使用~\gls{sigmoid}~激活函数时,双曲正切激活函数通常要比~\gls{logistic_sigmoid}~函数表现更好。
在$\text{tanh}(0)=0$而$\sigma(0)=\frac{1}{2}$的意义上,它更像是单位函数。
因为$\text{tanh}$在0附近与单位函数类似,训练深层神经网络$\hat{y}=\Vw^\top \text{tanh}(\MU^\top \text{tanh}(\MV^\top \Vx))$类似于训练一个线性模型$\hat{y}= \Vw^\top \MU^\top \MV^\top \Vx$,只要网络的激活能够被保持地很小。
这使得训练$\text{tanh}$网络更加容易。
% -- 189 --
\gls{sigmoid}~激活函数在除了\gls{feedforward_network}以外的情景中更为常见。
循环网络、许多概率模型以及一些\gls{AE}有一些额外的要求使得它们不能使用分段线性激活函数,并且使得~\gls{sigmoid}~单元更具有吸引力,尽管它存在饱和性的问题。
\subsection{其他\gls{hidden_unit}}
\label{sec:other_hidden_units}
也存在许多其他种类的\gls{hidden_unit},但它们并不常用。
一般来说,很多种类的可微函数都表现得很好。
许多未发布的激活函数与流行的激活函数表现得一样好。
为了提供一个具体的例子,作者在MNIST数据集上使用$\Vh=\cos(\MW\Vx+\Vb)$测试了一个\gls{feedforward_network},并获得了小于1\%的误差率,这可以与更为传统的激活函数获得的结果相媲美。
在新技术的研究和开发期间,通常会测试许多不同的激活函数,并且会发现许多标准方法的变体表现非常好。
这意味着,通常新的\gls{hidden_unit}类型只有在被明确证明能够提供显著改进时才会被发布。
新的\gls{hidden_unit}类型如果与已有的\gls{hidden_unit}表现大致相当的话,那么它们是非常常见的,不会引起别人的兴趣。
列出文献中出现的所有\gls{hidden_unit}类型是不切实际的。
我们只对一些特别有用和独特的类型进行强调。
其中一种是完全没有激活函数$g(z)$。
也可以认为这是使用单位函数作为激活函数的情况。
我们已经看过线性单元可以用作神经网络的输出。
它也可以用作\gls{hidden_unit}。
如果神经网络的每一层都仅由线性变换组成,那么网络作为一个整体也将是线性的。
然而,神经网络的一些层是纯线性也是可以接受的。
考虑具有$n$个输入和$p$个输出的神经网络层$\Vh=g(\MW^\top \Vx+\Vb)$。
我们可以用两层来代替它,一层使用权重矩阵$\MU$,另一层使用权重矩阵$\MV$。
如果第一层没有激活函数,那么我们(用$\MU$和$\MV$替代$\MW$)实际上是对基于$\MW$的原始层的权重矩阵进行了因式分解。
分解方法是计算$\Vh=g(\MV^\top \MU^\top \Vx+\Vb)$。
如果$U$产生了$q$个输出,那么$\MU$和$V$一起仅包含$(n+p)q$个参数,而$\MW$包含$np$个参数。
如果$q$很小,这可以在很大程度上节省参数。
这是以将线性变换约束为低秩的代价来实现的,但这些低秩关系往往是足够的。
线性\gls{hidden_unit}因此提供了一种减少网络中参数数量的有效方法。
% -- 190 --
softmax单元是另外一种经常用作输出的单元(如\secref{sec:softmax_units_for_multinoulli_output_distributions}中所描述的),但有时也可以用作\gls{hidden_unit}。
softmax单元很自然地表示具有$k$个可能值的离散型随机变量的概率分布,所以它们可以用作一种开关。
这些类型的\gls{hidden_unit}通常仅用于明确地学习操作内存的高级结构中,将在\secref{sec:explicit_memory}中描述。
其他一些常见的\gls{hidden_unit}类型包括:
\begin{itemize}
\item \firstall{RBF}:$h_i = \exp \left (-\frac{1}{\sigma_i^2}|| \MW_{:,i}-\Vx||^2 \right )$。
这个函数在$\Vx$接近模板$\MW_{:,i}$时更加活跃。
因为它对大部分$\Vx$都饱和到0,因此很难优化。
\item \textbf{\gls{softplus}}函数:$g(a)=\zeta(a)=\log(1+e^a)$。
这是\gls{ReLU}的平滑版本,由~\cite{Dugas01}引入用于函数近似,由~\cite{Nair-2010-small}引入用于无向概率模型的条件分布。
\cite{Glorot+al-AI-2011-small}比较了softplus和\gls{ReLU},发现后者的结果更好。
通常不鼓励使用~\gls{softplus_function}。
softplus表明\gls{hidden_unit}类型的性能可能是非常反直觉的——因为它处处可导或者因为它不完全饱和,人们可能希望它具有优于\gls{ReLU}的点,但根据经验来看,它并没有。
\item \firstgls{hard_tanh}:它的形状和$\text{tanh}$以及\gls{ReLU}类似,但是不同于后者,它是有界的,$g(a)=\max(-1, \min(1,a))$。
它由~\cite{Collobert04}引入。
\end{itemize}
\gls{hidden_unit}的设计仍然是一个活跃的研究领域,许多有用的\gls{hidden_unit}类型仍有待发现。
\section{架构设计}
\label{sec:architecture_design}
神经网络设计的另一个关键点是确定它的架构。
\firstgls{architecture}一词是指网络的整体结构:它应该具有多少单元,以及这些单元应该如何连接。
% -- 191 --
大多数神经网络被组织成称为层的单元组。
大多数神经网络架构将这些层布置成链式结构,其中每一层都是前一层的函数。
在这种结构中,第一层由下式给出:
\begin{equation}
\Vh^{(1)}= g^{(1)}\left ( \MW^{(1)\top} \Vx + \Vb^{(1)}\right );
\end{equation}
第二层由
\begin{equation}
\Vh^{(2)} = g^{(2)}\left ( \MW^{(2)\top}\Vh^{(1)}+\Vb^{(2)} \right );
\end{equation}
给出,以此类推。
在这些链式架构中,主要的架构考虑是选择网络的深度和每一层的宽度。
我们将会看到,即使只有一个\gls{hidden_layer}的网络也足够适应训练集。
更深层的网络通常能够对每一层使用更少的单元数和更少的参数,并且经常容易泛化到测试集,但是通常也更难以优化。
对于一个具体的任务,理想的网络架构必须通过实验,观测在验证集上的误差来找到。
\subsection{万能近似性质和深度}
\label{sec:universal_approximation_properties_and_depth}
线性模型,通过矩阵乘法将特征映射到输出,顾名思义,仅能表示线性函数。
它具有易于训练的优点,因为当使用线性模型时,许多损失函数会导出凸优化问题。
可惜的是,我们经常希望我们的系统学习非线性函数。
乍一看,我们可能认为学习非线性函数需要为我们想要学习的那种非线性专门设计一类模型族。
幸运的是,具有\gls{hidden_layer}的\gls{feedforward_network}提供了一种万能近似框架。
具体来说,\firstgls{universal_approximation_theorem}\citep{Hornik89,Cybenko89}表明,一个\gls{feedforward_neural_network}如果具有线性输出层和至少一层具有任何一种``挤压''性质的激活函数(例如\gls{logistic_sigmoid}激活函数)的\gls{hidden_layer},只要给予网络足够数量的\gls{hidden_unit},它可以以任意的精度来近似任何从一个有限维空间到另一个有限维空间的Borel可测函数。
\gls{feedforward_network}的导数也可以任意好地来近似函数的导数\citep{hornik1990universal}。
Borel可测的概念超出了本书的范畴;对于我们想要实现的目标,只需要知道定义在$\SetR^n$的有界闭集上的任意连续函数是Borel可测的,因此可以用神经网络来近似。
神经网络也可以近似从任何有限维离散空间映射到另一个的任意函数。
虽然原始定理最初以具有特殊激活函数的单元的形式来描述,这个激活函数当变量取绝对值非常大的正值和负值时都会饱和,\gls{universal_approximation_theorem}也已经被证明对于更广泛类别的激活函数也是适用的,其中就包括现在常用的\gls{ReLU}~\citep{Leshno-et-al-1993}。