【问题标题】:How to calculate prediction uncertainty using Keras?如何使用 Keras 计算预测不确定性?
【发布时间】:2017-09-17 16:50:56
【问题描述】:

我想计算 NN 模型的确定性/置信度(请参阅 What my deep model doesn't know) - 当 NN 告诉我图像代表“8”时,我想知道它有多确定。我的模型 99% 确定它是“8”还是 51% 确定它是“8”,但也可能是“6”?有些数字很模糊,我想知道模型只是“抛硬币”。

我找到了一些关于此的理论著作,但我无法将其放入代码中。如果我理解正确,我应该多次评估测试图像,同时“杀死”不同的神经元(使用 dropout)然后......?

在 MNIST 数据集上工作,我正在运行以下模型:

from keras.models import Sequential
from keras.layers import Dense, Activation, Conv2D, Flatten, Dropout

model = Sequential()
model.add(Conv2D(128, kernel_size=(7, 7),
                 activation='relu',
                 input_shape=(28, 28, 1,)))
model.add(Dropout(0.20))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Dropout(0.20))
model.add(Flatten())
model.add(Dense(units=64, activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(units=10, activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy',
              optimizer='sgd',
              metrics=['accuracy'])
model.fit(train_data, train_labels,  batch_size=100, epochs=30, validation_data=(test_data, test_labels,))

我应该如何使用这个模型进行预测,以便我也能确定预测的准确性?我会很感激一些实际的例子(最好在 Keras 中,但任何人都可以)。

为了澄清,我正在寻找一个如何使用the method outlined by Yurin Gal 获得确定性的示例(或解释为什么其他一些方法会产生更好的结果)。

【问题讨论】:

    标签: machine-learning neural-network deep-learning keras uncertainty


    【解决方案1】:

    您的模型使用 softmax 激活,因此获得某种不确定性度量的最简单方法是查看输出的 softmax 概率:

    probs = model.predict(some input data)[0]
    

    probs 数组将是 [0, 1] 范围内总和为 1.0 的数字的 10 元素向量,因此可以将它们解释为概率。例如数字 7 的概率就是probs[7]

    然后有了这些信息,你可以做一些后处理,通常预测的类是概率最高的类,但你也可以查看概率第二高的类,等等。

    【讨论】:

    • 谢谢你的回答,但是链接的post 似乎不同意你的观点:“在这个模型中,我们将我们的预测输入到一个 softmax 中,它为我们提供了不同类别的概率( 10 位)。有趣的是,这些概率不足以查看我们的模型在其预测中是否确定。这是因为标准模型会将预测均值传递给 softmax 而不是整个分布。” 我错过了什么吗?
    • @johndodo 和我的回答没有异议,我从来没有声称有最好的方法,只是最简单的。
    • 曲线与一个好的确定性函数不匹配。你可以得到一个迂回的想法(如果它非常高或非常低),但仅此而已。您不能确定性地依赖预测输出
    • 我同意概率给出了一些关于结果不确定性的想法,但提问者引用的是 模型不确定性,这就像在问一个问题:什么是不确定性模型的概率预测?您可以对非常“矛盾”的概率有非常高的确定性,反之亦然。例如。您可以 99% 确定概率在 [49.9 - 50.1%] 范围内,例如,当您掷硬币时,您知道正面朝上的概率约为 50%。
    • Softmax 概率不是衡量不确定性的好指标。见arxiv.org/abs/1703.04977
    【解决方案2】:

    如果您想实施 dropout 方法来衡量不确定性,您应该执行以下操作:

    1. 实现在测试期间也应用 dropout 的函数:

      import keras.backend as K
      f = K.function([model.layers[0].input, K.learning_phase()],
                     [model.layers[-1].output])
      
    2. 将此函数用作不确定性预测器,例如以下列方式:

      def predict_with_uncertainty(f, x, n_iter=10):
          result = numpy.zeros((n_iter,) + x.shape)
      
          for iter in range(n_iter):
              result[iter] = f(x, 1)
      
          prediction = result.mean(axis=0)
          uncertainty = result.var(axis=0)
          return prediction, uncertainty
      

    当然,您可以使用任何不同的函数来计算不确定性。

    【讨论】:

    • 这看起来正是我想要的!不幸的是,我不在的时候赏金到期了),所以我将开始并奖励另一个。谢谢! (编辑:但当然,我只能奖励双倍,而且只能在 24 小时后......所以直到明天...... :))
    • n_iter 在你的函数中代表什么@Marcin Możejko
    • 当你说不确定性时,当它说 0.93 时,是表示它有 93% 的不确定性还是 93% 的确定是选择?
    • 这个功能有问题。这是用什么tensorflow,keras版本写的?
    • 我不明白这一点.. 模型不会每次都为相同的输入预测完全相同的值吗?在这种情况下,var(方差)每次都会为 0。当我为我的代码实现这个时。我得到了完全相同的值预测了 10 次(n_iter=10)
    【解决方案3】:

    对投票最多的答案进行了一些更改。现在它对我有用。

    这是一种估计模型不确定性的方法。对于其他不确定性来源,我发现 https://eng.uber.com/neural-networks-uncertainty-estimation/ 很有帮助。

    f = K.function([model.layers[0].input, K.learning_phase()],
                   [model.layers[-1].output])
    
    
    def predict_with_uncertainty(f, x, n_iter=10):
        result = []
    
        for i in range(n_iter):
            result.append(f([x, 1]))
    
        result = np.array(result)
    
        prediction = result.mean(axis=0)
        uncertainty = result.var(axis=0)
        return prediction, uncertainty
    

    【讨论】:

    • 我在这里尝试过使用您的实现,虽然它似乎可以正常工作,但我似乎只收到了一个相同预测的矩阵,以及一个包含 0 的不确定性矩阵?任何帮助都感激不尽!谢谢!
    • 你得到 0,因为在推理过程中 dropout 被禁用。只有在训练时启用它,您才会得到不同的结果。您可以在 dropout 层中设置参数 trainable=Tue。你可以在这里找到详细的文章-towardsdatascience.com/…
    【解决方案4】:

    一种更简单的方法是在推理期间也希望在任何退出层上设置training=True(基本上告诉层像始终处于训练模式一样运行 - 因此它始终存在于训练和推理中) .

    import keras
    
    inputs = keras.Input(shape=(10,))
    x = keras.layers.Dense(3)(inputs)
    outputs = keras.layers.Dropout(0.5)(x, training=True)
    
    model = keras.Model(inputs, outputs)
    

    上面的代码来自这个issue

    【讨论】:

    • 如果我使用keras.Sequential([]),我该如何使用你的方法?
    • @Samuel 我迟到了,但也许它可以帮助其他人:不,如果你使用顺序 API,training=True 不能设置 - 你需要使用如示例中所示的功能 API。也就是说,您可能想查看uncertainty-wizard,它允许在 Sequential API 中实现相同的功能(免责声明:我是作者)
    猜你喜欢
    • 2020-12-31
    • 2012-07-10
    • 1970-01-01
    • 2016-02-01
    • 2019-12-08
    • 2019-05-06
    • 1970-01-01
    • 2017-07-28
    • 1970-01-01
    相关资源
    最近更新 更多