tensorflow.python.framework.errors\u impl.InvalidArgumentError:不兼容的形状:[128784]与[96784]

tensorflow.python.framework.errors\u impl.InvalidArgumentError:不兼容的形状:[128784]与[96784],tensorflow,keras,neural-network,deep-learning,autoencoder,Tensorflow,Keras,Neural Network,Deep Learning,Autoencoder,我正在用python Keras运行VAE模型。 我在拟合autoencoder模型时遇到了错误(这里的名称为“vae”) 错误: tensorflow.python.framework.errors\u impl.InvalidArgumentError:不兼容的形状:[128784]与[96784] 但我认为这两种形状在这里是相同的,正如我在下面展示的。 如果有人能给我一些建议,那将非常有帮助。谢谢 我的代码: from keras.layers import Lambda, Input,

我正在用python Keras运行VAE模型。 我在拟合autoencoder模型时遇到了错误(这里的名称为“vae”)

错误:

tensorflow.python.framework.errors\u impl.InvalidArgumentError:不兼容的形状:[128784]与[96784]

但我认为这两种形状在这里是相同的,正如我在下面展示的。 如果有人能给我一些建议,那将非常有帮助。谢谢

我的代码:

from keras.layers import Lambda, Input, Dense
from keras.models import Model
from keras.datasets import mnist
from keras.losses import mse, binary_crossentropy
from keras.utils import plot_model
from keras import backend as K


original_dim = 784 #28 * 28
input_shape = (original_dim, )
intermediate_dim = 512
batch_size = 128
latent_dim = 2
epochs = 50
epsilon_std = 1.0


#encoding
x = Input(batch_shape=(batch_size, original_dim))
h = Dense(intermediate_dim, activation = 'relu')(x) #h = hidden layer

#creating latent variable = z
z_mean = Dense(latent_dim)(h) #mean of latent variable (2 dimension)
z_log_sigma = Dense(latent_dim)(h) #log_sigma of latent variable (2 dimension)

def sampling(args):
    z_mean, z_log_sigma = args
    epsilon = K.random_normal(shape=(batch_size, latent_dim),
                              mean=0., 
                              #std=epsilon_std
                              )
    return(z_mean + K.exp(z_log_sigma) * epsilon)

z = Lambda(sampling, output_shape = (latent_dim,))([z_mean, z_log_sigma])

#encoder
encoder = Model(x, z_mean)

#decoding with z
decoder_h = Dense(intermediate_dim, activation='relu')
decoder_mean = Dense(original_dim, activation='sigmoid')

h_decoded = decoder_h(z)#input encoded z
x_decoded_mean = decoder_mean(h_decoded)

#autoencoder
vae = Model(x, x_decoded_mean)

#decoding to generate images
decoder_input = Input(shape=(latent_dim,))
_h_decoded = decoder_h(decoder_input)
_x_decoded_mean = decoder_mean(_h_decoded)

#generator
generator = Model(decoder_input, _x_decoded_mean)


#training
def vae_loss(x,x_decoded_mean):
    xent_loss = binary_crossentropy(x,x_decoded_mean)
    kl_loss = -0.5 * K.mean(1+z_log_sigma-K.square(z_mean)-K.exp(z_log_sigma), axis=-1)
    return(xent_loss+kl_loss)

vae.compile(optimizer = 'rmsprop', loss=vae_loss)

#creating dataset
(x_train, y_train), (x_test, y_test) = mnist.load_data()

x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:])))
x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))
print('x_train', x_train.shape)
print('x_test', x_test.shape)

vae.fit(x_train, x_train,
        shuffle=True,
        epochs=epochs,
        batch_size=batch_size,
        validation_data=(x_test, x_test))

根据您的代码,您似乎在模型中硬编码批量大小,这通常是一个坏主意

