Потеря восстановления при регрессионном типе вариационного автоэнкодера

#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