简体   繁体   中英

Training Variational Autoencoder in Keras raises “SymbolicException: Inputs to eager execution function cannot be Keras symbolic tensors”

I am making a vanilla Variational Autoencoder in Keras. Following is my try:

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


(xTrain,yTrain),(xTest,yTest)=mnist.load_data()
xTrain=xTrain.astype('float32')/255.
xTest=xTest.astype('float32')/255.
xTrain=xTrain.reshape(xTrain.shape[0],-1)
xTest=xTest.reshape(xTest.shape[0],-1)
xTrain.shape,yTrain.shape,xTest.shape,yTest.shape



hidden_dim1=256
hidden_dim2=128
z_dim=2
n_epoch=100
n_batch=512
xTrain.shape[1:]



def sampleZ(args):
  mu,log_var=args
  eps=K.random_normal(shape=(z_dim,),mean=0.0,stddev=1.0)
  return mu+K.exp(log_var/2)*eps


def vae_loss(yPred,yTrue):
  recon_loss=K.sum(K.binary_crossentropy(yPred,yTrue),axis=1)
  kl_loss=0.5*K.sum(K.square(mu)+K.exp(log_var)-1-log_var,axis=1)
  return recon_loss+kl_loss



encoderInput=Input(shape=(xTrain.shape[1:]))
encoder=Dense(hidden_dim1,activation='relu')(encoderInput)
encoder=Dense(hidden_dim2,activation='relu')(encoder)
mu=Dense(z_dim,activation='linear')(encoder)
log_var=Dense(z_dim,activation='linear')(encoder)
encoderModel=Model(encoderInput,encoder)

zLayer=Lambda(sampleZ,output_shape=(z_dim,)([mu,log_var])
decoder=Dense(hidden_dim2,activation='relu')(zLayer)
decoder=Dense(hidden_dim1,activation='relu')(decoder)
decoder=Dense(xTrain.shape[1],activation='sigmoid')(decoder)
vaeModel=Model(encoderInput,decoder)
vaeModel.compile(optimizer='adam',loss=vae_loss)
vaeModel.summary()

vaeModel.fit(xTrain,xTrain,epochs=n_epoch,batch_size=n_batch)

Here is the model summary:

Model: "functional_58"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_12 (InputLayer)           [(None, 784)]        0                                            
__________________________________________________________________________________________________
dense_90 (Dense)                (None, 256)          200960      input_12[0][0]                   
__________________________________________________________________________________________________
dense_91 (Dense)                (None, 128)          32896       dense_90[0][0]                   
__________________________________________________________________________________________________
dense_92 (Dense)                (None, 2)            258         dense_91[0][0]                   
__________________________________________________________________________________________________
dense_93 (Dense)                (None, 2)            258         dense_91[0][0]                   
__________________________________________________________________________________________________
lambda_20 (Lambda)              (None, 2)            0           dense_92[0][0]                   
                                                                 dense_93[0][0]                   
__________________________________________________________________________________________________
dense_103 (Dense)               (None, 128)          384         lambda_20[0][0]                  
__________________________________________________________________________________________________
dense_104 (Dense)               (None, 256)          33024       dense_103[0][0]                  
__________________________________________________________________________________________________
dense_105 (Dense)               (None, 784)          201488      dense_104[0][0]                  
==================================================================================================
Total params: 469,268
Trainable params: 469,268
Non-trainable params: 0

And here is the error I get when training starts:

Epoch 1/100
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/execute.py in quick_execute(op_name, num_outputs, inputs, attrs, ctx, name)
     59     tensors = pywrap_tfe.TFE_Py_Execute(ctx._handle, device_name, op_name,
---> 60                                         inputs, attrs, num_outputs)
     61   except core._NotOkStatusException as e:

TypeError: An op outside of the function building code is being passed
a "Graph" tensor. It is possible to have Graph tensors
leak out of the function building context by including a
tf.init_scope in your function building code.
For example, the following function will fail:
  @tf.function
  def has_init_scope():
    my_constant = tf.constant(1.)
    with tf.init_scope():
      added = my_constant * 2
The graph tensor has name: dense_92/BiasAdd:0

During handling of the above exception, another exception occurred:

_SymbolicException                        Traceback (most recent call last)
9 frames
/usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/execute.py in quick_execute(op_name, num_outputs, inputs, attrs, ctx, name)
     72       raise core._SymbolicException(
     73           "Inputs to eager execution function cannot be Keras symbolic "
---> 74           "tensors, but found {}".format(keras_symbolic_tensors))
     75     raise e
     76   # pylint: enable=protected-access

_SymbolicException: Inputs to eager execution function cannot be Keras symbolic tensors, but found [<tf.Tensor 'dense_92/BiasAdd:0' shape=(None, 2) dtype=float32>, <tf.Tensor 'dense_93/BiasAdd:0' shape=(None, 2) dtype=float32>]

Can anybody guide me how to tackle this issue?

The error is due to the loss function accessing tensors generated by the model, namely mu and log_var . Instead, you either need to create a custom training loop (eg using tf.GradientTape ) or alternatively use add_loss method of the model as follow:

vaeModel=Model(encoderInput,decoder)
vaeModel.add_loss(vae_loss(encoderInput, decoder))
vaeModel.compile(optimizer='adam') # No need to pass any loss function to compile method

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM