课程视频地址: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$

超参数优化

算法中很有多超参数,我们应该如何选择呢?这里需要用之前介绍交叉验证来处理——即我们尝试不同的超参数组合,然后比较交叉验证集上的效果,如果我们的超参数不多,可以使用网格搜索,否则应该使用随机搜索,如下图所示