训练一个前馈网络至少需要做和线性模型一样的多的设计决策:选择一个优化模型、代价函数以及输出单元的形式。
激活单元可以分为隐藏单元和输出单元。
目前神经网络中最常用的隐藏单元是tanh函数和Relu函数。
激活函数
隐藏单元的选择:
Relu参数初始化使用正态分布给参数加上噪声来打破完全对称并且避免0梯度,而在softmax层可以将参数全部初始化为0。
当使用交叉熵作为代价函数的时候,代价函数的选择与输出单元 p ( y ∣ x ) p(y|x) p(y∣x)的选择紧密相关。基于使用sigmoid输出单元和最大似然估计来保证较大的梯度。
1)高斯输出分布的线性单元,此时的最大化对数似然等价于最小化均方误差;
2)用于Bernoulli输出分布的sigmoid单元,此时可以得到很好的性质。仅在预测正确时饱和,预测错误时梯度较大;
3)用于Multinoulli输出分布的softmax单元,此时对数似然的推测与二分类相似,负对数似然总是强烈地惩罚最活跃的不正确预测。
具体来说,那些不使用对数来抵消softmax中的指数的目标函数,当指数函数的变量取非常小的负值时会造成梯度消失。
在大多数情况下,参数模型定义了一个分布 p ( y ∣ x ; θ ) p(y|x;\theta) p(y∣x;θ)并且简单地使用最大似然原理,这意味着我们使用训练数据和模型预测间的交叉熵作为代价函数。
代价函数是负的最大似然,与训练模型和模型分布间的交叉熵等价。这个代价函数表示为: J ( θ ) = − E X , Y ∼ p ^ d a t a log p m o d e l ( y ∣ x ) J(\theta)=-\mathbb{E}_{X,Y\sim \hat p_{data}}\log{p_{\rm model}(y|x)} J(θ)=−EX,Y∼p^datalogpmodel(y∣x)
选择负对数似然来导出代价函数的一个优势是,它减轻了为每个模型设计代价函数的负担,明确一个模型则自动确定了一个代价函数;另外,贯穿神经网络设计的一个主题是代价函数的梯度必须足够大和具有足够的预测性,来为学习算法提供好的指引。饱和(变得非常平)的函数破坏了这一目标,因为它们把梯度变得特别小。许多输出单元都会包含一个指示函数,这在它的变量取非常大的负值时会造成饱和,负对数似然中的对数函数消除了某些输出单元中的指数效果。
神经网络的正向传播与反向传播
神经网络中的正则化的方法很多,比较典型的代表有L2正则和dropout正则
L2正则依赖于一个假设:即简单的可解释的模型优于复杂的模型,因此,L2正则通过在原始的损失函数上加上了正则项( 1 m λ 2 W 2 \frac{1}{m}\frac{\lambda}{2}W^2 m12λW2),而使得参数趋于一个较小的值,也就是加大的对参数的惩罚,这就使得整个模型较为简单,当输入变化时输出变化比较缓慢。
dropout正则:在每一次迭代训练中随机的隐藏一定概率的隐藏单元,因此每一次迭代的模型都是不同的,每一个神经元都不能多度依赖于另一个神经元,因此增强了模型的鲁棒性。
其他的正则化方式有:
1)数据扩充。
2)early stopping
详细戳这个
输出单元一般都使用softmax函数进行决策,softmax的公式:
a i = e i ∑ k e k a_i=\frac{e^i}{\sum_ke^k} ai=∑kekei
其中i是最后一个隐藏层对应的数值。例如在最后一个隐藏层的输出为[3,1,-3],则计算出来它们对应的softmax值为[0.88,0.12,0],这个list的总和为1,每个值的含义是输入为当前位置分类的概率。此时可以认为分类结果为[1,0,0]。
为什么在多分类中多使用softmax作为最后一层呢?
当损失函数为交叉熵损失函数的时候,即 L = ∑ i − y i log a i L=\sum_i -y_i\log a_i L=∑i−yilogai,其中 a i a_i ai为i类的预测输出概率, y i y_i yi为真实输出概率。
具体推导过程见 softmax函数详解与推导
得到的结论是:以softmax为决策函数,交叉熵函数为损失函数的时候,计算损失函数对最后一层参数w的导数会非常方便。
对w,b来说,选择一个好的初始参数有以下两个优点:
1.加快梯度下降的速度,使其快速收敛;
2.增加梯度下降到全局最优解的几率。
那么如何选择这个参数呢,首先参数不能全部初始化为0。当初始化参数均为0时,隐藏层中的各个单元呈对称性,在计算梯度下降时,各层的各个单元也呈对称性,那么多个隐藏单元都在做同样的事情,因为多个隐藏单元没有意义。
因此,要对w参数做随机初始化,打破对称性;初始化参数为较大的值也不好,因为这样会使得activations接近0或者1,导致梯度消失或者梯度爆炸问题。
使用Relu激活函数时,多使用He initialization:
np.random.randn ( n l , n l − 1 ) ⋅ 2 n l − 1 \text{np.random.randn}(n^l,n^{l-1}) \cdot \sqrt{\frac{2}{n^{l-1}}} np.random.randn(nl,nl−1)⋅nl−12
另外Xavier initialization是用随机值乘 1 n l − 1 \sqrt{\frac{1}{n^{l-1}}} nl−11。
为训练策略寻找一个算法,以往我们使用的都是梯度下降算法,实际上我们可以使用其优化算法对模型进行更快速的训练。
两种方法:1.随机取值;2.从大范围到小范围(从粗糙到精细)
CNN公式推导:https://blog.csdn.net/lu597203933/article/details/46575871
关于CNN的几个探讨:
https://mp.weixin.qq.com/s?__biz=MzI4MTQ2NjU5NA==&mid=2247487812&idx=1&sn=0a7deac6f105f9430a0d9d6aaf4db852&chksm=eba992c9dcde1bdf84f394988c0bbfbabee34f146163e97e1f280103c887b5fa0346a1677f93&mpshare=1&scene=23&srcid=09113lPVAlw4BJ1uCjFpub0i#rd
LSTM:http://colah.github.io/posts/2015-08-Understanding-LSTMs/
RNN的使用场景:语音识别,图像标注,翻译。。。
https://blog.csdn.net/xwd18280820053/article/details/76026523