python - Keras:我到底需要改变哪些维度?

标签 python tensorflow keras

问题

我正在尝试在 https://blog.keras.io/building-autoencoders-in-keras.html 中构建卷积自动编码器但在代码部分

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))

我得到了错误

[...]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]

正确 - 使用“th”模式(即使使用 TensorFlow 作为后端)。但是我不知道该怎么做。我需要准确转动的螺丝是什么/在哪里?

更多信息

输入数据

我加载的数据(不是 MNIST,但具有相似的维度)具有以下形状:

print(x_train.shape)
print(x_test.shape)

(60000, 784)
(10000, 784)

代码

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()

完整的错误信息

[...]是anaconda环境的路径

---------------------------------------------------------------------------
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].

最佳答案

尝试在所有卷积层、上采样层和最大池化层中设置它:

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]

是选择他们使用的模型的最后一层(密集自动编码器)。他们为什么这样做?这是因为他们的解码器只有一层大……所以他们接受它并将输入应用于它,这就是他们的解码器。现在你的情况有点棘手,你想使用卷积自动编码器的所有“解码器端”层。这是你应该如何做的:

 # 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)

是不是更清楚了?在不知道这些代码部分的含义的情况下,您不能复制/粘贴代码并使用部分代码构建复杂的东西。

关于python - Keras:我到底需要改变哪些维度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42588145/

相关文章:

python-3.x - 神经网络、Keras 的内存使用情况

tensorflow - 对全连接层使用单一共享偏差

python - Keras 中分类变量的嵌入问题

python - 在不知道字符数量的情况下进行负向预测

python - 有效地重新排列 2D NumPy 数组

python - 速率限制api多进程

tensorflow - 预期 input_1 有 3 个维度,但得到形状为 (3, 4) 的数组

python - 如何永久设置 LD_LIBRARY_PATH

python - Keras 预处理在使用 load_img() 导入图像时旋转图像

tensorflow - 如何对多个批处理的摘要进行平均?