我正在尝试在https://blog.keras.io/building-autoencoders-in-keras.html中构建卷积自动编码器,但在代码部分
[...]lib/python3.5/site-packages/tensorflow/python/framework/common_shapes.py in _call_cpp_shape_fn_impl(op, input_tensors_needed, input_tensors_as_shapes_needed, debug_python_shape_fn, require_shape_fn)
673 missing_shape_fn = True
674 else:
--> 675 raise ValueError(err.message)
676
677 if missing_shape_fn:
ValueError: Dimensions must be equal, but are 1 and 16 for 'Conv2D_12' (op: 'Conv2D') with input shapes: [?,28,28,1], [3,3,16,1].
我收到错误
shape of input = [batch, in_height, in_width, in_channels]
shape of filter = [in_channels, filter_height, filter_width, out_channels]
我知道问题是错误的尺寸,我需要设置
print(x_train.shape)
print(x_test.shape)
(60000, 784)
(10000, 784)
正确 - 使用''模式(即使使用TensorFlow作为后端)。但是我不知道该怎么做。什么/我需要转动的螺丝在哪里?
我加载的数据(不是MNIST,但具有相似的尺寸)具有以下形状:
from keras.layers import Input, Dense, Convolution2D, MaxPooling2D, UpSampling2D
from keras.models import Model
# this is the size of our encoded representations
encoding_dim = 32 # 32 floats -> compression of factor 24.5, assuming the input is 784 floats
import tensorflow as tf
tf.merge_all_summaries = tf.summary.merge_all # see http://stackoverflow.com/questions/40046619/keras-tensorflow-gives-the-error-no-attribute-control-flow-ops
tf.train.SummaryWriter = tf.summary.FileWriter
# this is our input placeholder
input_img = Input(shape=(1, 28, 28))
dim_ordering = 'th' # see http://stackoverflow.com/questions/39848466/tensorflow-keras-convolution2d-valueerror-filter-must-not-be-larger-than-t/39882814
# "encoded" is the encoded representation of the input
x = Convolution2D(16, 3, 3, activation='relu', border_mode='same', dim_ordering=dim_ordering)(input_img)
x = MaxPooling2D((2, 2), border_mode='same', dim_ordering=dim_ordering)(x)
x = Convolution2D(8, 3, 3, activation='relu', border_mode='same', dim_ordering=dim_ordering)(x)
x = MaxPooling2D((2, 2), border_mode='same', dim_ordering=dim_ordering)(x)
x = Convolution2D(8, 3, 3, activation='relu', border_mode='same', dim_ordering=dim_ordering)(x)
encoded = MaxPooling2D((2, 2), border_mode='same', dim_ordering=dim_ordering)(x)
# at this point the representation is (8, 4, 4) i.e. 128-dimensional
# "decoded" is the lossy reconstruction of the input
x = Convolution2D(8, 3, 3, activation='relu', border_mode='same', dim_ordering=dim_ordering)(encoded)
x = UpSampling2D((2, 2), dim_ordering=dim_ordering)(x)
x = Convolution2D(8, 3, 3, activation='relu', border_mode='same', dim_ordering=dim_ordering)(x)
x = UpSampling2D((2, 2), dim_ordering=dim_ordering)(x)
x = Convolution2D(16, 3, 3, activation='relu', dim_ordering=dim_ordering)(x)
x = UpSampling2D((2, 2), dim_ordering=dim_ordering)(x)
decoded = Convolution2D(1, 3, 3, activation='sigmoid', border_mode='same', dim_ordering=dim_ordering)(x)
# this model maps an input to its reconstruction
autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='adam', loss='mean_squared_error')
# this model maps an input to its encoded representation
encoder = Model(input=input_img, output=encoded)
# create a placeholder for an encoded (32-dimensional) input
encoded_input = Input(shape=(1, 28, 28))
# retrieve the last layer of the autoencoder model
decoder_layer = autoencoder.layers[-1]
# create the decoder model
decoder = Model(input=encoded_input, output=decoder_layer(encoded_input))
autoencoder.compile(optimizer='adam', loss='mean_squared_error')
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.shape)
print(x_test.shape)
from keras.callbacks import TensorBoard
autoencoder.fit(x_train, x_train,
nb_epoch=3,
batch_size=128,
shuffle=True,
validation_data=(x_test, x_test),
callbacks=[TensorBoard(log_dir='/tmp/autoencoder')])
# encode and decode some digits
# note that we take them from the *test* set
encoded_imgs = encoder.predict(x_test)
decoded_imgs = decoder.predict(encoded_imgs)
# use Matplotlib (don't ask)
import matplotlib.pyplot as plt
n = 10 # how many digits we will display
plt.figure(figsize=(20, 4))
for i in range(n):
# display original
ax = plt.subplot(2, n, i + 1)
plt.imshow(x_test[i].reshape(28, 28))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
# display reconstruction
ax = plt.subplot(2, n, i + 1 + n)
plt.imshow(decoded_imgs[i].reshape(28, 28))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
n = 10
plt.figure(figsize=(20, 8))
for i in range(n):
ax = plt.subplot(1, n, i+1)
plt.imshow(encoded_imgs[i].reshape(4, 4 * 8).T)
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
---------------------------------------------------------------------------
InvalidArgumentError Traceback (most recent call last)
[...]/lib/python3.5/site-packages/tensorflow/python/framework/common_shapes.py in _call_cpp_shape_fn_impl(op, input_tensors_needed, input_tensors_as_shapes_needed, debug_python_shape_fn, require_shape_fn)
669 node_def_str, input_shapes, input_tensors, input_tensors_as_shapes,
--> 670 status)
671 except errors.InvalidArgumentError as err:
[...]/lib/python3.5/contextlib.py in __exit__(self, type, value, traceback)
65 try:
---> 66 next(self.gen)
67 except StopIteration:
[...]/lib/python3.5/site-packages/tensorflow/python/framework/errors_impl.py in raise_exception_on_not_ok_status()
468 compat.as_text(pywrap_tensorflow.TF_Message(status)),
--> 469 pywrap_tensorflow.TF_GetCode(status))
470 finally:
InvalidArgumentError: Dimensions must be equal, but are 1 and 16 for 'Conv2D_7' (op: 'Conv2D') with input shapes: [?,28,28,1], [3,3,16,1].
During handling of the above exception, another exception occurred:
ValueError Traceback (most recent call last)
<ipython-input-9-2658ab5e0418> in <module>()
4 decoder_layer = autoencoder.layers[-1]
5 # create the decoder model
----> 6 decoder = Model(input=encoded_input, output=decoder_layer(encoded_input))
[...]/lib/python3.5/site-packages/keras/engine/topology.py in __call__(self, x, mask)
570 if inbound_layers:
571 # This will call layer.build() if necessary.
--> 572 self.add_inbound_node(inbound_layers, node_indices, tensor_indices)
573 # Outputs were already computed when calling self.add_inbound_node.
574 outputs = self.inbound_nodes[-1].output_tensors
[...]/lib/python3.5/site-packages/keras/engine/topology.py in add_inbound_node(self, inbound_layers, node_indices, tensor_indices)
633 # creating the node automatically updates self.inbound_nodes
634 # as well as outbound_nodes on inbound layers.
--> 635 Node.create_node(self, inbound_layers, node_indices, tensor_indices)
636
637 def get_output_shape_for(self, input_shape):
[...]/lib/python3.5/site-packages/keras/engine/topology.py in create_node(cls, outbound_layer, inbound_layers, node_indices, tensor_indices)
164
165 if len(input_tensors) == 1:
--> 166 output_tensors = to_list(outbound_layer.call(input_tensors[0], mask=input_masks[0]))
167 output_masks = to_list(outbound_layer.compute_mask(input_tensors[0], input_masks[0]))
168 # TODO: try to auto-infer shape
[...]/lib/python3.5/site-packages/keras/layers/convolutional.py in call(self, x, mask)
473 border_mode=self.border_mode,
474 dim_ordering=self.dim_ordering,
--> 475 filter_shape=self.W_shape)
476 if self.bias:
477 if self.dim_ordering == 'th':
[...]/lib/python3.5/site-packages/keras/backend/tensorflow_backend.py in conv2d(x, kernel, strides, border_mode, dim_ordering, image_shape, filter_shape, filter_dilation)
2689 if filter_dilation == (1, 1):
2690 strides = (1,) + strides + (1,)
-> 2691 x = tf.nn.conv2d(x, kernel, strides, padding=padding)
2692 else:
2693 assert filter_dilation[0] == filter_dilation[1]
[...]/lib/python3.5/site-packages/tensorflow/python/ops/gen_nn_ops.py in conv2d(input, filter, strides, padding, use_cudnn_on_gpu, data_format, name)
394 strides=strides, padding=padding,
395 use_cudnn_on_gpu=use_cudnn_on_gpu,
--> 396 data_format=data_format, name=name)
397 return result
398
[...]/lib/python3.5/site-packages/tensorflow/python/framework/op_def_library.py in apply_op(self, op_type_name, name, **keywords)
761 op = g.create_op(op_type_name, inputs, output_types, name=scope,
762 input_types=input_types, attrs=attr_protos,
--> 763 op_def=op_def)
764 if output_structure:
765 outputs = op.outputs
[...]/lib/python3.5/site-packages/tensorflow/python/framework/ops.py in create_op(self, op_type, inputs, dtypes, input_types, name, attrs, op_def, compute_shapes, compute_device)
2395 original_op=self._default_original_op, op_def=op_def)
2396 if compute_shapes:
-> 2397 set_shapes_for_outputs(ret)
2398 self._add_op(ret)
2399 self._record_op_seen_by_control_dependencies(ret)
[...]/lib/python3.5/site-packages/tensorflow/python/framework/ops.py in set_shapes_for_outputs(op)
1755 shape_func = _call_cpp_shape_fn_and_require_op
1756
-> 1757 shapes = shape_func(op)
1758 if shapes is None:
1759 raise RuntimeError(
[...]/lib/python3.5/site-packages/tensorflow/python/framework/ops.py in call_with_requiring(op)
1705
1706 def call_with_requiring(op):
-> 1707 return call_cpp_shape_fn(op, require_shape_fn=True)
1708
1709 _call_cpp_shape_fn_and_require_op = call_with_requiring
[...]/lib/python3.5/site-packages/tensorflow/python/framework/common_shapes.py in call_cpp_shape_fn(op, input_tensors_needed, input_tensors_as_shapes_needed, debug_python_shape_fn, require_shape_fn)
608 res = _call_cpp_shape_fn_impl(op, input_tensors_needed,
609 input_tensors_as_shapes_needed,
--> 610 debug_python_shape_fn, require_shape_fn)
611 if not isinstance(res, dict):
612 # Handles the case where _call_cpp_shape_fn_impl calls unknown_shape(op).
[...]/lib/python3.5/site-packages/tensorflow/python/framework/common_shapes.py in _call_cpp_shape_fn_impl(op, input_tensors_needed, input_tensors_as_shapes_needed, debug_python_shape_fn, require_shape_fn)
673 missing_shape_fn = True
674 else:
--> 675 raise ValueError(err.message)
676
677 if missing_shape_fn:
ValueError: Dimensions must be equal, but are 1 and 16 for 'Conv2D_7' (op: 'Conv2D') with input shapes: [?,28,28,1], [3,3,16,1].
[...]是anaconda环境的路径
{{1}}
答案 0 :(得分:1)
尝试在所有卷积,上采样和最大化层中设置它:
Convolution2D(..., dim_ordering = 'th')
UpSampling2D(..., dim_ordering='th')
MaxPooling2D(..., dim_ordering='th')
您可以找到有关此功能的信息in the doc。
如果这没有帮助,您是否介意分享有关您的设置和版本的更多信息?
**编辑:**
这就是为什么你应该总是在你的问题中包含可执行代码。
您的错误是您以错误的方式复制粘贴tutorial的代码。
当他们构建这个解码器时:
encoded_input = Input(shape=(1, 28, 28))
# retrieve the last layer of the autoencoder model
decoder_layer = autoencoder.layers[-1]
# create the decoder model
decoder = Model(input=encoded_input, output=decoder_layer(encoded_input))
它是为之前的自动编码器制作的:
# this is our input placeholder
input_img = Input(shape=(784,))
# "encoded" is the encoded representation of the input
encoded = Dense(encoding_dim, activation='relu')(input_img)
# "decoded" is the lossy reconstruction of the input
decoded = Dense(784, activation='sigmoid')(encoded)
他们encoded_input
的形状与您的形状不匹配,因为您使用的是卷积自动编码器。所以你想要匹配:
encoded = MaxPooling2D((2, 2), border_mode='same', dim_ordering=dim_ordering)(x)
# at this point the representation is (8, 4, 4) i.e. 128-dimensional
一个输入,其形状(1,28,28)具有形状(8,4,4)的形状。密集自动编码器和卷积自动编码器之间的编码图像的形状是不同的。您的输入必须与您正在使用的模型的编码张量的形状相匹配。
首先要改变的是这一行:
encoded_input = Input(shape=(8,4,4))
现在,他们在这里做了什么:
decoder_layer = autoencoder.layers[-1]
是选择他们使用的模型的最后一层(密集自动编码器)。他们为什么这样做?这是因为他们的解码器只有一层大...所以他们接受它并将输入应用于它,这是他们的解码器。现在你的情况有点棘手,你想要使用所有的解码器端&#39;你的卷积自动编码器的各层。这就是你应该这样做的方式:
# Retrieve and apply the encoded input to the first layer of the decoder
# it corresponds to Convolution2D(8, 3, 3,...) part of your model if you count the layers.
decoder_layer = autoencoder.layers[-7](encoded_input)
# loop over the next layers of the decoder until the last one
for i in range(-6,0):
decoder_layer = autoencoder.layers[i](decoder_layer)
# create the decoder model
decoder = Model(input=encoded_input, output=decoder_layer)
更清楚吗?你无法复制/粘贴代码并使用部分代码构建复杂的东西,而不知道代码的这些部分是什么意思。