Dropout的意义
在学习时,随即的去掉某些特征,以此避免过拟合。
Dropout层源代码
dropout层在layer下的core.py中
class Dropout(Layer):
'''Applies Dropout to the input. Dropout consists in randomly setting
a fraction `p` of input units to 0 at each update during training time,
which helps prevent overfitting.
# Arguments
p: float between 0 and 1. Fraction of the input units to drop.
# References
- [Dropout: A Simple Way to Prevent Neural Networks from Overfitting](http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf)
'''
def __init__(self, p, **kwargs):
self.p = p
if 0. < self.p < 1.:
self.uses_learning_phase = True
self.supports_masking = True
super(Dropout, self).__init__(**kwargs)
def call(self, x, mask=None):
if 0. < self.p < 1.:
x = K.in_train_phase(K.dropout(x, level=self.p), x)
return x
def get_config(self):
config = {'p': self.p}
base_config = super(Dropout, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
分析
功能实现
其中的call方法调用了K.dropout来处理具体的事情。
根据前面的import得知,这个K就是backend。 keras的backend有两个,一个是theano,一个是tensorflow
theano的dropout
在backend的theano_backend.py中
def dropout(x, level, seed=None):
if level < 0. or level >= 1:
raise Exception('Dropout level must be in interval [0, 1[.')
if seed is None:
seed = np.random.randint(10e6)
rng = RandomStreams(seed=seed)
retain_prob = 1. - level
x *= rng.binomial(x.shape, p=retain_prob, dtype=x.dtype)
x /= retain_prob
return x
这个函数里使用了固定的随机数种子(10e6), 用户可以通过seed函数指定。
随即使用二项式分布的随机数种子生成了一串随机数。这些随机数是0或者1
他们服从二项分布。 乘以x后,x若干项被置为0. 然后将x除以(1-lever),使得所有的x保持加为1
这样就实现了Dropout
in_train_phase
这个函数的作用就是说, 当我训练的时候我采用dropout,当我测试的时候,我不采用。他里面调用了一个switch语句
def switch(condition, then_expression, else_expression):
'''condition: scalar tensor.
'''
return T.switch(condition, then_expression, else_expression)
def in_train_phase(x, alt):
x = T.switch(_LEARNING_PHASE, x, alt)
x._uses_learning_phase = True
return x