Tensorflow 如何在keras中禁用预测时退出?

Tensorflow 如何在keras中禁用预测时退出?,tensorflow,machine-learning,keras,deep-learning,neural-network,Tensorflow,Machine Learning,Keras,Deep Learning,Neural Network,我正在keras中使用神经网络模型中的辍学。一点点代码就像 model.add(Dropout(0.5)) model.add(Dense(classes)) 对于测试,我使用的是preds=model\u 1.predict\u proba(图像) 但是,在测试时,辍学者也参与预测不应该发生的分数。我搜索了很多来禁用辍学者,但还没有得到任何提示 在keras中测试时,是否有人有办法禁用退出功能?退出功能会从游戏中移除某些神经元,为了弥补这一点,我们通常采取以下两种方法之一 在测试时缩放激活

我正在keras中使用神经网络模型中的辍学。一点点代码就像

model.add(Dropout(0.5))
model.add(Dense(classes))
对于测试,我使用的是
preds=model\u 1.predict\u proba(图像)

但是,在测试时,辍学者也参与预测不应该发生的分数。我搜索了很多来禁用辍学者,但还没有得到任何提示


在keras中测试时,是否有人有办法禁用退出功能?

退出功能会从游戏中移除某些神经元,为了弥补这一点,我们通常采取以下两种方法之一

  • 在测试时缩放激活
  • 在培训阶段扭转辍学现象

  • keras使用第二种修正形式,正如您可以看到的那样,

    keras默认情况下会这样做。在Keras中,在测试模式下禁用辍学。您可以查看代码,看到他们在培训中使用了删除的输入,在测试时使用了实际的输入


    据我所知,您必须从层中构建自己的训练函数,并指定训练标志以使用辍学进行预测(例如,不可能为预测函数指定训练标志)。如果您想进行GANs,由于生成的训练图像和生成的测试图像之间存在差异,GANs使用中间输出进行训练,同时也对整个网络进行训练,这是一个问题。

    如前所述,Keras中的退出仅在训练时发生(在训练期间按比例调整体重,以便在禁用辍学时,学习的体重适合预测)

    这对于我们希望使用缺失NNET作为概率预测器的情况并不理想(这样,当要求重复预测相同的输入时,它会产生一个分布)。换句话说,Keras的缺失层旨在在训练时为您提供正则化,但“平均函数”预测时所学习的分布

    如果希望保留辍学进行预测,可以轻松实现永久辍学(“PermaDropout”)层(这是基于F.Chollet在

    通过用“PermaDropout”替换Keras模型中的任何丢失层,您也将获得预测中的概率行为

    # define the LSTM model
    n_vocab = text_to_train.n_vocab
    
    model = Sequential()
    model.add(LSTM(n_vocab*4, 
              input_shape=input_shape, 
              return_sequences=True))
    # Replace Dropout with PermaDropout
    # model.add(Dropout(0.3)
    model.add(PermaDropout(0.3))
    model.add(LSTM(n_vocab*2))
    # Replace Dropout with PermaDropout
    # model.add(Dropout(0.3)
    model.add(PermaDropout(0.3))
    #model.add(Dense(n_vocab*2))
    model.add(Dense(n_vocab, activation='softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    

    要激活推断时间的退出,您只需在感兴趣的层中指定
    training=True
    dropout
    ,在我们的例子中):

    使用
    training=False

    inp = Input(shape=(10,))
    x = Dropout(0.3)(inp, training=False)
    x = Dense(1)(x)
    m = Model(inp,x)
    # m.compile(...)
    # m.fit(...)
    
    X = np.random.uniform(0,1, (1,10))
    
    output = []
    for i in range(0,100):
        output.append(m.predict(X)) # always the same
    
    使用
    training=True

    inp = Input(shape=(10,))
    x = Dropout(0.3)(inp, training=True)
    x = Dense(1)(x)
    m = Model(inp,x)
    # m.compile(...)
    # m.fit(...)
    
    X = np.random.uniform(0,1, (1,10))
    
    output = []
    for i in range(0,100):
        output.append(m.predict(X)) # always different
    
    默认情况下,培训设置为False


    推理时使用droput的完整示例

    由于较新的Tensorflow版本通常很受欢迎,您可以尝试以下方法:

    train_prediction = model_or_layer(input_data_numpy, training=True)
    test_prediction = model_or_layer(input_data_numpy, training=False)
    
    这将为您提供考虑所需阶段行为的预测。 对于定制的训练循环(在这里,您可以进行热切的预测并自己应用梯度,而不是
    model.fit
    ),使用以下方法非常重要:

    #training
    for batchX, batchY in data_generator:
        with with tf.GradientTape() as tape:
           train_outputs = model(batchX, training=True)
           loss = some_loss(batchY, train_outputs)
        gradients = tape.gradient(loss, model.trainable_weights)
        optimizer.apply_gradients(zip(gradients, model.trainable_weights))
    
    #validating
    for batchX, batchY in val_generator:
        val_outputs = model(batchX, training=False)
        #calculate metrics
    

    我从未测试过以下内容,但在非急切模式下,您也可以使用现有层构建新模型,但将
    training=False
    传递给调用(函数API模型):


    你能补充更多关于如何工作的细节吗?我也在你关于媒体的非常有用的NN-LSTM帖子中看到了这一点。谢谢!嗨,德鲁,谢谢!这一简单的代码行只允许在训练后在你的网络中激活退出(你的预测每次都会不同!)。通过Keras中的这一技巧,可以使用自举迭代预测来估计预测不确定性。要深入研究该理论,我建议您看看这篇论文:以及有关该主题的相关参考文献。
    #training
    for batchX, batchY in data_generator:
        with with tf.GradientTape() as tape:
           train_outputs = model(batchX, training=True)
           loss = some_loss(batchY, train_outputs)
        gradients = tape.gradient(loss, model.trainable_weights)
        optimizer.apply_gradients(zip(gradients, model.trainable_weights))
    
    #validating
    for batchX, batchY in val_generator:
        val_outputs = model(batchX, training=False)
        #calculate metrics
    
    #if using an existing layer
    output_symbolic_tensor = someExistingLayer(input_symbolic_tensor, training=True) 
    
    #if you're creating a new layer now
    output_symbolic_tensoe = SomeLayer(*layer_params)(input_symbolic_tensor, training=True)