如何使用Keras计算预测不确定性?

时间:2017-04-20 21:07:39

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

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

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

使用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,但任何人都会这样做。)

编辑:澄清一下,我正在寻找如何使用Yurin Gal概述的方法获得确定性(或解释为什么其他方法会产生更好的结果)。

4 个答案:

答案 0 :(得分:23)

如果您想实施 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
    
  3. 当然,您可以使用任何不同的函数来计算不确定性。

答案 1 :(得分:5)

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

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

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

然后使用此信息,您可以进行一些后处理,通常预测的类是概率最高的类,但您也可以查看具有第二高概率的类等。

答案 2 :(得分:2)

对票数最高的答案进行了一些更改。现在对我有用。

这是一种估计模型不确定性的方法。对于其他不确定性来源,我发现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

答案 3 :(得分:0)

一种更简单的方法是在您要在推理期间运行的所有辍学图层上设置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