Keras Dropout图层似乎不起作用

时间:2017-10-22 19:20:15

标签: tensorflow keras

我有一个相对简单的Keras模型,我见过很多其他人在文献中使用过的模型。简化形式,如下所示:

model = Sequential()
model.add(Dense(n, activation="relu"))
model.add(Dropout(dropout))
model.add(Dense(m, activation="relu"))
model.add(Dropout(dropout))
model.add(Dense(p))

其中n,m,p是一些任意维度,dropout是辍学率。我像这样训练模型

                model.compile(loss='mae', optimizer='adam')

                lossHistory = keras.callbacks.History()
                model.fit_generator(train_generator,
                                    steps_per_epoch=steps_per_epoch,
                                    epochs=epochs,
                                    validation_data=valid_generator,
                                    validation_steps=validation_steps,
                                    callbacks = [lossHistory])

这里没什么好疯狂的。问题是dropout参数似乎没有效果。我说的原因是我得到了很多过度拟合,不管我使用的丢失值(我已经尝试过0.1,0.2,...,0.95)。

因此,为了尝试诊断问题,我想尝试极值(dropout = 0和1)。我可能误解了丢失数字代表什么,但是其中一个值会导致一切都被丢弃,从而使模型基本上无法处理(因为它应该返回一个常量输出)。但是......如果辍学值为0,则训练看起来像:

1/20 [>.............................] - ETA: 139s - loss: 0.9623
2/20 [==>...........................] - ETA: 87s - loss: 0.7758 
3/20 [===>..........................] - ETA: 68s - loss: 0.6146

然后辍学值为1,训练看起来像:

 1/20 [>.............................] - ETA: 178s - loss: 0.2134
 2/20 [==>...........................] - ETA: 102s - loss: 0.2295
 3/20 [===>..........................] - ETA: 76s - loss: 0.2368 

这应该是不可能的。我在这里想念的是什么?在我的Tensorflow模型中,Dropout对我来说非常有用,但是我在Keras中实现它的方式似乎有些错误......

仅为了记录,model.summary()的片段返回

dense_1 (Dense)              (None, 50)                550       
_________________________________________________________________
dropout_1 (Dropout)          (None, 50)                0         
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 51        

所以在我看来,辍学层实际上是在模型中(不是一些愚蠢的错误,我不小心将其从模型中排除)。

1 个答案:

答案 0 :(得分:2)

将dropout设置为0或1会导致根据源代码中的the layer definition忽略dropout图层。

def call(self, inputs, training=None):
    if 0. < self.rate < 1.:
        noise_shape = self._get_noise_shape(inputs)

        def dropped_inputs():
            return K.dropout(inputs, self.rate, noise_shape,
                             seed=self.seed)
        return K.in_train_phase(dropped_inputs, inputs,
                                training=training)
    return inputs