Python 无法将符号Keras输入/输出转换为numpy数组
我下面介绍如何创建一个生成式变分自动编码器。然而,我使用的是从Kaggle提取的狗的3个通道(RGB)的图像。我正在构建自动编码器,但出现以下错误:Python 无法将符号Keras输入/输出转换为numpy数组,python,tensorflow,machine-learning,keras,deep-learning,Python,Tensorflow,Machine Learning,Keras,Deep Learning,我下面介绍如何创建一个生成式变分自动编码器。然而,我使用的是从Kaggle提取的狗的3个通道(RGB)的图像。我正在构建自动编码器,但出现以下错误: Cannot convert a symbolic Keras input/output to a numpy array. This error may indicate that you're trying to pass a symbolic value to a NumPy call, which is not supported. Or,
Cannot convert a symbolic Keras input/output to a numpy array. This error may indicate that you're trying to pass a symbolic value to a NumPy call, which is not supported. Or, you may be trying to pass Keras symbolic inputs/outputs to a TF API that does not register dispatching, preventing Keras from automatically converting the API call to a lambda layer in the Functional Model.
以下是相关代码:
batch_size = 32
train_ds = tf.data.Dataset.from_tensor_slices(dog_images).batch(batch_size).prefetch(1)
...
# Build encoder
latent_dim = 32
input_data = keras.layers.Input(shape=(256, 256, 3))
encoder = keras.layers.Conv2D(256, 4, 2, "same")(input_data)
encoder = keras.layers.Conv2D(256, 4, 2, "same")(encoder)
encoder = keras.layers.LeakyReLU(0.2)(encoder)
...
encoder = keras.layers.Conv2D(latent_dim * 2, 4, 2, "same", use_bias=False)(encoder)
encoder = keras.layers.Flatten()(encoder)
encoder_mu = keras.layers.Dense(units=latent_dim, name="encoder_mu")(encoder)
encoder_log_variance = keras.layers.Dense(units=latent_dim, name="encoder_log_variance")(encoder)
encoder = Sampling()([encoder_mu, encoder_log_variance])
encoder_model = keras.Model(input_data, [encoder_mu, encoder_log_variance, encoder], name="encoder")
encoder_model.summary()
下面是总结的图像。我觉得奇怪的是,输入层的形状是一个开始的[
,但没有结束的]
接下来,这里是解码器:
decoder_input = keras.layers.Input(shape=(32,))
decoder = keras.layers.Dense(4096)(decoder_input)
decoder = keras.layers.Reshape((8, 8, 64))(decoder) #(8, 8, 64)
decoder = keras.layers.Conv2DTranspose(512, 3, strides=2, padding="same")(decoder) #(16, 16, 512)
decoder = keras.layers.BatchNormalization()(decoder)
decoder = keras.layers.ReLU()(decoder)
...
decoder = keras.layers.Conv2DTranspose(3, 3, strides=2, padding="same")(decoder) #(256, 256, 3)
decoder = keras.layers.BatchNormalization()(decoder)
decoder_output = keras.layers.ReLU()(decoder)
decoder_model = keras.Model(decoder_input, decoder_output)
decoder_model.summary()
总结如下:
接下来我构建自动编码器并对其进行训练,但在它训练一个历元(或者,显然是一批)之前,它会抛出错误
_, _, encoded = encoder_model(input_data)
decoded = decoder_model(encoded)
autoencoder = keras.models.Model(input_data, decoded)
autoencoder.summary()
autoencoder.compile(loss=get_loss(encoder_mu, encoder_log_variance), optimizer='adam')
autoencoder.summary()
autoencoder.fit(train_ds, epochs=3)
如您所见,我使用的是一个自定义的丢失函数,我从链接教程中复制并粘贴了该函数。这是:
def get_loss(distribution_mean, distribution_variance):
def get_reconstruction_loss(y_true, y_pred):
reconstruction_loss = keras.losses.mse(y_true, y_pred)
reconstruction_loss_batch = tf.reduce_mean(reconstruction_loss)
return reconstruction_loss_batch*256*256
def get_kl_loss(distribution_mean, distribution_variance):
kl_loss = 1 + distribution_variance - tf.square(distribution_mean) - tf.exp(distribution_variance)
kl_loss_batch = tf.reduce_mean(kl_loss)
return kl_loss_batch*(-0.5)
def total_loss(y_true, y_pred):
reconstruction_loss_batch = get_reconstruction_loss(y_true, y_pred)
kl_loss_batch = get_kl_loss(distribution_mean, distribution_variance)
return reconstruction_loss_batch + kl_loss_batch
return total_loss
你知道是什么导致了这个问题吗
编辑:
下面是我的代码的相关NumPy部分。我以np数组的形式获取图像,并在图像周围添加了黑色空间,这样它们的大小都可以256x256
而不会扭曲纵横比:
import pathlib
data_dir_str = '/content/dogs/all-dogs/'
data_dir = pathlib.Path(data_dir_str)
dogs = list(data_dir.glob('*.jpg'))
PIL.Image.open(str(dogs[0]))
...
from PIL import Image, ImageOps
desired_size = 256
def resizeImage(im_pth):
im = Image.open(im_pth)
old_size = im.size # old_size[0] is in (width, height) format
ratio = float(desired_size) / max(old_size)
new_size = tuple([int(x * ratio) for x in old_size])
# use thumbnail() or resize() method to resize the input image
# thumbnail is a in-place operation
# im.thumbnail(new_size, Image.ANTIALIAS)
im = im.resize(new_size, Image.ANTIALIAS)
# create a new image and paste the resized on it
new_im = Image.new("RGB", (desired_size, desired_size))
new_im.paste(im, ((desired_size - new_size[0]) // 2,
(desired_size - new_size[1]) // 2))
return np.asarray(new_im)
new_dogs = list(map(resizeImage, dogs[:10]))
...
def scalePixels(x):
return x.astype('float32') / 255
new_dogs = scalePixels(np.array(new_dogs))
因此,我曾尝试使用新狗
进行如下训练:
autoencoder.fit(new_dogs, new_dogs, epochs=3)
我还尝试使用这个TF数据集:
# turn array of [x1, x2, x3...] to [(x1, x1), (x2, x2)...]
f = lambda x: (x,x)
new_dogs_toup = f(new_dogs)
batch_size = 32
train_ds = tf.data.Dataset.from_tensor_slices(new_dogs_toup).batch(batch_size).prefetch(1)
最后,我运行了get\u loss(编码器\u mu,编码器\u log\u variance)
,下面是输出:
我在您的代码中没有看到任何numpy调用。你叫努比吗?如果是的话,请加上这部分代码。符号张量的用法对我来说很奇怪。尝试在ot
compile()之外调用get\u loss(编码器\u mu,编码器\u log\u variance)
。它有效吗?@Andrey我已经更新了问题,加入了NumPy代码。我还添加了get\u loss(encoder\u mu,encoder\u log\u variance)
采样()层在这里做什么?这是某种numpy函数吗?如果是,那么我认为这就是错误发生的地方。