#python #tensorflow #keras #recurrent-neural-network #eager-execution
#python #тензорный поток #keras #рекуррентная нейронная сеть #нетерпеливое выполнение
Вопрос:
В настоящее время я работаю над вариантом вариационного автоэнкодера в последовательной настройке, где задача состоит в том, чтобы соответствовать / восстанавливать последовательность вещественных данных наблюдения (следовательно, это проблема регрессии).
Я построил свою модель, используя tf.keras
с включенным активным выполнением и tensorflow_probability (tfp). Следуя концепции VAE, генеративная сеть выдает параметры распределения данных наблюдений, которые я моделирую как многомерную норму. Поэтому выходные данные являются средним и логарифмическим значением прогнозируемого распределения.
Что касается процесса обучения, первым компонентом потери является ошибка восстановления. Это логарифмическая вероятность истинного наблюдения с учетом прогнозируемого (параметров) распределения из порождающей сети. Здесь я использую tfp.distributions
, поскольку это быстро и удобно.
Однако после завершения обучения, отмеченного значительно низким значением потерь, оказывается, что моя модель, похоже, ничему не учится. Прогнозируемое значение из модели едва ли является плоским во временном измерении (напомним, что проблема является последовательной).
Тем не менее, ради проверки работоспособности, когда я заменяю логарифмическую вероятность на потерю MSE (что не оправдано при работе с VAE), это дает очень хорошую подгонку данных. Итак, я пришел к выводу, что с этим термином логарифмического правдоподобия должно быть что-то не так. Есть ли у кого-нибудь какая-то подсказка и / или решение для этого?
Я рассмотрел возможность замены логарифмической вероятности потерей кросс-энтропии, но я думаю, что это неприменимо в моем случае, поскольку моя проблема заключается в регрессии, и данные не могут быть нормализованы в диапазоне [0,1].
Я также попытался реализовать отожженный член KL (т. Е. Взвешивание члена KL с константой < 1) при использовании логарифмической вероятности в качестве потери при восстановлении. Но это также не сработало.
Вот мой фрагмент кода исходной (с использованием логарифмической вероятности в качестве ошибки восстановления) функции потери:
import tensorflow as tf
tfe = tf.contrib.eager
tf.enable_eager_execution()
import tensorflow_probability as tfp
tfd = tfp.distributions
def loss(model, inputs):
outputs, _ = SSM_model(model, inputs)
#allocate the corresponding output component
infer_mean = outputs[:,:,:latent_dim] #mean of latent variable from inference net
infer_logvar = outputs[:,:,latent_dim : (2 * latent_dim)]
trans_mean = outputs[:,:,(2 * latent_dim):(3 * latent_dim)] #mean of latent variable from transition net
trans_logvar = outputs[:,:, (3 * latent_dim):(4 * latent_dim)]
obs_mean = outputs[:,:,(4 * latent_dim):((4 * latent_dim) output_obs_dim)] #mean of observation from generative net
obs_logvar = outputs[:,:,((4 * latent_dim) output_obs_dim):]
target = inputs[:,:,2:4]
#transform logvar to std
infer_std = tf.sqrt(tf.exp(infer_logvar))
trans_std = tf.sqrt(tf.exp(trans_logvar))
obs_std = tf.sqrt(tf.exp(obs_logvar))
#computing loss at each time step
time_step_loss = []
for i in range(tf.shape(outputs)[0].numpy()):
#distribution of each module
infer_dist = tfd.MultivariateNormalDiag(infer_mean[i],infer_std[i])
trans_dist = tfd.MultivariateNormalDiag(trans_mean[i],trans_std[i])
obs_dist = tfd.MultivariateNormalDiag(obs_mean[i],obs_std[i])
#log likelihood of observation
likelihood = obs_dist.prob(target[i]) #shape = 1D = batch_size
likelihood = tf.clip_by_value(likelihood, 1e-37, 1)
log_likelihood = tf.log(likelihood)
#KL of (q|p)
kl = tfd.kl_divergence(infer_dist, trans_dist) #shape = batch_size
#the loss
loss = - log_likelihood kl
time_step_loss.append(loss)
time_step_loss = tf.convert_to_tensor(time_step_loss)
overall_loss = tf.reduce_sum(time_step_loss)
overall_loss = tf.cast(overall_loss, dtype='float32')
return overall_loss