深度学习根底入门篇[六(1)]:模型调优:注意力机制[多头注意力、自注意力],正则化【L1、L2,Dropout,Drop Connect】等
1. 注意力机制
在深度学习畛域,模型往往须要接管和解决大量的数据,然而在特定的某个时刻,往往只有少部分的某些数据是重要的,这种状况就非常适合 Attention 机制发光发热。
举个例子,图 2 展现了一个机器翻译的后果,在这个例子中,咱们想将”who are you”翻译为”你是谁”,传统的模型解决形式是一个 seq-to-seq 的模型,其蕴含一个 encoder 端和一个 decoder 端,其中 encoder 端对”who are you”进行编码,而后将整句话的信息传递给 decoder 端,由 decoder 解码出”我是谁”。在这个过程中,decoder 是逐字解码的,在每次解码的过程中,如果接管信息过多,可能会导致模型的外部凌乱,从而导致谬误后果的呈现。咱们能够应用 Attention 机制来解决这个问题,从图 2 能够看到,在生成”你”的时候和单词”you”关系比拟大,和”who are”关系不大,所以咱们更心愿在这个过程中可能应用 Attention 机制,将更多注意力放到”you”上,而不要太多关注”who are”,从而进步整体模型的体现。
Attention 机制自提出以来,呈现了很多不同 Attention 利用形式,但小道是独特的,均是将模型的注意力聚焦在重要的事件上。本文后续将抉择一些经典或罕用的 Attention 机制展开讨论。
备注:在深度学习畛域,有意识的显著性注意力更加常见。
1.1 用机器翻译工作带你看 Attention 机制的计算
独自地去讲 Attention 机制会有些形象,也有些干燥,所以咱们无妨以机器翻译工作为例,通过解说 Attention 机制在机器翻译工作中的利用形式,来理解 Attention 机制的应用。
什么是机器翻译工作?以中译英为例,机器翻译是将一串中文语句翻译为对应的英文语句,如图 1 所示。
图 1 展现了一种经典的机器翻译构造 Seq-to-Seq,并且向其中增加了 Attention 计算。Seq-to-Seq 构造蕴含两个局部:Encoder 和 Decoder。其中 Encoder 用于将中文语句进行编码,这些编码后续将提供给 Decoder 进行应用;Decoder 将依据 Encoder 的数据进行解码。咱们还是以图 1 为例具体解释一下 Decoder 的解码过程。
更明确的讲,图 1 展现的是生成单词”machine”时的计算形式。首先将前一个时刻的输入状态 $q_2$ 和 Encoder 的输入 $h=[h_1,h_2,h_3,h_4]$ 进行 Attention 计算,失去一个以后时刻的 context,用公式能够这样组织:
$$\begin{array}{c}[a_1,a_2,a_3,a_4]=sqrt{max}([s(q_2,h_1),s(q_2,h_2),s(q_2,h_3),s(q_2,h_4)])\\ cemtext{text}t=\sum_{i=1}^{4}a_i\cdot h_i\end{array}$$
咱们来解释一下,这里的 $s(q_i,h_j)$ 示意注意力打分函数,它是个标量,其大小形容了以后时刻在这些 Encoder 的后果上的关注水平,这个函数在后边会展开讨论。而后用 softmax 对这个后果进行归一化,最初应用加权评估取得以后时刻的上下文向量 context。这个 context 能够解释为:截止到以后曾经有了”I love”,在此基础高低一个时刻应该 更加关注源中文语句 的那些内容。这就是对于 Attention 机制的一个残缺计算。
最初,将这个 context 和上个时刻的输入”love”进行交融作为以后时刻 RNN 单元的输出。
图 1 中采纳了持续交融上一步的输入后果,例如上述形容中交融了”love”,在有些实现中,并没有融入这个上一步的输入,默认 $q_2$ 中曾经携带了”love”的信息,这也是正当的。
1.2 注意力机制的正式引入
前边咱们通过机器翻译工作介绍了 Attention 机制的整体计算。然而还有点小尾巴没有开展,就是那个 注意力打分函数的计算,当初咱们未来探讨这个事件。但在讲这个函数之前,咱们先来对上边的 Attention 机制的计算做个总结,图 2 具体地形容了 Attention 机制的计算原理。
假如当初咱们要对一组输出 $H=[h1,h2,h3,…,h_n]$ 应用 Attention 机制计算重要的内容,这里往往须要一个 查问向量 q(这个向量往往和你做的工作无关,比方机器翻译中用到的那个 $q_2$),而后通过一个 打分函数计算 查问向量 q 和每个输出 $h_i$ 之间的相关性,得出一个分数。接下来应用 softmax 对这些分数进行归一化,归一化后的后果便是查问向量 q 在各个输出 $h_i$ 上的注意力散布 $a=[a1,a2,a3,…,a_n]$,其中每一项数值和原始的输出 $H=[h1,h2,h3,…,h_n]$ 一一对应。以 $a_i$ 为例,相干计算公式如下:
$$a_i=software(s(h_i,q))=\dfrac{exp(s(h_i,q))}{\sum_{j=1}^n exp(s(h_j,q))}\quad$$
最初依据这些注意力散布能够去有选择性的从输出信息 H 中提取信息,这里比拟罕用的信息提取形式,是一种”软性”的信息提取(图 2 展现的就是一种”软性”注意力),即依据注意力散布对输出信息进行加权求和,最终的这个后果 context 体现了模型以后应该关注的内容:
$$\text{context}=\sum_{i=1}^n a_i\cdot h_i$$
当初咱们来解决之前始终没有开展的小尾巴 - 打分函数,它能够应用以下几种形式来计算:
加性模型: $$s(h,q)=v^Ttanh(Wh+Uq)\quad\text{}$$
点积模型: $$s(h,q)=h^Tq$$
缩放点积模型:$$s(h,q)=\frac{h^{T}q}{\sqrt{D}}\quad$$
双线性模型: $$s(h,q)=h^{T}W q$$
以上公式中的参数 W、U 和 v 均是可学习的参数矩阵或向量,D 为输出向量的维度。下边咱们来剖析一下这些分数计算形式的差异。
- 加性模型引入了可学习的参数,将查问向量 q 和原始输出向量 h 映射到不同的向量空间后进行计算打分,显然相较于加性模型,点积模型具备更好的计算效率。
- 另外,当输出向量的维度比拟高的时候,点积模型通常有比拟大的方差,从而导致 Softmax 函数的梯度会比拟小。因而缩放点积模型通过除以一个平方根项来平滑分数数值,也相当于平滑最终的注意力散布,缓解这个问题。
最初,双线性模型能够重塑为 $s(h_{i},q)=h^{T}W q=h^{T}(U^{T}V)q=(Uh)^{T}(V_q),$,即别离对查问向量 q 和原始输出向量 h 进行线性变换之后,再计算点积。相比点积模型,双线性模型在计算类似度时引入了非对称性。
1.3 注意力机制相干变体
1.3.1 硬性注意力机制
在经典注意力机制章节咱们应用了一种软性注意力的形式进行 Attention 机制,它通过注意力散布来加权求和交融各个输出向量。而硬性注意力(Hard Attention)机制则不是采纳这种形式,它是依据注意力散布抉择输出向量中的一个作为输入。这里有两种抉择形式:
- 抉择注意力散布中,分数最大的那一项对应的输出向量作为 Attention 机制的输入。
- 依据注意力散布进行随机采样,采样后果作为 Attention 机制的输入。
硬性注意力通过以上两种形式抉择 Attention 的输入,这会使得最终的损失函数与注意力散布之间的函数关系不可导,导致无奈应用反向流传算法训练模型,硬性注意力通常须要应用强化学习来进行训练。因而,个别深度学习算法会应用软性注意力的形式进行计算,
1.3.2 键值对注意力机制¶
假如咱们的输出信息不再是前边所提到的 $H=[h1,h2,h3,…,h_n]$,而是更为个别的键值对(key-value pair)模式 $(K,V)=[(k1,v1),(k2,v2),…,(k_n,v_n)]$,相干的查问向量依然为 q。这种模式下,个别会应用查问向量 q 和相应的键 $k_i$ 进行计算注意力权值 $a_i$。
$$a_i=software(s(k_i,q))=\dfrac{exp(s(k_i,q))}{\sum_{j=1}^n exp(s(k_j,q))}$$
当计算出在输出数据上的注意力散布之后,利用注意力散布和键值对中的对应值进行加权交融计算:
$$context=\sum\limits_{i=1}^{n}a_i\cdot v_i$$
显然,当键值雷同的状况下 $k=v$,键值对注意力就进化成了一般的经典注意力机制。
1.3.3. 多头注意力机制
多头注意力 (Multi-Head Attention) 是利用多个查问向量 $Q=[q1,q2,…,qm]$,并行地从输出信息 $(K,V)=[(k1,v1),(k2,v2),…,(kn,vn)]$ 中选取多组信息。在查问过程中,每个查问向量 qi 将会关注输出信息的不同局部,即从不同的角度下来剖析以后的输出信息。
假如 $a_{ij}$ 代表第 i 各查问向量 $q_i$ 与第 j 个输出信息 $k_j$ 的注意力权重,contexti 代表由查问向量 $q_i$ 计算得出的 Attention 输入向量。其计算形式为:
$$\begin{aligned}a_{ij}=sqrt{max}(s(k_j,q_i))&=\frac{exp(s(k_j,q_i))}{\sum_{i=1}^n exp(s(k_i,q_i))}\\ \text{context}_i&=\sum_{j=1}^n a_{ij}\cdot v_j\end{aligned}\quad$$
最终将所有查问向量的后果进行拼接作为最终的后果:
$$context=context_1\oplus\textit{context}_2\oplus\textit{context}_3\oplus\ldots\oplus\textit{context}_m$$
公式里的 ⊕示意向量拼接操作。
1.4 自注意力机制
在前边所讲的内容中,咱们会应用一个查问向量 q 和对应的输出 $H=[h1,h2,…,h_n]$ 进行 attention 计算,这里的查问向量 q 往往和工作相干,比方基于 Seq-to-Seq 的机器翻译工作中,这个查问向量 q. 能够是 Decoder 端前个时刻的输入状态向量,如图 1 所示。
然而在自注意力机制(self-Attention)中,这里的查问向量也能够应用输出信息进行生成,而不是抉择一个上述工作相干的查问向量。相当于模型读到输出信息后,依据输出信息自身决定以后最重要的信息。
自注意力机制往往采纳查问 - 键 - 值(Query-Key-Value)的模式,无妨以 BERT 中的自注意力机制展开讨论,如图 2 所示。
在图 2 中,输出信息 $H=[h1,h2]$,其中蓝色矩阵中每行代表对应一个输出向量,另外图 2 中有 $W_q,W_k,W_v$3 个矩阵,它们负责将输出信息 H 顺次转换到对应的查问空间 $Q=[q1,q2]$,键空间 $K=[k1,k2 和值空间 V =[v1,v2]$:
$$\begin{bmatrix}q_1=h_1W_q\\ q_2=h_2W_q\end{bmatrix}\Rightarrow Q=HW_q$$
$$\begin{bmatrix}k_1=h_1W_k\\ k_2=h_2W_k\end{bmatrix}\Rightarrow K=HW_k$$
$$\begin{bmatrix}v_1=h_1W_v\\ v_2=h_2W_v\end{bmatrix}\Rightarrow V=HW_v$$
取得输出信息在不同空间的表白 Q、K 和 V 后,这里无妨以 $h_1$ 这个为例,去计算这个地位的一个 attention 输入向量 $context_1$,它代表在这个地位模型应该重点关注的内容,如图 3 所示。
能够看到在取得原始输出 H 在查问空间、键空间和值空间的表白 Q、K 和 V 后,计算 $q_1$ 在 $h_1$ 和 $h_2$ 的分数 $s_11$ 和 $s_12$,这里的分数计算采纳的是点积操作。而后将分数进行缩放并应用 softmax 进行归一化,取得在 $h_1$ 这个地位的注意力散布:$a_11$ 和 $a_12$,它们代表模型以后在 $h_1$ 这个地位须要对输出信息 $h_1$ 和 $h_2$ 的关注水平。最初依据该地位的注意力散布对 $v_1$ 和 $v_2$ 进行加权均匀取得最终 h1 这个地位的 Attention 向量 $context_1$。
同理,你能够取得第 2 个地位的 Attention 向量 context2,或者持续扩大输出序列取得更多的 $context_i$,原理都是一样的。注意力机制的计算过程:
假如以后有输出信息 $H=[h1,h2,…,h_n]$,咱们须要应用自注意力机制获取每个地位的输入 $context=[context1,context2,…,context_n]$。
- 首先,须要将原始输出映射到查问空间 Q、键空间 K 和值空间 V,相干计算公式如下:
$$\begin{array}{c}Q=HW_q=[q_1,q_2,\ldots,q_n]\\ K=HW_k=[k_1,k_2,\ldots,k_n]\\ V=HW_v=[v_1,v_2,\ldots,v_n]\end{array}$$
- 接下来,咱们将去计算每个地位的注意力散布,并且将相应后果进行加权求和:
$$context_i=\sum\limits_{j=1}^n{software(s(q_i,k_j))}\cdot v_j$$
其中 $s(q_i,k_j)$ 是通过上述点积、缩放后分数值。
- 最初,为了放慢计算效率,这里其实能够应用矩阵计算的形式,一次性计算出所有地位的的 Attention 输入向量:
$$context=software(\dfrac{QK^T}{\sqrt{D_k}})V$$
祝贺,看到这里置信你曾经十分分明自注意力机制的原理了。
2. 正则化
当咱们向右移时,咱们的模型试图从训练数据中很好地学习细节和噪声,这最终导致在看不见的数据上体现不佳。也就是说,当模型向右挪动时,模型的复杂度减少,使得训练误差减小,而测试误差没有减小。如下图所示。
如果你以前建设过神经网络,你就晓得它们有多简单。这使得他们更容易适度拟合。
正则化是一种对学习算法稍加批改以使模型具备更好的泛化能力的技术。这反过来也进步了模型在看不见的数据上的性能。
2.1 正则化如何帮忙缩小适度拟合
让咱们思考一个神经网络,它对训练数据进行了适度拟合,如下图所示。
如果你钻研过机器学习中正则化的概念,你会有一个偏心的想法,正则化惩办系数。在深度学习中,它实际上惩办节点的权重矩阵。
假如咱们的正则化系数十分高,以至于一些权重矩阵简直等于零。
这将导致更简略的线性网络和训练数据的轻微欠拟合。
如此大的正则化系数值并不是很有用。咱们须要优化正则化系数的值,以取得如下图所示的良好拟合模型。
正则化能够防止算法过拟合,过拟合通常产生在算法学习的输出数据无奈反馈实在的散布且存在一些噪声的状况。过来数年,研究者提出和开发了多种适宜机器学习算法的 正则化办法,如数据加强、L2 正则化(权重衰减)、L1 正则化、Dropout、Drop Connect、随机池化和早停等。
除了泛化起因,奥卡姆剃刀原理和贝叶斯预计也都反对着正则化。依据奥卡姆剃刀原理,在所有可能抉择的模型中,能很好解释已知数据,并且非常简略的模型才是最好的模型。而从贝叶斯预计的角度来看,正则化项对应于模型的先验概率。
2.2 数据加强
数据加强是晋升算法性能、满足深度学习模型对大量数据的需要的重要工具。数据加强通过向训练数据增加转换或扰动来人工减少训练数据集。数据加强技术如程度或垂直翻转图像、裁剪、色调变换、扩大和旋转通常利用在视觉表象和图像分类中。
对于视觉畛域的数据加强的办法具体请参考:数据增广,后续开展。
2.3 L1 和 L2 正则化
L1 和 L2 正则化是最罕用的正则化办法。L1 正则化向指标函数增加正则化项,以缩小参数的绝对值总和;而 L2 正则化中,增加正则化项的目标在于缩小参数平方的总和。依据之前的钻研,L1 正则化中的很多参数向量是稠密向量,因为很多模型导致参数趋近于 0,因而它罕用于特征选择设置中。机器学习中最罕用的正则化办法是对权重施加 L2 范数束缚。
规范正则化代价函数如下:
$$\theta=argmin_\theta\dfrac{1}{N}\sum\limits_{i=1}^N(L(\hat{y}_i,y)+\lambda R(w))$$
其中正则化项 R(w) 是:
$$R_{L_2}(w)=||W||_2^2$$
另一种惩办权重的绝对值总和的办法是 L1 正则化:
$$R_{L_1}(w)=||W||_1$$
L1 正则化在零点不可微,因而权重以趋近于零的常数因子增长。很多神经网络在权重衰减公式中应用一阶步骤来解决非凸 L1 正则化问题。L1 范数的近似变体是:
$$\left|\left|W\right|\right|_1=\sum\limits_{k=1}^Q\sqrt{w_k^2+\epsilon}$$
另一个正则化办法是混合 L1 和 L2 正则化,即弹性网络罚项。
整个最优化问题从贝叶斯观点来看是一种贝叶斯最大后验预计,其中正则化项对应后验预计中的先验信息,损失函数对应后验预计中的似然函数,两者的乘积即对应贝叶斯最大后验预计的模式
2.3.1 贝叶斯推断分析法
针对 L1 范数和 L2 范数还有论断:
- L1 范数相当于给模型参数 θ 设置一个参数为 $\frac{1}{\alpha}$ 的零均值拉普拉斯先验散布
- L2 范数相当于给模型参数 θ 设置一个协方差 $\frac{1}{\alpha}$ 的零均值高斯先验散布
1.L2 范数相当于给模型参数 θ 设置一个零均值高斯先验散布
以线性模型为例,论断能够推广到任意模型,线性模型方程能够示意为:
$$Y=\theta^TX+\epsilon\quad\text{}$$
其中 ϵ 示意误差,$\epsilon\sim N(0,\sigma^2)\text{,}\theta_i\sim N(0,\tau^2)$, 则有:
$$p(\epsilon_i)=\dfrac{1}{\sqrt{2\pi\sigma^2}}exp(-\dfrac{\epsilon_i^2}{2\sigma^2})$$
$$p(y_i|x_i;\theta)=\dfrac{1}{\sqrt{2\pi\sigma^2}}exp(-\dfrac{(y_i-\theta^Tx_i)^2}{2\sigma^2})$$
计算最大后验预计:
$$argmax_{\theta}ln L(\theta)=argmax_\theta(ln\prod\limits_{i=1}^np(y_i|x_i;\theta)+lp(\theta)) \\=ln\prod\limits_{i=1}^n\dfrac{1}{\sqrt{2\pi\sigma^2}}exp(-\dfrac{(y_i-\theta^Tx_i)^2}{2\sigma^2})+ln\prod\limits_{j=1}^d\dfrac{1}{\sqrt{2\pi\tau^2}}exp(-\dfrac{\theta_j^2}{2\tau^2})\quad \\ =-\dfrac{1}{2\sigma^2}\sum_{i=1}^n(y_i-\theta^Tx_i)^2-\dfrac{1}{2\tau^2}\sum_{j=1}^d\theta_j^2+nln\sigma\sqrt{2\pi}-dln\tau\sqrt{2\pi}\quad$$
最大化上式,去掉负号,对立参数能够转化为:
$$argmin_{\theta}ln L(\theta)=\sum_{i=1}^n(y_i-\theta^Tx_i)^2+\lambda\sum_{j=1}^d\theta_j^2$$
上式正好是线性回归问题在 L2 范数的代价函数,故验证了论断。
2.L1 范数相当于给模型参数 θ 设置一个拉普拉斯先验散布
以线性模型为例,论断能够推广到任意模型,同样假如 $\epsilon\sim N(0,\sigma^2)\text{,}\theta_i\sim Laplace(0,b)$ 则有:
$$argmax_{\theta}ln L(\theta)=ln\prod\limits_{i=1}^n p(y_i|x_i;\theta)+ln p(\theta)\quad\quad\quad \\ \begin{aligned}&=ln\prod\frac{1}{\sqrt{2\pi\sigma^2}}exp(-\frac{(y_i-\theta^Tx_i)^2}{2\sigma^2})+ln\prod\limits_{j=1}^d\frac{1}{2b}exp(-\frac{|\theta_j|}{b})\\ &=\frac{1}{2\sigma^2}\sum_{i=1}^n(y_i-\theta^Tx_i)^2-\frac{1}{b}\sum\limits_{i=1}^n|\theta_j|-nln\sigma\sqrt{2\pi}-d in2b\end{aligned}$$
最大化上式,去掉负号和对立参数,就变成了最小化:
$$argmin_\theta lnL(\theta)=\sum\limits_{i=1}^n(y_i-\theta^Tx_i)+\lambda\sum\limits_{j=1}^d|\theta_j|$$
上式正好是线性回归问题在 L1 范数正则下的代价函数,故验证了论断。
如果误差合乎 0 均值的高斯分布,那么最大似然预计法的后果就是最小二乘法,这也是为何误差定义常常应用 $$\sum_{i=1}^{n}(y_{i}-\theta^{T}x_{i})^{2}$$ 的起因,因为这个公式是基于概率推导进去的
2.4 Dropout
Dropout 指在训练神经网络过程中随机丢掉一部分神经元来缩小神经网络复杂度,从而避免过拟合。Dropout 实现办法很简略:在每次迭代训练中,以肯定概率随机屏蔽每一层中若干神经元,用余下神经元所形成网络来持续训练。
图 1 是 Dropout 示意图,右边是残缺的神经网络,左边是利用了 Dropout 之后的网络结构。利用 Dropout 之后,会将标了×的神经元从网络中删除,让它们不向前面的层传递信号。在学习过程中,抛弃哪些神经元是随机决定,因而模型不会适度依赖某些神经元,能肯定水平上克制过拟合。
- 利用示例
在预测场景时,会向前传递所有神经元的信号,可能会引出一个新的问题:训练时因为局部神经元被随机抛弃了,输入数据的总大小会变小。比方:计算其 L1 范数会比不应用 Dropout 时变小,然而预测时却没有抛弃神经元,这将导致训练和预测时数据的散布不一样。为了解决这个问题,飞桨反对如下两种办法:
- downscale_in_infer
训练时以比例 r 随机抛弃一部分神经元,不向后传递它们的信号;预测时向后传递所有神经元的信号,然而将每个神经元上的数值乘以 (1−r)。
- upscale_in_train
训练时以比例 r 随机抛弃一部分神经元,不向后传递它们的信号,然而将那些被保留的神经元上的数值除以 (1−r);预测时向后传递所有神经元的信号,不做任何解决。
已飞桨框架为例:Dropout API 中,通过 mode 参数来指定用哪种形式对神经元进行操作,
paddle.nn.Dropout(p=0.5, axis=None, mode=”upscale_in_train”, name=None)
主要参数如下:
- p (float):将输出节点置为 0 的概率,即抛弃概率,默认值:0.5。该参数对元素的抛弃概率是针对于每一个元素而言,而不是对所有的元素而言。举例说,假如矩阵内有 12 个数字,通过概率为 0.5 的 dropout 未必肯定有 6 个零。
- mode(str):抛弃法的实现形式,有’downscale_in_infer’和’upscale_in_train’两种,默认是’upscale_in_train’。
# dropout 操作
import paddle
import numpy as np
# 设置随机数种子,这样能够保障每次运行后果统一
np.random.seed(100)
# 创立数据[N, C, H, W],个别对应卷积层的输入
data1 = np.random.rand(2,3,3,3).astype('float32')
# 创立数据[N, K],个别对应全连贯层的输入
data2 = np.arange(1,13).reshape([-1, 3]).astype('float32')
# 应用 dropout 作用在输出数据上
x1 = paddle.to_tensor(data1)
# downgrade_in_infer 模式下
drop11 = paddle.nn.Dropout(p = 0.5, mode = 'downscale_in_infer')
droped_train11 = drop11(x1)
# 切换到 eval 模式。在动态图模式下,应用 eval()切换到求值模式,该模式禁用了 dropout。drop11.eval()
droped_eval11 = drop11(x1)
# upscale_in_train 模式下
drop12 = paddle.nn.Dropout(p = 0.5, mode = 'upscale_in_train')
droped_train12 = drop12(x1)
# 切换到 eval 模式
drop12.eval()
droped_eval12 = drop12(x1)
x2 = paddle.to_tensor(data2)
drop21 = paddle.nn.Dropout(p = 0.5, mode = 'downscale_in_infer')
droped_train21 = drop21(x2)
# 切换到 eval 模式
drop21.eval()
droped_eval21 = drop21(x2)
drop22 = paddle.nn.Dropout(p = 0.5, mode = 'upscale_in_train')
droped_train22 = drop22(x2)
# 切换到 eval 模式
drop22.eval()
droped_eval22 = drop22(x2)
print('x1 {}, \n droped_train11 \n {}, \n droped_eval11 \n {}'.format(data1, droped_train11.numpy(), droped_eval11.numpy()))
print('x1 {}, \n droped_train12 \n {}, \n droped_eval12 \n {}'.format(data1, droped_train12.numpy(), droped_eval12.numpy()))
print('x2 {}, \n droped_train21 \n {}, \n droped_eval21 \n {}'.format(data2, droped_train21.numpy(), droped_eval21.numpy()))
print('x2 {}, \n droped_train22 \n {}, \n droped_eval22 \n {}'.format(data2, droped_train22.numpy(), droped_eval22.numpy()))
程序运行后果如下:
x1
[[[[0.54340494 0.2783694 0.4245176] [0.84477615 0.00471886 0.12156912] [0.67074907 0.82585275 0.13670659]]
[[0.5750933 0.89132196 0.20920213] [0.18532822 0.10837689 0.21969749] [0.9786238 0.8116832 0.17194101]]
[[0.81622475 0.27407375 0.4317042] [0.9400298 0.81764936 0.33611196] [0.17541045 0.37283206 0.00568851]]]
[[[0.25242636 0.7956625 0.01525497] [0.5988434 0.6038045 0.10514768] [0.38194343 0.03647606 0.89041156]]
[[0.98092085 0.05994199 0.89054596] [0.5769015 0.7424797 0.63018394] [0.5818422 0.02043913 0.21002658]]
[[0.5446849 0.76911515 0.25069523] [0.2858957 0.8523951 0.9750065] [0.8848533 0.35950786 0.59885895]]]]
droped_train11
[[[[0. 0.2783694 0.4245176] [0. 0.00471886 0.] [0. 0.82585275 0.]]
[[0. 0. 0.20920213] [0.18532822 0.10837689 0.] [0.9786238 0. 0.17194101]]
[[0.81622475 0.27407375 0.] [0. 0. 0.33611196] [0.17541045 0.37283206 0.00568851]]]
[[[0.25242636 0. 0.] [0.5988434 0.6038045 0.10514768] [0.38194343 0. 0.89041156]]
[[0.98092085 0. 0.] [0.5769015 0.7424797 0.] [0.5818422 0.02043913 0.]]
[[0.5446849 0.76911515 0.] [0. 0.8523951 0.9750065] [0. 0.35950786 0.59885895]]]],
droped_eval11
[[[[0.27170247 0.1391847 0.2122588] [0.42238808 0.00235943 0.06078456] [0.33537453 0.41292638 0.0683533]]
[[0.28754666 0.44566098 0.10460106] [0.09266411 0.05418845 0.10984875] [0.4893119 0.4058416 0.08597051]]
[[0.40811238 0.13703687 0.2158521] [0.4700149 0.40882468 0.16805598] [0.08770522 0.18641603 0.00284425]]]
[[[0.12621318 0.39783126 0.00762749] [0.2994217 0.30190226 0.05257384] [0.19097172 0.01823803 0.44520578]]
[[0.49046043 0.02997099 0.44527298] [0.28845075 0.37123984 0.31509197] [0.2909211 0.01021957 0.10501329]]
[[0.27234244 0.38455757 0.12534761] [0.14294785 0.42619756 0.48750326] [0.44242665 0.17975393 0.29942948]]]]
x1
[[[[0.54340494 0.2783694 0.4245176] [0.84477615 0.00471886 0.12156912] [0.67074907 0.82585275 0.13670659]]
[[0.5750933 0.89132196 0.20920213] [0.18532822 0.10837689 0.21969749] [0.9786238 0.8116832 0.17194101]]
[[0.81622475 0.27407375 0.4317042] [0.9400298 0.81764936 0.33611196] [0.17541045 0.37283206 0.00568851]]]
[[[0.25242636 0.7956625 0.01525497] [0.5988434 0.6038045 0.10514768] [0.38194343 0.03647606 0.89041156]]
[[0.98092085 0.05994199 0.89054596] [0.5769015 0.7424797 0.63018394] [0.5818422 0.02043913 0.21002658]]
[[0.5446849 0.76911515 0.25069523] [0.2858957 0.8523951 0.9750065] [0.8848533 0.35950786 0.59885895]]]]
droped_train12
[[[[0. 0.5567388 0.8490352] [0. 0. 0.24313824] [0. 0. 0.]]
[[0. 0. 0.41840425] [0.37065643 0. 0.] [1.9572476 0. 0.]]
[[0. 0. 0.] [0. 1.6352987 0.6722239] [0.3508209 0. 0.01137702]]]
[[[0. 1.591325 0.03050994] [1.1976868 1.207609 0.] [0.76388687 0. 1.7808231]]
[[0. 0. 0.] [1.153803 0. 0.] [1.1636844 0. 0.42005315]]
[[1.0893698 0. 0.50139046] [0.5717914 1.7047902 0.] [0. 0.7190157 0.]]]]
droped_eval12
[[[[0.54340494 0.2783694 0.4245176] [0.84477615 0.00471886 0.12156912] [0.67074907 0.82585275 0.13670659]]
[[0.5750933 0.89132196 0.20920213] [0.18532822 0.10837689 0.21969749] [0.9786238 0.8116832 0.17194101]]
[[0.81622475 0.27407375 0.4317042] [0.9400298 0.81764936 0.33611196] [0.17541045 0.37283206 0.00568851]]]
[[[0.25242636 0.7956625 0.01525497] [0.5988434 0.6038045 0.10514768] [0.38194343 0.03647606 0.89041156]]
[[0.98092085 0.05994199 0.89054596] [0.5769015 0.7424797 0.63018394] [0.5818422 0.02043913 0.21002658]]
[[0.5446849 0.76911515 0.25069523] [0.2858957 0.8523951 0.9750065] [0.8848533 0.35950786 0.59885895]]]]
x2
[[1. 2. 3.] [4. 5. 6.] [7. 8. 9.] [10. 11. 12.]],
droped_train21
[[1. 2. 3.] [4. 5. 6.] [0. 0. 9.] [0. 11. 0.]]
droped_eval21
[[0.5 1. 1.5] [2. 2.5 3.] [3.5 4. 4.5] [5. 5.5 6.]]
x2
[[1. 2. 3.] [4. 5. 6.] [7. 8. 9.] [10. 11. 12.]]
droped_train22
[[2. 0. 6.] [0. 10. 0.] [14. 16. 18.] [0. 22. 24.]]
droped_eval22
[[1. 2. 3.] [4. 5. 6.] [7. 8. 9.] [10. 11. 12.]]
从下面的运行后果能够看到,通过 dropout 之后,tensor 中的某些元素变为了 0,这个就是 dropout 实现的性能,通过随机将输出数据的元素置 0,打消削弱了神经元节点间的联结适应性,加强模型的泛化能力。
在程序中,咱们将随机失活比率设为 0.5,别离应用两种不同的策略进行 dropout,并且别离打印训练和评估模式下的网络层输入。其中,数据 x1 模仿的是卷积层的输入数据,数据 x2 模仿的是全连贯层的输出数据。因为通常状况下,咱们会把 dropout 增加到全连贯层后,所以这里针对前一层的输入为 x2 的状况为大家进行剖析,前一层的输入为 x1 的状况也根本相似。
x2 定义如下:
$$x_2=\begin{bmatrix}1&2&3\\ 4&5&6\\ 7&8&9\\ 10&11&12\end{bmatrix}$$
将 paddle.nn.Dropout API 中 mode 设置为‘downscale_in_infer’时,能够察看到在训练模式下,局部元素变为 0,其余元素的值并没有产生扭转,此时 $x_{2_\textit{train}}$ 为:
$$x_2=\begin{bmatrix}1&2&3\\ 4&5&6\\ 0&0&9\\ 0&11&0\end{bmatrix}$$
而在验证模式下,所有的元素都被保留,然而所有元素的值都进行了缩放,缩放的系数为(1−r),即(1−0.5)=0.,此时 x2_eval 为:
$$x_2=\begin{bmatrix}0.5&1&1.5\\ 2&2.5&3\\ 3.5&4&4.5\\ 5&5.5&6\end{bmatrix}\quad$$
而将 paddle.nn.Dropout API 中 mode 设置为‘upscale_in_train’时,能够察看到在训练模式下,局部元素变为 0,其余元素的值进行了缩放,缩放的系数为 1 /1−r,即 1 /(1−0.5)=2,,此时 x2_train 为:
$$x_2=\left[\begin{array}{ccc}2&0&6\\ 0&10&0\\ 14&16&18\\ 0&22&24\end{array}\right]$$
而在验证模式下,所有的元素都被保留,且所有元素的值并没有产生扭转,此时 x2_eval 为:
$$x_2=\begin{bmatrix}1&2&3\\ 4&5&6\\ 7&8&9\\ 10&11&12\end{bmatrix}\quad$$
2.5 Drop Connect
DropConnect 也是在 ICML2013 上发表的另一种缩小算法过拟合的正则化策略,是 Dropout 的一般化。在 Drop Connect 的过程中须要将网络架构权重的一个随机抉择子集设置为零,取代了在 Dropout 中对每个层随机抉择激活函数的子集设置为零的做法。因为每个单元接管来自过来层单元的随机子集的输出,Drop Connect 和 Dropout 都能够取得无限的泛化性能。Drop Connect 和 Dropout 类似的中央在于它波及在模型中引入稠密性,不同之处在于它引入的是权重的稠密性而不是层的输入向量的稠密性。对于一个 DropConnect 层,输入能够写为:
$$r=a((M*W)v)$$
其中 r 是一个层的输入,v 是一个层的输出,W 是权重参数,M 是编码连贯信息的二进制矩阵,其中 $M_{ij} Bernoulli(p)$。在训练期间,M 中的每个元素都是独立的对样本进行。基本上为每个示例实例化不同的连贯。另外,这些偏见在训练中也被覆盖了。
2.5.1 dropout 与 dropconncet 区别
- Dropout 是随机将隐含层节点的输入清 0,针对的是输入。
- DropConnect 是将节点中的每个与其相连的输出权值以 1 - p 的概率清 0;针对的是输出。
2.5.2 DropConnect 的训练
应用 DropConnect 时,须要对每个 example, 每个 echo 都随机 sample 一个 M 矩阵(元素值都是 0 或 1, 俗称 mask 矩阵)。training 局部的算法流程如下:
DropConnect 只能用于全连贯的网络层(和 dropout 一样),如果网络中用到了卷积,则用 patch 卷积时的隐层节点是不应用 DropConnect 的,因而下面的流程里有一个 Extract feature 步骤,该步骤就是网络后面那些非全连贯层的流传过程,比方卷积 +pooling.
2.5.3 DropConnect 的推理
在 Dropout 网络中进行 inference 时,是将所有的权重 W 都 scale 一个系数 p(作者证实这种近似在某些场合是有问题的)。而在对 DropConnect 进行推理时,采纳的是对每个输出(每个隐含层节点连贯有多个输出)的权重进行高斯分布的采样。该高斯分布的均值与方差当然与后面的概率值 p 无关,满足的高斯分布为:
$$uN(pWv,p(1-p)(W*W)(v*v))$$
推理过程如下:
由下面的过程可知,在进行 inference 时,须要对每个权重都进行 sample,所以 DropConnect 速度会慢些。
依据作者的观点,Dropout 和 DropConnect 都相似模型均匀,Dropout 是 $2^{|m|}$ 个模型的均匀,而 DropConnect 是 $2^{|M|}$ 个模型的均匀。(m 是向量,M 是矩阵,取模示意矩阵或向量中对应元素的个数),从这点上来说,DropConnect 模型均匀能力更强,因为 $|M|>|m|$
2.6 早停法
早停法能够限度模型最小化代价函数所需的训练迭代次数。早停法通常用于避免训练中适度表白的模型泛化性能差。如果迭代次数太少,算法容易欠拟合(方差较小,偏差较大),而迭代次数太多,算法容易过拟合(方差较大,偏差较小)。早停法通过确定迭代次数解决这个问题,不须要对特定值进行手动设置。
提前进行是一种穿插验证的策略,即把一部分训练集保留作为验证集。当看到验证集上的性能变差时,就立刻进行模型的训练。
在上图中,咱们在虚线处进行模型的训练,因为在此处之后模型会开始在训练数据上过拟合。
本文参加了 SegmentFault 思否写作挑战赛,欢送正在浏览的你也退出。