CS231 第六讲 训练神经网络(上)
课程视频地址:https://study.163.com/courses-search?keyword=CS231
课程主页:http://cs231n.stanford.edu/2017/
这一讲主要介绍训练神经网络的一些技巧。
激活函数
回顾神经元的架构
我们首先进行线性运算,接着使用激活函数$f$,常用激活函数如下
下面分别介绍这几个激活函数。
Sigmoid
Sigmoid函数有如下三个问题:
1.饱和的神经元会使得梯度消失。
这是因为当$x$绝对值很大时,Sigmoid函数的导数几乎为$0$(这点从图像中就能看出),而这会使训练过程很缓慢。
2.Sigmoid函数输出结果的均值不是$0$。
由于Sigmoid函数输出结果都大于$0$,由乘法门的含义可知,这会导致梯度的符号都相同,这也不利于训练。
3.$\exp()$有一定的计算量。
这个算是比较次要的原因,感觉主要是和之后的ReLU作对比。
tanh
tanh函数可以克服上述第2个问题,因为输出结果的均值为$0$,但是问题1,3依然没有解决。
ReLU
ReLU函数可以有效克服问题1,但是输出结果的均值不是$0$,并且会导致部分神经元“死亡”(当$x<0$时输出永远为$0$)
Leaky ReLU
Leaky ReLU保留了ReLU的优点,并且有效解决了ReLU导致的神经元“死亡”问题。
实际中,还有Parametric Rectifier (PReLU),这里多引入一个系数$\alpha$,即
$\alpha$可以通过反向传播来学习。
ELU
ELU和Leaky ReLU类似,但是将小于$0$部分修改为指数函数,这样的好处是在$0$这一点可导,更为平滑,坏处是需要计算$\exp()$,加大计算量。
Maxout
Maxout实际上式前面三种激活函数的推广,激活函数为
这种激活函数的问题是参数数量会加倍。
在实际中,大多数情况都是使用ReLU,如果效果不好,可以尝试Leaky ReLU,ELU以及Maxout,如果这些激活函数效果都不好,可以尝试tanh(不要期望太多),实际中一般从不使用Sigmoid。
数据预处理
比较简单的数据预处理方式为将数据零均值化以及方差归一化,效果如下图所示
其他的方法还有PCA以及Whitening,这里略过(CNN中不常用)。
在实际中,对于图像数据,我们只要将数据零均值化即可。
权重初始化
第一种初始化方式为将权重全部初始为$0$,不难发现这样会导致每个神经元的输出都相同,反向传播中更新的梯度也相同,从而权重始终相等,神经元失去效果。
第二种初始化方式为随机初始化为很小的值,这样对小网络合理,但是当网络层数增加后,会导致一些问题。例如10层神经网络,按照上述初始化方式,做实验可得如下结果
上述现象可以描述为输入输出的方差相差太多,一个合理的假设是我们希望输入和输出的方差比较接近,假设
那么
前三步运用了方差的性质,第四步利用了
最后一步利用了$x_i$独立同分布,$w_i$独立同分布。
所以要使得$x$与$s$的方差相同,应该有
所以可以用如下初始化方式
w = np.random.randn(fan_in, fan_out) / np.sqrt(fan_in)
利用这种初始化得到图像为
这种初始化方式被称为“Xavier initialization”。
如果激活函数为ReLU,大约一半的神经元会“死亡”,所以初始化方式修改为
w = np.random.randn(fan_in, fan_out) / np.sqrt(fan_in / 2)
批量标准化
批量标准化是指在全连接层或者卷积层之后对数据进行如下处理
使得数据满足$0$均值以及方差为$1$,此时的网络架构为
现在的问题是,我们是否希望均值为$0$以及方差为$1$?为了让算法效果更好,增加两个参数$\gamma^{(k)},\beta^{(k)}$,每层的输入为
这里$\gamma^{(k)},\beta^{(k)}$为参数,需要通过反向传播来训练,实际中的算法步骤为
注意第4行分母增加了$\epsilon$,这是为了防止分母为$0$
超参数优化
算法中很有多超参数,我们应该如何选择呢?这里需要用之前介绍交叉验证来处理——即我们尝试不同的超参数组合,然后比较交叉验证集上的效果,如果我们的超参数不多,可以使用网格搜索,否则应该使用随机搜索,如下图所示