Байесовская модель не учится с вероятностью тензорного потока и кера - PullRequest
1 голос
/ 26 сентября 2019

Я хочу оценить эпистемическую неопределенность моей модели.Поэтому я преобразовал все слои в слои вероятности тензорного потока.Модель не возвращает ошибок, но она также ничего не изучает.Модель имеет два выхода, и потери обоих выходов не меняются вообще.С другой стороны, общая потеря модели уменьшается, но, похоже, не связана с другими потерями вообще, что я не могу объяснить.

import numpy as np
from tensorflow import keras
import tensorflow_probability as tfp
import tensorflow as tf
from plot.plot_utils import plot_model_metrics
from Custom_Keras_layers.ProbSqueezeExcite import squeeze_excite_block

inp = keras.layers.Input(shape=[self.timesteps, self.features])
    # left side
    # 1 Conv1D block
    l = tfp.layers.Convolution1DFlipout(filters=2*self.features, kernel_size=2, padding='same', activation=tf.nn.relu)(inp)
    l = keras.layers.BatchNormalization()(l)
    if squeeze_excite == 1:
        l = squeeze_excite_block(l)
    l = keras.layers.Dropout(dropout_rate)(l, training=True)

    # 1 Conv1D block
    l = tfp.layers.Convolution1DFlipout(filters=4 * self.features, kernel_size=4, padding='same', activation=tf.nn.relu)(l)
    l = keras.layers.BatchNormalization()(l)
    if squeeze_excite == 1:
        l = squeeze_excite_block(l)
    l = keras.layers.Dropout(dropout_rate)(l, training=True)

    # 1 lstm bock
    l = keras.layers.LSTM(32, recurrent_dropout=dropout_rate, dropout=dropout_rate)(l, training=True)

    # letf output layer
    l = tfp.layers.DenseFlipout(self.classes, activation=tf.nn.softmax, name='left')(l)

    # right side
    # 1 Conv1D block
    r = tfp.layers.Convolution1DFlipout(filters=2 * self.features, kernel_size=2, padding='same', activation=tf.nn.relu)(inp)
    r = keras.layers.BatchNormalization()(r)
    if squeeze_excite == 1:
        r = squeeze_excite_block(r)
    r = keras.layers.Dropout(dropout_rate)(r, training=True)

    # 1 Conv1D block
    r = tfp.layers.Convolution1DFlipout(filters=4 * self.features, kernel_size=4, padding='same', activation=tf.nn.relu)(r)
    r = keras.layers.BatchNormalization()(r)
    if squeeze_excite == 1:
        r = squeeze_excite_block(r)
    r = keras.layers.Dropout(dropout_rate)(r, training=True)

    # 1 lstm bock
    r = keras.layers.LSTM(32, recurrent_dropout=dropout_rate, dropout=dropout_rate)(r, training=True)

    # letf output layer
    r = tfp.layers.DenseFlipout(self.classes, activation=tf.nn.softmax, name='right')(r)

    model = keras.models.Model(inputs=inp, outputs=[l, r])

    optimizer = tf.train.AdamOptimizer(learning_rate=lr)
    losses = {
        "left": self._neg_log_likelihood_bayesian,
        "right": self._neg_log_likelihood_bayesian}
    model.compile(optimizer=optimizer, loss=losses, metrics=['accuracy'])
    self.model = model

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

    def _neg_log_likelihood_bayesian(self, y_true, y_pred):
    labels_distribution = tfp.distributions.Categorical(logits=y_pred)
    neg_log_likelihood = -tf.reduce_mean(labels_distribution.log_prob(tf.argmax(y_true, axis=-1)))
    kl = sum(self.model.losses) / self.trainNUM
    loss = neg_log_likelihood + kl
    return loss

Любая помощь будет принята с благодарностью.Общая потеря начинается с 45000, тогда как потери на двух выходах составляют около 1,3.Это очень странно для меня.

Ответы [ 2 ]

2 голосов
/ 27 сентября 2019

Благодаря этому посту на форуме вопросов github tenorflow я узнал, как его решить https://github.com/tensorflow/probability/issues/282 Вам необходимо масштабировать сумму KL в каждом слое tfp:

 kernel_divergence_fn=lambda q, p, _: tfp.distributions.kl_divergence(q, p) / tf.to_float(train.num_examples))

Более тогоЯ изменил функцию потерь на:

neg_log_likelihood = tf.nn.softmax_cross_entropy_with_logits_v2 (tags = y_true, logits = y_pred)

Это сделал для меня, теперь моя модельправильно тренируется.

0 голосов
/ 27 сентября 2019

Общая потеря может уже включать в себя предыдущую потерю kl (выборочные веса || предыдущие), поэтому можно ли рассчитывать сомнение?(Я не уверен, как Керас справляется с этим.) Другая мысль состоит в том, чтобы попытаться использовать redu_sum вместо redu_mean.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...