【问题标题】:Is there a way to activate dropout during inference in Keras, while freezing batch norm layers有没有办法在 Keras 的推理过程中激活 dropout,同时冻结批处理规范层
【发布时间】:2020-10-02 04:23:21
【问题描述】:

我正在尝试在我的模型中使用 dropout 层在推理时间来衡量模型的不确定性 如the method outlined by Yurin Gal中所述

这篇文章描述了一个解决方案: How to calculate prediction uncertainty using 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`

然而,这些都不起作用。

【问题讨论】:

    标签: keras deep-learning uncertainty


    【解决方案1】:

    这个问题重复了,这里已经回答了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)
    

    【讨论】:

    • 感谢您的快速回复。问题是我没有再次定义模型。我只是将它用于推理,不想再次训练它。我使用 keras.model 中的加载函数来加载已经训练好的 .h5 模型。以这种方式加载模型时,有没有办法更改模型的定义?
    【解决方案2】:

    感谢@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. 重新加载模型:(如本答案The inverse of keras.models.Model.get_config() seems to be keras.models.Model.from_config(), not keras.models.model_from_config()所述):

    model = Model.from_config(model_config)

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

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

    【讨论】:

      【解决方案3】:

      您可以关注this link 创建自定义层,还有一个使用自定义 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-21
        • 1970-01-01
        • 2020-08-16
        • 1970-01-01
        • 2017-06-18
        相关资源
        最近更新 更多