一、Dropout简介

在2012年,Hinton在其论文《Improving neural networks by preventing co-adaptation of feature detectors》中提出Dropout。当一个复杂的前馈神经网络被训练在小的数据集时,容易造成过拟合。为了防止过拟合,可以通过阻止特征检测器的共同作用来提高神经网络的性能。

Dropout也是正则化的一种方法,它可以随机掐死一部分神经元,阻止它们的前向和方向传播,有效缓解过拟合的发生。

Dropout简单来说就是:我们在前向传播的时候,让某个神经元的激活值以一定的概率p停止工作(掐死),这样可以使模型泛化性更强,因为它不会太依赖某些局部的特征,随机搭配不同的神经元。(在预测阶段不使用dropout)

Dropout缺点:训练时间增大

1D神经网络 神经网络dropout_机器学习

二、Dropout为何有效?

1、模型集成说:dropout相当于生成了若干更瘦小的神经网络。对于N个神经元的神经网络来说,dropout可以看做2的N次方个共享某些参数模型的集成(N等于全连接层的神经元的数量)。Dropout率等于0.5时效果最好,因为0.5时随机生成的网络结构最多。模型集成“取平均”让一些“相反的”拟合互相抵消。相互依赖的大部队(神经网络)不能适应各种各样的变化,应变能力不强,容易团灭,但dropout一些神经元后就像打游击战了,很灵活,可以对付各种情况。

1D神经网络 神经网络dropout_机器学习_02

2、强制协同工作说:强迫每个神经元每次和随机挑选出来的不同神经元共同工作,减弱了神经元节点间的联合适应依赖性。

1D神经网络 神经网络dropout_深度学习_03

3、有性繁殖说:无性繁殖的基因很少变异,但有性繁殖可以将海量的基因片段重新组合,每个基因片段都要与其它基因片段协同工作。

1D神经网络 神经网络dropout_1D神经网络_04

4、记忆消除说:将死记硬背的过拟合的知识掐死在摇篮中,学习大而化之的知识。

1D神经网络 神经网络dropout_人工智能_05

5、数据增强说:总可以找到一个数据样本,使得在原始的网络上也能到达dropout单元后的效果。比如,对于某一层网络,dropout一些单元后,形成的结果是(1.5, 0,2.5, 0,1,2,0),其中 0 是被drop的单元,那么总能找到一个样本,使得到结果也是如此。这样,每一次dropout其实都相当于增加了数据样本。

1D神经网络 神经网络dropout_深度学习_06

但数据很小的时候加了dropout也会过拟合。

1D神经网络 神经网络dropout_人工智能_07

三、代码实现

下面是Keras中Dropout的实现,它是屏蔽掉某些神经元,使其激活值为0以后,对激活值向量x1……x1000进行放大,也就是乘以1/(1-p)。函数中,x是本层网络的激活值。Level就是dropout就是每个神经元要被丢弃的概率。

# coding:utf-8
import numpy as np
 
# dropout函数的实现
def dropout(x, level):
    if level < 0. or level >= 1: #level是概率值,必须在0~1之间
        raise ValueError('Dropout level must be in interval [0, 1[.')
    retain_prob = 1. - level
 
    # 我们通过binomial函数,生成与x一样的维数向量。binomial函数就像抛硬币一样,我们可以把每个神经元当做抛硬币一样
    # 硬币 正面的概率为p,n表示每个神经元试验的次数
    # 因为我们每个神经元只需要抛一次就可以了所以n=1,size参数是我们有多少个硬币。
    random_tensor = np.random.binomial(n=1, p=retain_prob, size=x.shape) #即将生成一个0、1分布的向量,0表示这个神经元被屏蔽,不工作了,也就是dropout了
    print(random_tensor)
 
    x *= random_tensor
    print(x)
    x /= retain_prob
 
    return x
 
#对dropout的测试,大家可以跑一下上面的函数,了解一个输入x向量,经过dropout的结果  
x=np.asarray([1,2,3,4,5,6,7,8,9,10],dtype=np.float32)
dropout(x,0.4)