Вероятность Tensorflow возвращает нестабильные прогнозы - PullRequest
1 голос
/ 19 марта 2019

Я использую модель вероятности Tensorflow.Конечно, это вероятностный результат, и производная от ошибки не стремится к нулю (в противном случае модель будет детерминированной).Прогноз не является стабильным, потому что у нас есть диапазон в производной потери, скажем, в выпуклой оптимизации, например, от 1,2 до 0,2.

Этот интервал генерирует другой прогноз каждый раз, когда модельобучен.Иногда я получаю отличную посадку (красный = реальный, синие линии = прогнозируемый +2 стандартное отклонение и -2 стандартное отклонение):

Good fit

Иногда нет,с такими же гиперпараметрами:

Bad fit

Иногда отражается:

Mirrored

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

Вот код:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
import tensorflow_probability as tfp
np.random.seed(42)
dataframe = pd.read_csv('Apple_Data_300.csv').ix[0:800,:]
dataframe.head()

plt.plot(range(0,dataframe.shape[0]),dataframe.iloc[:,1])

x1=np.array(dataframe.iloc[:,1]+np.random.randn(dataframe.shape[0])).astype(np.float32).reshape(-1,1)

y=np.array(dataframe.iloc[:,1]).T.astype(np.float32).reshape(-1,1)

tfd = tfp.distributions

model = tf.keras.Sequential([
  tf.keras.layers.Dense(1,kernel_initializer='glorot_uniform'),
  tfp.layers.DistributionLambda(lambda t: tfd.Normal(loc=t, scale=1)),
  tfp.layers.DistributionLambda(lambda t: tfd.Normal(loc=t, scale=1)),
  tfp.layers.DistributionLambda(lambda t: tfd.Normal(loc=t, scale=1))
])
negloglik = lambda x, rv_x: -rv_x.log_prob(x)

model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.0001), loss=negloglik)

model.fit(x1,y, epochs=500, verbose=True)

yhat = model(x1)
mean = yhat.mean()

init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    mm = sess.run(mean)    
    mean = yhat.mean()
    stddev = yhat.stddev()
    mean_plus_2_std = sess.run(mean - 2. * stddev)
    mean_minus_2_std = sess.run(mean + 2. * stddev)


plt.figure(figsize=(8,6))
plt.plot(y,color='red',linewidth=1)
#plt.plot(mm)
plt.plot(mean_minus_2_std,color='blue',linewidth=1)
plt.plot(mean_plus_2_std,color='blue',linewidth=1)

Потеря:

Epoch 498/500
801/801 [==============================] - 0s 32us/sample - loss: 2.4169
Epoch 499/500
801/801 [==============================] - 0s 30us/sample - loss: 2.4078
Epoch 500/500
801/801 [==============================] - 0s 31us/sample - loss: 2.3944

Есть ли способ управления выводом прогноза для вероятностной модели ?Потеря останавливается на 1,42, даже уменьшая скорость обучения и увеличивая периоды обучения.Что мне здесь не хватает?

КОД РАБОТЫ ПОСЛЕ ОТВЕТА:

init = tf.global_variables_initializer()

with tf.Session() as sess:

    model = tf.keras.Sequential([
      tf.keras.layers.Dense(1,kernel_initializer='glorot_uniform'),
      tfp.layers.DistributionLambda(lambda t: tfd.Normal(loc=t, scale=1))
    ])
    negloglik = lambda x, rv_x: -rv_x.log_prob(x)

    model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.0001), loss=negloglik)

    model.fit(x1,y, epochs=500, verbose=True, batch_size=16)

    yhat = model(x1)
    mean = yhat.mean()

    sess.run(init)
    mm = sess.run(mean)    
    mean = yhat.mean()
    stddev = yhat.stddev()
    mean_plus_2_std = sess.run(mean - 3. * stddev)
    mean_minus_2_std = sess.run(mean + 3. * stddev)

1 Ответ

2 голосов
/ 19 марта 2019

Ты бежишь tf.global_variables_initializer слишком поздно?

Я нашел это в ответе Понимание tf.global_variables_initializer :

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

...