Пользовательская функция потери Keras, не возвращающая ни одного - PullRequest
0 голосов
/ 27 апреля 2018

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

 def vae_loss(sigma, mu):
        def loss(y_true, y_pred):
            recon = K.sum(K.binary_crossentropy(y_true, y_pred), axis=-1)
            kl = 0.5 * K.sum(K.exp(sigma) + K.square(mu) - 1. - sigma, axis=-1)
            return recon + kl
        return loss

Двоичная часть кроссентропии работает нормально, но всякий раз, когда я возвращаю для тестирования только дивергенционный член kl, я получаю следующую ошибку: ValueError: «Попытка преобразовать x в тензор и ошибка. Ошибка: ни одно из значений не поддерживается.».

Я с нетерпением жду возможных подсказок относительно того, что я сделал неправильно. Вы найдете весь мой код ниже. Спасибо за ваше время!

import numpy as np
from keras import Model
from keras.layers import Input, Dense, Lambda
import keras.backend as K
from keras.datasets import mnist
from matplotlib import pyplot as plt

class VAE(object):

    def __init__(self, n_latent, batch_size):

        self.encoder, self.encoder_input, self.mu, self.sigma = self.create_encoder(n_latent, batch_size)
        self.decoder, self.decoder_input, self.decoder_output = self.create_decoder(n_latent, batch_size)
        pipeline = self.decoder(self.encoder.outputs[0])

        def vae_loss(sigma, mu):
            def loss(y_true, y_pred):
                recon = K.sum(K.binary_crossentropy(y_true, y_pred), axis=-1)
                kl = 0.5 * K.sum(K.exp(sigma) + K.square(mu) - 1. - sigma, axis=-1)
                return recon + kl
            return loss

        self.VAE = Model(self.encoder_input, pipeline)
        self.VAE.compile(optimizer="adadelta", loss=vae_loss(self.sigma, self.mu))

    def create_encoder(self, n_latent, batch_size):

        input_layer = Input(shape=(784,))
        #net = Dense(512, activation="relu")(input_layer)
        mu = Dense(n_latent, activation="linear")(input_layer)
        print(mu)
        sigma = Dense(n_latent, activation="linear")(input_layer)

        def sample_z(args):
            mu, log_sigma = args
            eps = K.random_normal(shape=(K.shape(input_layer)[0], n_latent), mean=0., stddev=1.)
            K.print_tensor(K.shape(eps))
            return mu + K.exp(log_sigma / 2) * eps

        sample_z = Lambda(sample_z)([mu, sigma])

        model = Model(inputs=input_layer, outputs=[sample_z, mu, sigma])
        return model, input_layer,  mu, sigma

    def create_decoder(self, n_latent, batch_size):

        input_layer = Input(shape=(n_latent,))
        #net = Dense(512, activation="relu")(input_layer)
        reconstruct = Dense(784, activation="linear")(input_layer)

        model = Model(inputs=input_layer, outputs=reconstruct)
        return model, input_layer, reconstruct

1 Ответ

0 голосов
/ 27 апреля 2018

Я предполагаю, что ошибка появляется, когда вы «тестируете» / отлаживаете фазу обучения, во время обратного распространения (позвольте мне, если я ошибаюсь).

Если это так, проблема заключается в том, что вы просите Keras оптимизировать всю сеть (model.VAE.fit(...)), используя потери (kl), покрывающие только часть кодера. Градиенты для декодера остаются неопределенными (без потерь, таких как recon, покрывающих их), вызывая ошибку оптимизации.

В целях отладки ошибка исчезнет, ​​если вы попытаетесь скомпилировать и установить только кодировщик с этой ампутированной потерей (kl), или если у вас возникнут фиктивные (дифференцируемые) потери, покрывающие также декодер (например, K.sum(y_pred - y_pred, axis=-1) + kl).

...