Персонализираната функция за загуба на Keras не връща нищо

Опитвам се да кодирам реализация на вариационния автоенкодер, но срещам някои трудности по отношение на функцията за загуба:

 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

person dawg_91    schedule 27.04.2018    source източник


Отговори (1)


Предполагам, че грешката се появява, когато "тествате"/отстранявате грешки във вашата тренировъчна фаза, по време на обратно разпространение (позволете ми, ако греша).

Ако е така, проблемът е, че вие ​​молите Keras да оптимизира цялата ви мрежа (model.VAE.fit(...)), докато използвате загуба (kl), покриваща само частта на енкодера. Градиентите за декодера остават недефинирани (без загуба като recon, която да го покрива), което води до грешка при оптимизиране.

За вашата цел за отстраняване на грешки грешката ще изчезне, ако се опитате да компилирате и напаснете само енкодера с тази ампутирана загуба (kl) или ако излезете с фиктивна (диференцируема) загуба, покриваща също декодера (напр. K.sum(y_pred - y_pred, axis=-1) + kl).

person benjaminplanche    schedule 27.04.2018