计算机视觉中的深度学习10: 神经网络的训练1
日期: 2020-09-20 分类: 个人收藏 505次阅读
Slides:百度云 提取码: gs3n
第9课讲的是神经网络的软硬件,感觉比较科普,不做总结。
总览
- 单次设置 
  
- 激活函数
 - 数据预处理
 - 权重初始化
 - 正则化
 
 - 动态训练 
  
- 学习率规划
 - large-batch 训练;
 - 超参数优化
 
 - 训练后 
  
- 模型融合
 - 迁移学习
 
 
今天第一讲讲解的是第一点,第二讲将介绍第二点和第三点。
激活函数

之前也介绍了激活函数是什么,不同的激活函数在训练上,在效果上,在解决问题的方面都各有侧重。下面一一来介绍。

Sigmoid
非常常用的激活函数,在很多线性分类的machine learning模型中也会有用到。

 
     
      
       
        
         σ
        
        
         (
        
        
         x
        
        
         )
        
        
         =
        
        
         
          1
         
         
          
           1
          
          
           +
          
          
           
            e
           
           
            
             −
            
            
             x
            
           
          
         
        
       
       
        \sigma(x) = {1\over 1+e^{-x}}
       
      
     σ(x)=1+e−x1
- 将函数值限制在[0, 1]之间
 - 由于它们可以很好地模拟神经元的饱和“触发率”,因此在历史上很受欢迎
 - 通常被用于表示概率,很适合用于表示boolean
 - 也是一种非常不错的非线性关系的表达
 
缺点
- 饱和的神经元将使得梯度下降效果糟糕 
  
- 我们可以看到在接近 ± ∞ ±\infin ±∞的时候,梯度是0,这也使得sigmoid难以训练
 - 这种影响甚至会通过链式法则传递到之前的神经元中,导致整个网络的灾难性慢收敛
 - 这是这个函数被弃用的最最最主要原因,其他缺点都是可以接受的
 
 - sigmoid函数的输出中心不是0 
  
- 在神经元输入全为正的情况下,在计算梯度的时候,w中的每一维都会同为正数。这也导致了训练收敛缓慢。
 
虽然在低维处理上面,没什么问题,但是当w是高维的时候,会受到很大的影响。
 - Exp()的计算开销大
 
Tanh

 此函数的函数值范围为[-1, 1],解决了sigmoid函数中心不在0的缺点。
但是还是继承了sigmoid最坏的缺点,在两端的梯度几乎为0.
ReLu

 
     
      
       
        
         f
        
        
         (
        
        
         x
        
        
         )
        
        
         =
        
        
         m
        
        
         a
        
        
         x
        
        
         (
        
        
         0
        
        
         ,
        
        
         x
        
        
         )
        
       
       
        f(x)=max(0, x)
       
      
     f(x)=max(0,x)
- 不会在远端让梯度为0
 - 计算上非常高效
 - 收敛比sigmoid、tanh快多了
 
缺点
-  
不以0为中心
 -  
当x<0时,梯度的情况令人担忧
- 甚至情况比sigmoid还糟糕,因为当x<0时,它完全不会收敛。
 - 有时候,我们在初始化ReLu神经元的bias的时候,我们不会设置为0,而是0.01
 
Leaky ReLU

继承了ReLu的优点,并且在x<0的时候,梯度不会变成0 
扩展开后
f ( x ) = m a x ( α x , x ) f(x)=max(\alpha x, x) f(x)=max(αx,x)
其中 α \alpha α是backprop的一个超参数。
Exponential Linear Unit

- 继承了ReLu的所有优点 
  
- 除了Exp()的计算消耗比较大
 
 - 均值输出接近0 
  
- 这点我有点没明白
 
 - 相比于Leaky ReLu,在x<0的表现,能更加robust,对noise不敏感
 
Scaled Exponential Linear Unit (SELU)

- ELU的扩展版本,在深度网络中表现更好
 - 能够自我归一化,使得不需要在训练的时候进行BatchNorm
 - 此处给出的 α \alpha α和 λ \lambda λ是经过试验测试以及数学论证,得出来效果最好的两个值。
 
总结
- 无脑使用ReLu,中正平和,不会有太多问题
 - 使用ReLu的其他变形,但是基本不会有太多影响,可能是最后0.1%的优化
 - 不要使用sigmoid和tanh
 
PS: 为什么使用的都是单调函数,而不是类似于sin,cos这样的函数,是因为对于一个y,如果存在多个x值,会使得信息有所混乱,导致NN不容易学习特征。
数据预处理

- 为什么想要将数据中心变成0 
  
- 比如,在之前提到的sigmoid中,如果数据集全是正的,或者全是负的,会导致W的gradient的方向是同一个符号的。这个问题就可以通过修正数据集的中心来解决。
 
 - 归一化的好处。 
  
- 降低noise的影响
 - 将数据缩小到一个合理的范围,使得W更好收敛。
 
 
这几个操作,都是在图片识别中相当常用的方式。对于其他种类的问题,都有一些特殊的数据预处理方法。
还有接下里两种PCA和whitening。
前者是主成分分析,降维的常用算法。
 后者是白化,将数据集的特征之间相关性降低;使得所有特征具有相同的方差。
 
权重初始化
全0
Q: 如果一个神经网络,将weight和bias全都初始化为0,这是一个好的方式吗?
A:当然不行,这样所有的输出也会是0(假设激活函数是以0为中心的),然后所有的梯度将会是一样。
较小的随机数
用正态分布,中心为0,std=0.01.
W = 0.01 * np.random.randn(Din, Dout)
 
对于一个小型的神经网络,这是一个非常不错的初始化方法。
 对于更深的神经网络,这就不是一个很好的方式了。
问题1
假设有6层神经网络,都用上述方式去初始化W。
我们可以明显感觉到随着层数的增加,因为W的累乘,output也会越来越小。
再考虑考虑梯度的变化。
 
 我们可以看到因为W逐渐减小,梯度也越发向0集中。如果一个神经网络非常深,那么结果就是output全是0,没有任何梯度,也没法学习。
问题2
那么我们用一个稍微大一些的std去初始化呢?
比如,std=0.05

 梯度的分布如上
 我们可以看到,梯度往-1和1聚集,那么local gradient就会变成0。
Xavier Initialization

 将正则分别的std设置为1/sqrt(Din),从而使得每一个输入输出都能有恰好的大小。

 对于卷积层而言,Din是kernel_size ^ 2 * input_channels
原理
这样,输入和输出的方差是一样的
 
 因此保证了gradient分布地均匀
激活函数是ReLu的情况呢?
之前我们都是使用tanh作为激活函数,那么使用ReLu呢?
 
 我们发现,梯度再一次聚集了,他们聚集在0处,再一次使得训练难以进行。
 
Kaiming / MSRA Initialization
进行修正,std = sqrt(2 / Din)
结果如下
 
 之所以要这么修正,正是我们想要保持输入输出的variance一致。
Residual Networks

 对于这个结构,如果我们使用MSRA,我们能够得出Var(F(x)) = Var(x)。
 但是我们的实际输出是Var(F(x)+x) > Var(x),经过每一个Block,variance都会增长。
解决办法,对第一个conv使用MSRA,对于第二个conv赋值为0.
 那么这个时候,Var(F(x)+x) = Var(x)
正则化
其实怎么判断overfit,是一个需要经验的工作。
 
在Loss函数后面增加一项

 常用的几种

Dropout
在向前传播的过程中,随机将一些神经元的输出设置为0
这个概率是一个超参数,0.5是一个比较常用的
 
 
dropout的作用是
- 强制网络具有冗余表示形式 
  
- 即,舍弃了一部分神经元也能提取出相似的特征
 
 - 防止特征的共适性
1.即,两个特征不一定要一同出现才能让机器做出判断 

另一种解释
Dropout是一种多模型(共享参数)的融合。
 每一个二元的取舍都是一个新的模型。
对于一个4096个单元的全连接层,会有 2 4096 2^{4096} 24096 ~ 1 0 1233 10^{1233} 101233种可能性
测试中的dropout
随机将输出舍弃
这并不是一个明智的决定。
因为我们可以用数据公式论证一下,这样的行为和在training中的dropout产生的输出期望,并不一样。

这种东西,复杂且难以估量。并不是一个理论上非常优秀的结果。
输出乘以dropout概率
测试的时候
 
     
      
       
        
         E
        
        
         [
        
        
         a
        
        
         ]
        
        
         =
        
        
         
          w
         
         
          1
         
        
        
         x
        
        
         +
        
        
         
          w
         
         
          2
         
        
        
         y
        
       
       
        E[a]=w_1x+w_2y
       
      
     E[a]=w1x+w2y
 训练的时候
 
 我们发现,在测试的时候,并不需要dropout
 我们只需要在输出的时候,乘以dropout的概率,即可

DropConnect
和一般的Dropout不同的是,它是,神经元之间的连接是随机的
这样在测试的时候,我们只需要将所有的东西连上即可。
 
Fractional Pooling
使用随机的pooling区域。
测试的时候,取各个sample size pooling结果的平均值

Stochastic Depth
随机跳过一些ResBlock
测试的时候,使用全网络
 
Stochastic Depth
遮盖(随机将一部分像素设置为0)
 
 在小的数据集上表现优秀,在大的数据集上更加少见。
混合

数据扩充
通常而言,训练集肯定是越多越好,但是有时候训练集并不是很足够,我们就需要一些别的方式来扩充数据。
这是我之前写的博文的例子,  除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
标签:机器学习与数学模型
精华推荐
