在创建 VAE 模型期间抛出异常 "you should implement a `call` method."

During creating VAE model throws exception "you should implement a `call` method."

我想创建 VAE(变分自动编码器)。在模型创建期间它抛出异常。 当 subclassing Model class 时,你应该实现一个 call 方法。

我正在使用 Tensorflow 2.0

def vae():
    models ={}

    def apply_bn_and_dropout(x):
        return l.Dropout(dropout_rate)(l.BatchNormalization()(x))
    input_image = l.Input(batch_shape=(batch_size,28,28,1))
    x = l.Flatten()(input_image)
    x = l.Dense(256,activation="relu")(x)
    x = apply_bn_and_dropout(x)
    x = l.Dense(128,activation="relu")(x)
    x = apply_bn_and_dropout(x)

    z_mean = l.Dense(latent_dim)(x)
    z_log_var = l.Dense(latent_dim)(x)

    def sampling(args):
        z_mean, z_log_var = args
        epsilon = K.random_normal(shape=(batch_size,latent_dim),mean=0., stddev=1.0)
        return z_mean + K.exp(z_log_var/2) * epsilon

    lambda_layer = l.Lambda(sampling,output_shape=(latent_dim,))([z_mean,z_log_var])

    models["encoder"] = Model(input_image,lambda_layer,"Encoder")
    models["z_meaner"] = Model(input_image,z_mean,"Enc_z_mean")
    models["z_lvarer"] = Model(input_image, z_log_var,"Enc_z_log_var")

    z = l.Input(shape=(latent_dim,))
    x = l.Dense(128)(z)
    x = l.LeakyReLU()(x)
    x = apply_bn_and_dropout(x)
    x = l.Dense(256)(x)
    x = l.LeakyReLU()(x)
    x = apply_bn_and_dropout(x)
    x = l.Dense(28*28,activation="sigmoid")(x)
    decoded = l.Reshape((28,28,1))(x)

    models["decoder"] = Model(z,decoded,name="Decoder")
    models["vae"] = Model(input_image, models["decoder"](models["encoder"](input_image)), name="VAE")

    def vae_loss(x,decoded):
        x = K.reshape(x,shape=(batch_size,28*28))
        decoded = K.reshape(decoded,shape=(batch_size,28*28))
        xent_loss = 28*28*binary_crossentropy(x, decoded)
        kl_loss = -0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)
        return (xent_loss + kl_loss)/2/28/28

    return models, vae_loss

---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
<ipython-input-34-186b31069dc3> in <module>
----> 1 models, vae_loss = vae()
      2 vae = models["vae"]

<ipython-input-33-0fa06b39e41c> in vae()
     36 
     37     models["decoder"] = Model(z,decoded,name="Decoder")
---> 38     models["vae"] = Model(input_image, models["decoder"](models["encoder"](input_image)), name="VAE")
     39 
     40     def vae_loss(x,decoded):

~\AppData\Local\Continuum\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py in __call__(self, inputs, *args, **kwargs)
    610                       base_layer_utils.AutoAddUpdates(self,
    611                                                       inputs)) as auto_updater:
--> 612                 outputs = self.call(inputs, *args, **kwargs)
    613                 auto_updater.set_outputs(outputs)
    614 

~\AppData\Local\Continuum\anaconda3\lib\site-packages\tensorflow\python\keras\engine\network.py in call(self, inputs, training, mask)
    865     """
    866     if not self._is_graph_network:
--> 867       raise NotImplementedError('When subclassing the `Model` class, you should'
    868                                 ' implement a `call` method.')
    869 

NotImplementedError: When subclassing the `Model` class, you should implement a `call` method.

有名字的模型

def create_dense_ae():
    encoding_dim = 64

    input_img = layers.Input(shape=(28, 28, 1))
    flat_img = layers.Flatten()(input_img)

    encoded = layers.Dense(encoding_dim, activation='relu')(flat_img)


    input_encoded = layers.Input(shape=(encoding_dim,))
    flat_decoded = layers.Dense(28*28, activation='sigmoid')(input_encoded)
    decoded = layers.Reshape((28, 28, 1))(flat_decoded)


    encoder = tf.keras.Model(input_img, encoded, name="encoder")
    decoder = tf.keras.Model(input_encoded, decoded, name="decoder")
    autoencoder = tf.keras.Model(input_img, decoder(encoder(input_img)), name="autoencoder")
    return encoder, decoder, autoencoder

我要买模型

问题出在这里:

models["encoder"] = Model(input_image,lambda_layer,"Encoder")
models["z_meaner"] = Model(input_image,z_mean,"Enc_z_mean")
models["z_lvarer"] = Model(input_image, z_log_var,"Enc_z_log_var")

您将三个参数传递给构造,其中只需要两个(输入和输出)。模型没有名字。问题是三个参数会破坏网络或子分类模型的检测,如 keras source code.

所示

所以只需将代码替换为:

models["encoder"] = Model(input_image,lambda_layer)
models["z_meaner"] = Model(input_image,z_mean)
models["z_lvarer"] = Model(input_image, z_log_var)