dropout原理及代码解析

一.dropout概念

  • 在训练的时候,以一定的概率使得某些神经元从网络中丢弃

dropout原理及代码解析_第1张图片

二.dropout原理解释

1.从ensemble的角度理解

  • 由于每个epoch前向的时候都是以一定概率随机的丢弃某些神经元,所以每个epoch训练的时候其实是在训练不同的网络,类似bagging。

2.从不同动机的角度来理解

  • 类比有性繁殖和无性繁殖,无性繁殖直接从父代保留大段的优秀基因,有性繁殖则是将基因随机拆解破坏了大段基因的联合适应性,从而有更多的多样性。
  • dropout则是强迫一个神经元和随机挑选出来的其他神经元共同工作,削弱了神经元节点之间的联合适应性,增强了泛化能力。

三.dropout细节

1.训练的时候

  • 以一定概率抛弃神经元
  • 通过乘以一个满足概率为p的伯努利,0-1分布的随机数实现

dropout原理及代码解析_第2张图片

2.测试的时候

  • 不抛弃任何一个神经元
  • 对每个单元的参数预先乘以概率p(训练的时候预设的不丢弃的概率),使得训练和预测的输出期望保持一致。

3.代码层面

  • 对于一个神经元,如果它在训练的时候以概率p丢弃,那么它输出的期望为px+(1-p)0=px;测试的时候不丢弃,所以期望为x。
  • 为了维持训练和测试的时候输出的期望保持一致,在代码上有两种做法,一种是在训练的时候对输出除以p,另外一种则是在预测的时候对输出乘以p
  • 在keras中的dropout源码则是采用第一种方式,如下所示:
def dropout(x, level, noise_shape=None, seed=None):
    """Sets entries in `x` to zero at random,
    while scaling the entire tensor.
    # Arguments
        x: tensor
        level: fraction of the entries in the tensor
            that will be set to 0.
        noise_shape: shape for randomly generated keep/drop flags,
            must be broadcastable to the shape of `x`
        seed: random seed to ensure determinism.
    """
    if level < 0. or level >= 1:
        raise ValueError('Dropout level must be in interval [0, 1[.')
    if seed is None:
        seed = np.random.randint(1, 10e6)
    if isinstance(noise_shape, list):
        noise_shape = tuple(noise_shape)

    rng = RandomStreams(seed=seed)
    retain_prob = 1. - level

    if noise_shape is None:
        random_tensor = rng.binomial(x.shape, p=retain_prob, dtype=x.dtype)
    else:
        random_tensor = rng.binomial(noise_shape, p=retain_prob, dtype=x.dtype)
        random_tensor = T.patternbroadcast(random_tensor,
                                           [dim == 1 for dim in noise_shape])
    x *= random_tensor
    x /= retain_prob    %除以丢弃的概率
    return x

四.参考

  1. 理解dropout
  2. 论文笔记:dropout
  3. Keras源代码阅读-Dropout
  4. keras源码
  5. 李理:卷积神经网络之Dropout

你可能感兴趣的:(深度学习)