如何在Keras模型中停用通过training = True调用的辍学层?

时间:2019-08-09 22:53:10

标签: python tensorflow keras tf.keras dropout

我希望查看训练tf.keras模型的最终输出。在这种情况下,它将是来自softmax函数的一系列预测,例如[0,0,0,1,0,1]。

此处的其他线程建议使用model.predict(training_data),但这不适用于我的情况,因为我在训练和验证时使用了辍学功能,因此神经元被随机丢弃,并使用相同的数据再次进行预测结果不同。

def get_model():
    inputs = tf.keras.layers.Input(shape=(input_dims,))
    x = tf.keras.layers.Dropout(rate=dropout_rate)(inputs, training=True)
    x = tf.keras.layers.Dense(units=29, activation='relu')(x)
    x = tf.keras.layers.Dropout(rate=dropout_rate)(x, training=True)  
    x = tf.keras.layers.Dense(units=15, activation='relu')(x)
    outputs = tf.keras.layers.Dense(2, activation='softmax')(x)
    model = tf.keras.Model(inputs=inputs, outputs=outputs)
    model.compile(optimizer='adam',
                  loss='sparse_categorical_crossentropy',      
                  metrics=['sparse_categorical_accuracy'])
    return model

myModel = get_model()
myModel.summary()
myModel.fit(X_train, y_train,
           batch_size = batch_size,
           epochs= epochs,
           verbose = 1,
           validation_data = (X_val, y_val))

在tensorflow中,您可以很容易地在训练后获取模型的输出。这是一个来自Github repo的示例:

input = tf.placeholder(tf.float32, shape=[None, INPUT_DIMS])
labels = tf.placeholder(tf.float32, shape=[None])

hidden = tf.nn.tanh(make_nn_layer(normalized, NUM_HIDDEN))
logits = make_nn_layer(hidden, NUM_CLASSES)
outputs = tf.argmax(logits, 1)

int_labels = tf.to_int64(labels)
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits, int_labels, name='xentropy')
train_step = tf.train.AdamOptimizer().minimize(cross_entropy)

correct_prediction = tf.equal(outputs, int_labels)
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())

    validation_dict = {
        input: validation_data[:,0:7],
        labels: validation_data[:,7],}

    for i in range(NUM_BATCHES):
        batch = training_data[numpy.random.choice(training_size, BATCH_SIZE, False),:]
        train_step.run({input: batch[:,0:7], labels: batch[:,7]})

        if i % 100 == 0 or i == NUM_BATCHES - 1:
            print('Accuracy %.2f%% at step %d' % (accuracy.eval(validation_dict) * 100, i))

    output_data = outputs.eval({input: data_vector[:,0:7]})

我只能从经过训练的模型中得到的输出似乎是历史对象。还有一个myModel.output对象,但这是一个张量,如果不将数据放入其中就无法评估。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

据我所知,调用层时传递training=True后,您无法关闭辍学(除非您将权重转移到具有相同架构的新模型中)。但是,相反,您可以在正常情况下(即在调用中不使用training参数)构建和训练模型,然后在测试阶段通过定义后端函数(即{{1 }})并设置学习阶段(即keras.backend.function()):

keras.backend.learning_phase()

更新:如我上面所述,另一种方法是定义一个具有相同架构但不设置# build your model normally (i.e. without using `training=True` argument) # train your model... from keras import backend as K func = K.function(model.inputs + [K.learning_phase()], model.outputs) # run the model with dropout layers being active, i.e. learning_phase == 1 preds = func(list_of_input_arrays + [1]) # run the model with dropout layers being inactive, i.e. learning_phase == 0 preds = func(list_of_input_arrays + [0]) 的新模型,然后将权重从经过训练的模型转移到这个新模型模型。为此,我只需在您的training=True函数中添加一个training参数:

get_model()