1. 激活函数:
1)Sigmoid,σ(x)=1/(1+e-x)。把输出压缩在(0,1)之间。几个问题:(a)x比较大或者比较小(比如10,-10),sigmoid的曲线很平缓,导数为0,在用链式法则的时候,后一层传回来的导数乘以sigmoid的导数也是0了,换句话说,对于sigmoid饱和的区域后一层的导数传不到前面去了。(b)输出永远为正,即下一层的输入永远为正,我们希望输入的均值为0。(c)exp还是稍微有点难计算。
2)tanh(x),输出压缩在[-1,+1]之间,比sigmoid的进步在于输出有正有负以0为中心。
3)ReLU(Rectified Linear Unit),f(x)=max(0,x)。优点:(a)在正方向不会饱和。(b)计算简单。(c)实际中比sigmoid和tanh都收敛的快的多。(d)更像生物学神经元。缺点:(a)not zero-centered output。(b)负方向全部是0.
实际使用中,会给ReLU神经元一个正向的bias,比如0.01。
4)Leaky ReLU,f(x)=max(0.01x, x)。优点:有ReLU的所有优点,另外它在负方向也不会饱和,所以总是不会失效。
类似的有Parametric Rectifier (PReLU),f(x)=max(αx, x)。
5)Exponential Linear Units (ELU)。x>0时,f(x)=x, x<=0时,f(x)=α(exp(x)-1)。优点:有ReLU的所有优点,相比于Leaky ReLU,它更鲁邦。但计算过程需要exp(),计算稍微复杂一点。
6)Maxout “Neuron”,f(x)=max(wT1x+b1, wT2x+b2),是对ReLU和Leaky ReLU的推广,正负方向都是线性,不会饱和。缺点是花了两倍的参数。
总结:(a)用ReLU,注意学习率。(b)尝试Leaky ReLU/Maxout/ElU。(c)尝试tanh,但不要期望太好。(d)不要用sigmoid。
2. 数据预处理:中心化,所有样本的均值设为0,标准差设为1。中心化的目的是把每个样本都放到同一个尺度下去考虑,对于图像来说,由于像素的值已经被归一化到0~255之间,所以中心化的诉求会轻一些。 有时候还会用PCA去掉相关性,让协方差矩阵成为对角矩阵。也会Whiten操作,把协方差矩阵变换为单位矩阵。
3. 权重W的初始化:这是很重要的研究课题,有很多paper。
1)小随机数,W = 0.01*np.random.randn(D, H)。这种方式对浅网络有效,对深层网络不好,每层的输出会很快衰减到0。
2)大随机数,W = np.random.randn(D, H),很容易饱和。
3)Xavier initialization,W = np.random.randn(node_in, node_out) / np.sqrt(node_in),Glorot et al., 2010,论文的数学推导是基于线性激活函数,对于非线性激活函数就无效了。
4)He initialization,W = np.random.randn(node_in, node_out) / np.sqrt(node_in / 2),He et al., 2015,直观的解释是:在ReLU网络中,假定每一层有一半的神经元被激活,另一半为0,所以,要保持variance不变,只需要在Xavier的基础上再除以2。
4. Batch Normalization:在线性变换(全连接层、卷积层)之后对输出进行归一化,然后再非线性化激活,Loffe and Szegedy,2015。直观的解释是:我们想要的是在非线性activation之前,输出值应该有比较好的分布(例如高斯分布),以便于back propagation时计算gradient,更新weight。Batch Normalization将输出值强行做一次Gaussian Normalization和线性变换。
归一化成均值为0,方差为1之后,我们也不能保证说这种归一化就一定好,于是往往又会给它*度调整自己的均值和方差。
Batch Normalization降低了对初始化好坏的依赖。
注意在训练阶段,mean/std是基于batch计算出来的,而在测试阶段,mean/std则是用训练阶段得到的某个固定值(比如取平均),而不是基于bach计算。
5. 深度学习的一般流程:
1)归一化输入,减去均值,除以方差。
2)检查Loss是否合理,先不要考虑正则化项,得到一个loss值,看这个值合理么;然后考虑正则化项,这时候的loss值应该比之前大了一些。
3)先用小的训练集,关掉正则化项,这时候算法要能过拟合,得到很小的loss,接近0。
4)用全部的训练集,设一个小的正则化项,找learning rate使得loss可以下降。Loss不下降或者下降很慢,说明learning rate设小了,需要增大。Loss变成无穷大NaN,说明learning rate设太大了,需要减小。Learning rate一般在[1e-3, 1e-5]。
6. 超参数的选取:用cross-validation从粗糙到精细地搜索。开始,只需要迭代几次,就可以很直观的看超参数如何影响,最好是把超参数在它的空间随机选取,如果一定要有规律,那就按10的n次方选取,线性的搜索太慢了。然后,迭代多一点,更精细的找。如果loss超过最开始值的三倍,就可以放弃这组参数了。另外一个经验是:更新的量和原来的值的比值update/value在0.001、0.01周围比较好,太大太好都不好。
超参数包括:网络的结构,学习率,正则化项等。这些参数里,学习率是最影响结果的,要优先调,正则化什么的相对次要一些。