cs231n 学习 -- Lecture 6/7 Training Neural Networks

激活函数 Activation Functions

        如下图所示,分别为神经元及其数学建模图,当叠加到细胞体的信号高于某个阈值时,神经元可以发射,沿轴突发送尖峰,在数学模型中,假定只有发射速率传达信息,基于此,我们使用激活函数模拟神经元的激发速率。在数学统计中,我们用来赋予模型非线性特性。

         比较常见的激活如下,从早期比较受欢迎的sigmoid函数到tanh,再到现在比较流行的ReLU.

        其优缺点比较

Sigmoid tanh ReLU

+ 输出压缩到[0 ,1]

- 饱和后梯度消失

- 输出不是相对0点对称

      (梯度产生锯齿)

- 指数运算太昂贵

+ 输出压缩到[-1 ,1]

+ 出相0点对

- 饱和后梯度消失

- 指数运算太昂贵

+ 不会饱和

+ 计算高效

+ 相比sigmoid/tanh收敛更快

-  输出不是相对0点对

-  神经网络可能在训练中死掉

        实际应用中,ReLU还是用的比较多,但是要注意学习速率的问题。也可以尝试Leaky ReLU / Maxout / ELU等激活函数。

数据预处理 Data Preprocessing

        中心化(零均值化)是最常见的预处理方式,两种操作方法

  • 减去图像平均值  以 CIFAR-10 为例, mean image = [32,32,3] array        e.g. AlexNet 
  • 减去每个通道的平均值  mean along each channel = 3 numbers       eg. VGGNet

        标准化是对数据维度进行操作,使它们具有大致相同的比例。在图像处理的情况下,像素的相对比例已经近似相等(并且在0到255的范围内),因此不必严格地执行该额外的预处理步骤。

权值初始化 Weight Initialization

        Proper initialization is an active area of research…
        不要全部初始化为0。如果网络中的每个神经元计算相同的输出,那么它们也将在反向传播期间计算相同的梯度并经历完全相同的参数更新。换句话说,如果神经元的权重初始化相同,则神经元之间不存在不对称的来源。
        实际应用中,在使用ReLU激活单元时,建议使用 w = np.random.randn(n) * sqrt(2.0/n) 进行初始化。
批量规范化 Batch Normalization

        该文章给出了BN的相关原理和推导,通过(1)把输入数据规范化为近似标准正态分布,通过式(2)可以进行压缩和平移。

                                                           x^{(k)} \rightarrow \hat{x} ^{(k)} = \frac{x^{(k)}-E[x^{(k)}]}{\sqrt{Var[x^{(k)}]}}     (1)
                                                          y^{(k)} = \gamma ^{(k)}\hat{x} ^{(k)} + \beta ^{(k)}                   (2)

        Batch Normalization 算法如下:
                                                         input:\ss =\left \{ x_{1...m} \right \}; Parameters\; to\, be\, \, learned:\gamma ,\beta
                                                         output:\! \left \{ y_{i} = BN_{\gamma ,\beta }\right (x_{i})\}
                                                          \mu_{\ss} \leftarrow \frac{1}{m}\sum_{i=1}^{m}x_{i}
                                                         \sigma_{\ss }^{2} \leftarrow \frac{1}{m}\sum_{i=1}^{m}(x_{i}-\mu_{\ss } )^{2}
                                                         \hat{x} _{i} \leftarrow \frac{x_{i}-\mu _{\ss }}{\sqrt{\sigma_{2}^{\ss }+\epsilon }}
                                                         y_{i} \leftarrow \gamma\hat{x_{i}} + \beta \equiv BN_{\gamma ,\beta } (x_{i})

优点: 

  • 缓解了梯度传递问题,使模型适应更大的学习率,加速了训练;
  • 起到了正则化的作用

具体在文章中有相关描述。

训练过程监控 Babysitting the Learning Process

1. 数据预处理
2. 选择框架,输入,神经元个数,输出
3. 取一小部分样本,不使用正则化,进行训练,保证训练过拟合,证明网络正常运行
4. 扩大训练集,找到合适的学习速率                 参考文章

超参数优化 Hyperparameter Optimization

常见的超参数设置包括:
    1. 学习速率初始化
    2. 学习速率衰变常数
    3. 正则化强度
在对数刻度上搜索超参数,随机搜索优于网格搜索。

SGD存在的问题

不同方向上的收敛速度差别较大

局部优化

saddle point ,梯度下降受阻

噪声干扰

引入动量 Momentum

SGD

while True:
    dx = compute_gradient(x)
    x += learning_rate * dx

SGD+Momentum

vx = 0

while True:
    dx = compute_gradient(x)

    vx = rho * vx + dx
    x += learning_rate * dx

rho物理学上代表摩擦力,一般为0.9或0.99

改进结果如图

Adagrad - 动态调整学习率的优化器

# Assume the gradient dx and parameter vector x
grad_squared = 0
while True:
    dx = compute_gradient(x)
    grad_squared += dx * dx
    x -= learning_rate * dx / (np.sqrt(grad_squared) + 1e-7)

Adam 使用最多

first_moment = 0
second_moment = 0
while True:
    dx = compute_gradient(x)
    first_moment = beta1 * first_moment  + (1 - beta1) * dx
    second_moment = beta2 * second_moment + (1 - beta2) * dx *dx
    x -= - learning_rate * first_moment / (np.sqrt(second_moment) + 1e-7)

几种算法的收敛图如下,实际上大多数案例中都默认使用Adam算法。

如何提高模型性能 : 添加正则项

猜你喜欢

转载自blog.csdn.net/wu472269100/article/details/86494429