由于将输入定义为
x=input(batch\u shape=(batch\u size,original\u dim))
,因此网络希望数据正好位于shape
(128784)
。如果您的输入数据不是128的整数倍,则会出现问题,因为
vae.fit()
将分批分割数据,对于最后一批,如果没有足够的数据填充整个批,则会发送部分数据。看起来,上一批只有96个样本,而不是128个,因此模型会引发形状不匹配错误

正确的方法是:不要在模型中的任何地方指定批量大小,只将参数传递给
fit
。实际上,这归结为从不使用Keras层的
batch\u shape
参数,而是使用
shape
并传递一个样本的形状:

x = Input(shape=(original_dim,))
如果有任何操作需要指定完整形状(即包括批量大小),请使用
None

epsilon = K.random_normal(shape=(None, latent_dim),
                          mean=0., 
                          #std=epsilon_std
                          )

根据您的代码,您似乎在模型中硬编码批量大小,这通常是一个坏主意

由于将输入定义为
x=input(batch\u shape=(batch\u size,original\u dim))
,因此网络希望数据正好位于shape
(128784)
。如果您的输入数据不是128的整数倍,则会出现问题,因为
vae.fit()
将分批分割数据,对于最后一批,如果没有足够的数据填充整个批,则会发送部分数据。看起来,上一批只有96个样本,而不是128个,因此模型会引发形状不匹配错误

正确的方法是:不要在模型中的任何地方指定批量大小,只将参数传递给
fit
。实际上,这归结为从不使用Keras层的
batch\u shape
参数,而是使用
shape
并传递一个样本的形状:

x = Input(shape=(original_dim,))
如果有任何操作需要指定完整形状(即包括批量大小),请使用
None

epsilon = K.random_normal(shape=(None, latent_dim),
                          mean=0., 
                          #std=epsilon_std
                          )

你能给我们一个完整错误信息的复制粘贴吗?看来你是在模型中对批量大小进行硬编码,而不是将其保留为变量。如果数据样本不是批大小的精确倍数(最后一批较小,因此您看到的错误),则这将导致最后一个输入批出现问题。考虑在模型定义中指定批处理大小的沟槽(将其作为<代码>无代码/代码>)或修剪您的数据,因此它正好是批量大小的倍数。@ GPhilo谢谢您的评论。对不起,我是个新手,我真的不明白你指的是什么……为什么即使我确定了批量大小,他们的批量大小也不一样呢?我该如何修复代码呢?如果您能给我看任何代码示例,我非常高兴……再次感谢。不必抱歉,我们都是新的;)我将在适当的回答中详细说明。你能给我们一份完整错误信息的拷贝粘贴吗?看起来你是在模型中硬编码批量大小,而不是将其保留为变量。如果数据样本不是批大小的精确倍数(最后一批较小,因此您看到的错误),则这将导致最后一个输入批出现问题。考虑在模型定义中指定批处理大小的沟槽(将其作为<代码>无代码/代码>)或修剪您的数据,因此它正好是批量大小的倍数。@ GPhilo谢谢您的评论。对不起,我是个新手,我真的不明白你指的是什么……为什么即使我确定了批量大小,他们的批量大小也不一样呢?我该如何修复代码呢?如果您能给我看任何代码示例,我非常高兴……再次感谢。不必抱歉,我们都是新的;)我会在适当的回答中详细说明的。非常感谢,这让我完全信服。那么,我可以问一下,在什么样的情况下,您会为创建模型设置批量大小吗?很抱歉问了很多问题!不用担心:)原则上,除非有很好的理由,否则您永远不会在模型中设置批量大小。批量大小是一个训练超参数,与模型本身无关,因此模型应该是不可知的w.r.t。训练期间使用的特定批量非常感谢您,这完全让我信服。那么,我可以问一下,在什么样的情况下,您会为创建模型设置批量大小吗?很抱歉问了很多问题!不用担心:)原则上,除非有很好的理由,否则您永远不会在模型中设置批量大小。批次大小是一个训练超参数,与模型本身无关,因此模型应该是不可知的w.r.t。训练期间使用的特定批次大小