Интервалы прогнозирования нейронной сети - метод MVE - PullRequest
1 голос
/ 20 октября 2019

Я хочу обучить нейронную сеть, которая также возвращает интервалы прогнозирования, чтобы иметь представление о моей уверенности в прогнозе. Кажется, есть четыре основных метода достижения этого, которые кратко изложены в статье «Комплексный обзор интервалов прогнозирования на основе нейронных сетей и новых достижений»: https://ieeexplore.ieee.org/document/5966350

Меня интересует оценка среднего отклонения(MVE), потому что это кажется самым простым для понимания. Однако я изо всех сил пытаюсь понять, как это будет реализовано в Керасе.

Я предполагаю, что функция потерь будет определяться следующим образом:

def mve_cost(y_true, y_pred, var_pred):
  loss = 0.5*tf.reduce_sum(tf.log(var_pred) + tf.divide((tf.square(y_true - y_pred)),(tf.square(var_pred)))  )
  return loss

Но может ли функция потерь в Keras принимать три входа? Я никогда не видел этого раньше. Кроме того, цель для дисперсии-NN заранее не известна и учитывает прогнозы, сделанные средним-NN. Я полагаю, что для этого потребуются некоторые более гибкие возможности функционального API Keras, но я не совсем понимаю, как его можно собрать.

  • Как правильно определить функцию потерь для метода MVE?
  • Каким образом сложные отношения между двумя NN могут быть реализованы в функциональном API Keras?
  • Кто-нибудь знает о реализации этого метода уже в сети?
  • Есть ли другой метод генерации интервалов прогнозирования для NN, который легче понять / реализовать в Keras?

1 Ответ

1 голос
/ 31 октября 2019

Такие методы нелегко реализовать, но есть хитрость. Определите потери следующим образом:

import keras.backend as K

def regression_nll_loss(sigma_sq, epsilon = 1e-6):
    def nll_loss(y_true, y_pred):
        return 0.5 * K.mean(K.log(sigma_sq + epsilon) + K.square(y_true - y_pred) / (sigma_sq + epsilon))

    return nll_loss

Затем определите модель с двумя выходными данными, один для среднего значения, а другой для дисперсии:

from keras.models import Model
from keras.layers import Dense, Input

inp = Input(shape=(1,))
x = Dense(32, activation="relu")(inp)
x = Dense(32, activation="relu")(x)
mean = Dense(1, activation="linear")(x)
var = Dense(1, activation="softplus")(x)

train_model = Model(inp, mean)
pred_model = Model(inp, [mean, var])

train_model.compile(loss=regression_nll_loss(var), optimizer="adam")

train_model.fit(x, y, ...)

mean, var = pred_model.predict(some_input)

Хитрость заключается в явном прохождении тензорадля дисперсии к потере, поэтому требуется только два входа, а контроль выполняется только для среднего значения. Затем вам нужно определить две модели, которые имеют общие веса, одну для обучения, а другую для тестирования / вывода. Эта последняя модель возвращает среднее значение и дисперсию.

Не забудьте использовать активацию softplus для дисперсии, чтобы сохранить ее положительной. Я реализовал эту потерю для использования с Deep Ensembles , вы можете найти пример здесь .

...