Keras中的训练变分自动编码器引发“ SymbolicException:渴望执行功能的输入不能是Keras符号张量”

问题描述

我正在用Keras做一个香草的变体自动编码器。以下是我的尝试:

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)

这是模型摘要

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

这是我开始训练时遇到的错误

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,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_s@R_404_6433@e in your function building code.
For example,the following function will fail:
  @tf.function
  def has_init_s@R_404_6433@e():
    my_constant = tf.constant(1.)
    with tf.init_s@R_404_6433@e():
      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,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>]

有人可以指导我如何解决这个问题吗?

解决方法

该错误是由于损失函数访问模型生成的张量,即mulog_var。相反,您需要创建自定义训练循环(例如,使用tf.GradientTape),或者使用模型的add_loss方法,如下所示:

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