Mixture Density Network (MDN) возвращает только вероятности 1.0 и 0.0 - PullRequest
0 голосов
/ 10 июля 2020

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

Для функции потерь я использую специально построенную отрицательную логарифмическую вероятность для нормального распределения, для которой я применить метод логарифмической суммы-экспонирования.

Я использую два скрытых слоя с функцией активации relu и 60 нейронами, пакет из 60 и скорость обучения e-4.

Однако, результаты всегда показывают вероятность 1 для одного из распределений и 0 для другого. Неважно, увеличиваю ли я количество эпох. Обратите внимание, что результаты для распределения с вероятностью 1,0 вполне разумны, но, учитывая предыдущую работу над этим топом c, мне трудно поверить, что за более чем 60 тыс. Часов ни одно из них не сочетает в себе 2 разных распределения *. 1007 *

Мы будем очень признательны за любые предложения о том, как исправить вероятности или что может быть причиной вероятностей только 0-1.

from tensorflow.keras import backend as bk

# reading inputs, etc.

components = 2 # Number of normal distributions in mixture
no_parameters = 3 # Number of parameters of the mixtures (weight, mean, std. dev)
neurons = 60 # Number of neurons per layer
SB = 1 # Number of outputs we want to predict

# Make the input tensor: two covariates-- quantity & price.
inputs = ks.Input(shape=(X_train.shape[1],))

h1 = ks.layers.Dense(neurons, activation="relu",
                     kernel_initializer='ones', bias_initializer='ones')(inputs)
h2 = ks.layers.Dense(neurons, activation="relu",
                     kernel_initializer='ones', bias_initializer='ones')(h1)
alphas = ks.layers.Dense(components, activation="softmax", name="alphas",
                         kernel_initializer='ones', bias_initializer='ones')(h2)
mus = ks.layers.Dense(components, name="mus")(h2)
sigmas = ks.layers.Dense(components, activation="relu", name="sigmas",
                         kernel_initializer='ones', bias_initializer='ones')(h2)
outputVector = ks.layers.Concatenate(name="output")([alphas, mus, sigmas])

model = ks.Model(inputs=inputs, outputs=outputVector)

def slice_parameter_vectors(parameter_vector):
    """ Returns an unpacked list of parameter vectors. """
    return [parameter_vector[:, i * components:(i + 1) * components] for i in range(no_parameters)]

def log_sum_exp(x, axis=None):
    """Log-sum-exp trick implementation"""
    x_max = bk.max(x, axis=axis, keepdims=True)
    return bk.log(bk.sum(bk.exp(x - x_max),
                         axis=axis, keepdims=True)) + x_max

def mean_log_Gaussian_like2(y, parameter_vector):
    """ Computes the mean negative log-likelihood loss of the observed price given the mixture parameters. """
    alpha, mu, sigma = slice_parameter_vectors(parameter_vector)  # Unpack parameter vectors
    mu = tf.keras.backend.reshape(mu, [-1, SB, 2])
    alpha = bk.softmax(bk.clip(alpha, 1e-8, 1.))
    exponent = bk.log(alpha) - .5 * float(SB) * bk.log(2 * np.pi) \
               - float(SB) * bk.log(sigma) \
               - bk.sum((bk.expand_dims(y, 2) - mu) ** 2, axis=1) / (2 * (sigma) ** 2)
    log_likelihood = log_sum_exp(exponent, axis=1)
    return -bk.mean(log_likelihood)

model.compile(optimizer=ks.optimizers.Adam(learning_rate=1e-4, clipvalue=1.0), # , clipvalue=0.5
              loss= mean_log_Gaussian_like2,
              metrics=['accuracy'])

model.fit(X_train, y_train, batch_size=60, epochs=500)

y_pred = model.predict(X_test)

1 Ответ

0 голосов
/ 11 августа 2020

Я решил эту проблему. Решение состояло в том, чтобы избавиться от функции softmax, переопределяющей альфу. То есть alpha = bk.softmax (bk.clip (alpha, 1e-8, 1.)) должен быть alpha = bk.clip (alpha, 1e-8, 1.). Всем спасибо.

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