Как приспособить модель Keras к гамма-распределению? - PullRequest
2 голосов
/ 25 сентября 2019

Я пытаюсь соответствовать модели keras, в которой моя выходная переменная всегда положительна.Я хочу использовать гамма-распределение для моделирования этой проблемы.Проблема в том, что потеря всегда выводит NAN.

Я построил следующую модель keras:

model_max = tf.keras.Sequential([
            tf.keras.layers.Dense(20,input_dim=10, activation="relu"),    
            tf.keras.layers.Dense(15,activation="relu"),
            tf.keras.layers.Dense(10,activation="relu"),
            tf.keras.layers.Dense(5,activation="relu"),
            tf.keras.layers.Dense(2),
            tfp.layers.DistributionLambda(lambda t:
            tfd.Gamma(concentration = tf.math.softplus(0.005*t[...,:1])+0.001,
             rate = tf.math.softplus(0.005*t[...,1:])+0.001)
            ),
])            

Обратите внимание, что я использовал softplus, потому что оба аргумента распределения должны быть положительными.Также я добавил 0,001, чтобы убедиться, что аргументы всегда больше нуля.

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

def gamma_loss(y_true, my_dist):

    dist_mean = my_dist.mean()
    dist_stddev = my_dist.stddev()
    alpha = (dist_mean / dist_stddev)**2
    beta = dist_mean / dist_stddev**2
    gamma_distr = tfd.Gamma(concentration=alpha, rate=beta)
    return -tf.reduce_mean(gamma_distr.log_prob(y_true))

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

import tensorflow as tf
import tensorflow_probability as tfp
tfd = tfp.distributions

def gamma_loss(y_true, my_dist):

    dist_mean = my_dist.mean()
    dist_stddev = my_dist.stddev()
    alpha = (dist_mean / dist_stddev)**2
    beta = dist_mean / dist_stddev**2
    #print(alpha)
    gamma_distr = tfd.Gamma(concentration=alpha, rate=beta)
    return -tf.reduce_mean(gamma_distr.log_prob(y_true)).numpy()

dist = tfd.Gamma(1,1)

gamma_loss(100, dist)

Однако, если я скомпилирую его со следующей строкой:

model_max.compile(optimizer=tf.optimizers.Adam(learning_rate = 0.001),loss=gamma_loss)

Потеря всегда выдает nan

Что я делаю не так?Я пробовал разные функции потери, но, похоже, ничего не работает.Я думаю, что это соответствует аргументу Концентрация , так как у меня уже есть подобная модель для этой работы с нормальным распределением.В этой модели я не использовал softplus для среднего значения (loc), потому что это распределение принимает любое положительное или отрицательное значение.Я использовал точную структуру для стандартного отклонения, поскольку она также должна быть возможной в нормальном распределении.Работает просто отлично.Почему это не работает для Gamma Distribution?

Спасибо за советы всем, кто может помочь мне понять, что я делаю неправильно.

1 Ответ

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

Определенно отбрасывайте .numpy() с конца gamma_loss, так как это нарушит градиент backprop.

Возможно, вы захотите чуть более щедрые минимальные значения для параметров гаммы, поскольку они могут сделать распределение довольно резким,В частности, такой параметр концентрации, как 0,5, делает распределение чрезвычайно сконцентрированным в 0. (Этот параметр называется «shape / alpha / k» в Википедии https://en.wikipedia.org/wiki/Gamma_distribution).

. Это может легко привести к +/- infгде-то, что затем дает нан где-то еще.

...