讨论 2022-12-06 = # 深度网络的训练(一) 我们现在经常说深度学习,深度网络,这里的“深度”具体指的就是网络的层数多。那么为什么神经网络层数多了,就出问题了? ## 深度网络为什么不易训练? 严格来说,学者们发现当MLP结构层数变多的时候(比如大于3,4层),参数的训练就变得越发困难,非常难以优化。这里的不易学习一般是对梯度下降来说的,具体而言,人们发现了梯度消失和梯度爆炸两个问题,他们的严重程度是随着网络层数增加而增强的,所以越深的网络受其影响越大。 一个多层MLP可以写成: \begin{gather} H_l = f(W_{l-1} H_{l-1}) \\ H_0 = \text{Input} \end{gather} 所以其导数 \begin{gather} \frac{\partial \mathbf{loss}}{W_0} = \frac{\partial \mathbf{loss}}{\partial H_L} \frac{\partial H_L}{\partial H_{L-1}} \cdots \frac{\partial H_l}{\partial H_{l-1}} \frac{\partial H_1}{\partial W_0} \\ \frac{\partial H_l}{\partial H_{l-1}} = f^{-1}(H_l) W_{l-1}^T \end{gather} 我们可以看到导数链条中包含了与层数正相关的乘法,假如f是$\sigma, \tanh$,那么我们还能知道激活值的数值范围。我们知道一系列数值相乘,很容易发生趋向于无穷或0的情况,也就对应了梯度爆炸和梯度消失。 另一方面,学者从连续程度的角度(其实和梯度有很大联系)谈了这一问题。如果我们观察一个作用于输入上的扰动,能多大程度影响系统输出的结果时,就可以理解到连续程度的重要性,如果输入的小扰动可以引起输出的大波动,那就是“蝴蝶效应”,此时系统往往是极其不稳定的,其参数训练自然也很苦难。而如果输入和输出太过一致,我们又发现这类系统往往能力太弱,因为我们实际想要的系统是对输入有稳定但也有区分性。其他而言,有些变化,我们希望系统能非常敏感,而另一些变化,我们又希望系统非常鲁棒。这里略作引伸,其实很多任务需要模型去学校准输入空间和输出空间的测度,我们不止需要把输入空间的数据点映射到输出空间,还需要把距离函数对齐。 关于系统对输入扰动的讨论,线性变化可以通过条件数来评判,对于有非线性的神经网络而言不容易分析,但比如对我们常用的激活函数ReLU而言,其实可以把神经网络理解为切分成很多块的线性空间,很多结论是可以扩展的。比如我们任意指定正负号,把ReLU拿掉,通过观察条件数的变化,我们可以看到网络层数的作用。 ### 矩阵的范数 矩阵的范数有多种定义方法,我们这里是的定义是 $$||A|| = \max_x \frac{||Ax||}{||x||} $$ 假如A可逆,设 $y=Ax$, $$||A^{-1}|| = \max_y \frac{||A^{-1}y||}{||y||} = \frac{1}{\min_y} \frac{||y||}{||A^{-1}y||} = \frac{1}{\min_x} \frac{||Ax||}{||x||} $$ ### 条件数 条件数的定义为 $\mathcal{k}(A) = ||A|| \cdot ||A^{-1}|| = \frac{\sigma_{max}}{\sigma_{min}}$ 考虑$Ax=b$,此时我们在x上假如噪声,相应的b上也许一个调整来让等号相等。 \begin{align} A(x+\delta x) = b + \delta b \\ A\delta x = \delta b \\ ||A\delta x|| = || \delta b|| \\ ||A|| \cdot ||\delta x|| \ge ||A\delta x|| = || \delta b|| \ge \frac{1}{||A^{-1}||} \cdot ||\delta x|| \\ ||A|| \cdot ||A^{-1}|| \ge \frac{||\delta b||}{||\delta x||} \end{align} 一般来讲,神经网络的条件数都很大,也就意味着他们其实很不鲁棒。当然条件数考虑的是最大波动(因为是最大特征值除以最小特征),实际上平均波动可能不是很大。其实通过观察数据分布和特征值分布可以有一些更精细的估计,但并不通用,我们也很难有数据分布。 ## 残差与跨层连接 为了应对上述的梯度问题,最简单的方法就是残差网络和跨层连接,即 \begin{align} H_l = H_{l-1} + f(W_{l-1} H_{l-1})\\ H_l = H_{l-k} + f(W_{l-1} H_{l-1}) \end{align} 这样导数是一个 1+X的形式,很大程度上缓解了梯度爆炸和消失问题。 ## 正交初始化 另一方面,我们知道正交矩阵以及酉矩阵有一个很好的性质,就是 $$||Ax|| = ||x|| $$ 即模长不变性。 如果网络每层的参数都是正交矩阵,那么梯度问题也可以得到缓解。但遗憾的是很多工作汇报说如果强制网络参数是正交矩阵,其表达能力会显著下降。 ## 高阶优化 (没整理好,以后有机会补上) # 度量学习与对抗学习 我们在之前的讨论中有涉及一个概念,就是神经网络实现了一个函数f,让$y=f(x)$,其中x是input,y是label。以此出发我们可以认为神经网络在学习如何将数据点从一个空间映射到另一个空间,而度量学习在乎的是二元关系,即$d(x_1, x_2)$与$d(f(x_1), f(x_2))$以及$d(y_1, y_2)$的关系。最简单的度量学习范式是$d(x,y;\theta)=x^T W_\theta y = \sum_{ij} x_i W_{ij} y_j$ ## 类内多态 ![](https://i.imgur.com/ANQytHr.png) 为什么我们要关注于度量学习,可以通过关于类内多态的问题来讨论。理想情况下,红色类别的数据点和蓝色类别的数据点是分开的,并且各自组成两个团(大家可以考虑如何定义一个团)。但实际上,红色可能有三个小团组成,蓝色有两个小团组成,并且这些小团无法合并(会混入其他颜色节点导致冲突)。据此,我们可以知道两个红色节点之间的距离未必很近,红色和蓝色数据点之间也未必很远。那么一个新来的节点,如何通过它与其他节点的位置来判定颜色呢? 这就引出了两种解决思路,一是认为假如特征空间足够好,我们可以把一个颜色的点总是映射到一起,那么不需要考虑度量问题。二是承认特征空间的局限性,把度量函数修改,比如分区域或分维度,有些区域用欧氏距离,有些用马氏,有些用哈密尔顿距离等。 ## 泛化性与可区分性 上述例子引出了进一步的思考,图中的连个红色包围圈好还是一个大的紫色包围圈好?落在两团红色中间的节点是不是应该为红色?我们可以发现这里存在一组矛盾,如果划分的更宽泛(紫色),那么泛化性可能更好,对于没见过的样本(偏离很远的)也可以识别,但区分性就降低了,我们很难分辨两团红色之间的区别,因为我们只知道他们都归属于紫色。反过来,如果划分的太细致,那么新来的数据点稍微偏离已知数据点,就认不出了。泛化性就很差。 \begin{align} f(x+\delta) ?= f(x) \\ y(x+\delta) ? = y \end{align} 上述的思考还有些宏观,当我们想要精细的控制数据点的延伸范围时,对抗学习就是一个很好的工具,其核心思想就是当一个数据点收到微小的扰动时,他的label变了还是没变,以此作为loss去训练网络。而这个微小的扰动是可学习的,比如利用GAN的方法,就可以控制扰动,进一步控制延伸范围(比如不规则延伸)。如果进一步考虑,有些扰动后label不变,有些变了,那还可以联系到对比学习。