Как рассчитать неопределенность прогноза с помощью Keras?
Я хотел бы рассчитать уверенность/уверенность модели NN (см. Что моя глубокая модель не знает) - когда 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, но любой будет делать).
РЕДАКТИРОВАТЬ: пояснить, я ищу пример, как получить определенность, используя метод, описанный Юрином Галом (или объяснение, почему другой метод дает лучшие результаты).
Ответы
Ответ 1
Если вы хотите реализовать метод отсева для измерения неопределенности, вы должны сделать следующее:
-
Реализуйте функцию, которая применяет исключение и во время тестирования:
import keras.backend as K
f = K.function([model.layers[0].input, K.learning_phase()],
[model.layers[-1].output])
-
Используйте эту функцию как предиктор неопределенности, например. следующим образом:
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
Конечно, вы можете использовать любую другую функцию для вычисления неопределенности.
Ответ 2
В вашей модели используется активация softmax, поэтому самым простым способом получения какой-либо меры неопределенности является просмотр вероятностей выходного softmax:
probs = model.predict(some input data)[0]
Затем массив probs
будет десятизначным вектором чисел в диапазоне [0, 1], который суммируется до 1.0, поэтому их можно интерпретировать как вероятности. Например, вероятность для цифры 7 равна probs[7]
.
Затем с помощью этой информации вы можете выполнить некоторую пост-обработку, как правило, предсказанный класс - с наивысшей вероятностью, но вы также можете посмотреть класс со второй наивысшей вероятностью и т.д.
Ответ 3
Сделано несколько изменений в топе проголосовавшего ответа. Теперь это работает для меня.
Это способ оценить неопределенность модели. Для другого источника неопределенности я нашел https://eng.uber.com/neural-networks-unterminty-esvaluation/ полезным.
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
Ответ 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)
Код выше из этого вопроса.