При обучении вариационной байесовской нейронной сети в TFP, как я могу визуализировать эволюцию различных терминов в потере в отдельности? - PullRequest
2 голосов
/ 15 января 2020

Я хочу использовать тензор потока вероятности для обучения простой полностью связанной байесовской нейронной сети. Потеря состоит из терминов KL и термина с отрицательным логарифмическим правдоподобием. Как я могу увидеть их отдельную эволюцию с помощью tfp?

У меня есть следующий код:

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
import tensorflow_probability as tfp

tfk = tf.keras
tfkl = tf.keras.layers
tfpl = tfp.layers
tfd = tfp.distributions

[make some data for a regression task]

input = tfkl.Input(n_features)
x = input
x = tfpl.DenseFlipout(100, activation='relu')(x)
x = tfpl.DenseFlipout(2)(x)
x = tfpl.DistributionLambda(lambda t: tfd.Normal(loc=t[..., :1],
                                                 scale=1e-3 + tf.math.softplus(t[..., 1:])))(x)

model = tfk.Model(input, x)

negloglik = lambda y, rv_y: -rv_y.log_prob(y)

model.compile(optimizer=tf.optimizers.Adam(), loss=negloglik, metrics=['mse'])
history = model.fit(x_train, y_train, epochs=10, validation_data=(x_val, y_val));

Функция потерь - это сумма явного члена negloglik и члена дивергенции KL в каждый DenseFlipout слой (я могу видеть их там, например, model.losses).

Как я могу визуализировать каждый из этих терминов в отдельности?


Попытка :

Если я пытаюсь добавить функцию, которая вычисляет negloglik к метрикам, например

def negloglik_met(y_true, y_pred):
    return -y_pred.log_prob(y_true)

, я получаю AttributeError: 'Tensor' object has no attribute 'log_prob', что меня смущает. y_pred должен быть выходным слоем DistributionLambda, так почему он является тензором, а не распределением?

Что-то еще, на что я надеялся, сработает, но не добавляет model.losses[0] к метрикам. Там я получаю ValueError: Could not interpret metric function identifier: Tensor("dense_flipout/divergence_kernel:0", shape=(), dtype=float32).

1 Ответ

1 голос
/ 30 января 2020

Я углубился в код TensorFlow. Это происходит из-за того, что automati c TensorFlow создает автоматическую c оболочку вокруг вашей (лямбда-функции) функции. Он преобразует и преобразует вывод модели (распределение) в тип метри c (что в любом случае мне кажется странным). Итак, чтобы предотвратить это, вы должны создать свою собственную обертку, которая не выполняет это приведение. Код, который делает это, находится по адресу: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/keras/metrics.py#L583

Поэтому вдохновите себя на этот блок кода, чтобы создать свой собственный Metri c Wrapper. Это должно быть функцией TFP.

...