2

我试图在推理期间使用模型中的 dropout 层来测量模型不确定性,如Yurin Gal 概述的方法中所述

这篇文章中描述了一个解决方案: 如何使用 Keras 计算预测不确定性?,它定义了一个新的 Keras 函数 self.f = K.function([self.graph.layers[0].input, K.learning_phase()], [self.graph.layers[-1].output])

但是,如果使用的模型具有批量标准化层,则此方法不成立。因为这将使模型不使用在训练期间学习的均值和方差,而是根据当前批次设置新的。

因此,我正在寻找一种方法将批处理层训练参数设置为 false,但将 dropout 层保持在训练模式?

我使用 KerasefficientNet B0 作为模型,在自定义数据keras_efficientNet上进行了训练

我已经尝试自己更改图层设置

`
        for layer in self.graph.layers[4].layers:
            if 'batch_norm' in layer.name:
                layer._trainable = False
                layer._inbound_nodes[0].output_tensors[0]._uses_learning_phase = False
                layer._inbound_nodes[0].input_tensors[0]._uses_learning_phase = False
            if 'dropout' in layer.name:
                layer._inbound_nodes[0].output_tensors[0]._uses_learning_phase = True
            for weight in self.graph.layers[4].weights:
                if 'batch_norm' in weight.name:
                    weight._trainable = False`

尽管如此,这些都没有奏效。

4

3 回答 3

0

您可以按照此链接创建自定义层,还有一个使用自定义 dropout 层的示例,以便您可以在训练期间操纵训练值以及推理时间以使 dropout 在推理时间运行

class CustomDropout(keras.layers.Layer):
def __init__(self, rate, **kwargs):
    super(CustomDropout, self).__init__(**kwargs)
    self.rate = rate

def call(self, inputs, training=None):
    if training: #you can remove this line,, so that you can use dropout on inference time
        return tf.nn.dropout(inputs, rate=self.rate)
    return inputs
于 2021-12-21T06:28:23.460 回答
0

这个问题是重复的,这里已经回答了How to apply Monte Carlo Dropout, in tensorflow, for an LSTM if batch normalization is part of the model?

基本上,当你定义你的模型时,你应该添加training=True到你的 Dropout 层

inputs = tf.keras.Input(...) 
x = tf.keras.layers.___(...)(input)
...
x = tf.keras.layers.Dropout(...)(x, training=True)
...

在这种情况下,您无法修改模型构造函数代码,您可以这样修改(不是我最喜欢的解决方案[1]

# load model
model_config = model.get_config()
layer_index = 3 # layer index you want to modify
model_config['layers'][layer_index]['inbound_nodes'][0][0][-1]['training'] = True
model = tf.keras.models.model_from_config(model_config)
于 2020-06-12T11:14:35.397 回答
0

感谢@pedrolarben 的解决方案,它对我帮助很大,但不完整!

最终起作用的是以下

  1. model_config = self.graph.get_config()
  2. 您需要直接更改层配置的 inbound_nodes 而不是 inbound_nodes model_config['layers'][layer_index]['config']['layers'][index_of_dropout_layer]['inbound_nodes'][0][0][-1]['training'] = True

  3. 重新加载模型:(如this answer中所述keras.models.Model.get_config() 的倒数似乎是 keras.models.Model.from_config(),而不是 keras.models.model_from_config()):

model = Model.from_config(model_config)

  1. 最后你需要再次加载权重,否则你的模型是随机初始化的model.load_weights(self.graph_path)

注意:这适用于效率网络的 keras 实现。

于 2020-06-16T18:16:02.620 回答