keras output_shape问题

时间:2016-11-06 19:20:21

标签: convolution keras deconvolution

我正在实施以下Colorization Model written in Caffe。我对我在keras中提供的output_shape参数感到困惑

model.add(Deconvolution2D(256,4,4,border_mode='same',
output_shape=(None,3,14,14),subsample=(2,2),dim_ordering='th',name='deconv_8.1'))

我添加了一个虚拟的output_shape参数。但是如何确定输出参数呢?在caffe模型中,图层定义为:

layer {
 name: "conv8_1"
  type: "Deconvolution"
  bottom: "conv7_3norm"
  top: "conv8_1"
  convolution_param {
    num_output: 256
    kernel_size: 4
    pad: 1
    dilation: 1
    stride: 2
  }

如果我不提供此参数,代码会给出参数错误但我无法理解我应该提供什么作为output_shape

P.S。已经在数据科学论坛页面上询问,没有回应。可能是由于用户群较小

1 个答案:

答案 0 :(得分:1)

Caffe反卷积层产生什么输出形状?

对于此着色模型,您可以简单地参考their paper的第24页(在其GitHub页面中链接):

Colorization model architecture

所以基本上原始模型中这个反卷积层的输出形状是[无,56,56,128]。这是您想要作为output_shape传递给Keras的内容。唯一的问题就是我在下面的部分中提到的,Keras并没有真正使用这个参数来确定输出形状,所以你需要运行一个虚拟预测来找到你需要的其他参数,以便你能够得到你想要的东西。

更常见的是Caffe source code for computing its Deconvolution layer output shape是:

    const int kernel_extent = dilation_data[i] * (kernel_shape_data[i] - 1) + 1;
    const int output_dim = stride_data[i] * (input_dim - 1)
    + kernel_extent - 2 * pad_data[i];

扩张参数等于1的情况简化为:

    const int output_dim = stride_data[i] * (input_dim - 1)
    + kernel_shape_data[i] - 2 * pad_data[i];

请注意,当参数a为零时,这与Keras documentation匹配:

  

计算输出形状的公式34:o = s(i - 1)+   a + k - 2p

如何使用Keras后端验证实际输出形状

这很棘手,因为实际的输出形状取决于后端实现和配置。 Keras目前无法单独找到它。因此,您实际上必须对某些虚拟输入执行预测以找到实际的输出形状。以下是如何从Derasvolution2D的Keras文档中执行此操作的示例:

To pass the correct `output_shape` to this layer,
one could use a test model to predict and observe the actual output shape.
# Examples
```python
    # apply a 3x3 transposed convolution with stride 1x1 and 3 output filters on a 12x12 image:
    model = Sequential()
    model.add(Deconvolution2D(3, 3, 3, output_shape=(None, 3, 14, 14), border_mode='valid', input_shape=(3, 12, 12)))
    # Note that you will have to change the output_shape depending on the backend used.
    # we can predict with the model and print the shape of the array.
    dummy_input = np.ones((32, 3, 12, 12))
    # For TensorFlow dummy_input = np.ones((32, 12, 12, 3))
    preds = model.predict(dummy_input)
    print(preds.shape)
    # Theano GPU: (None, 3, 13, 13)
    # Theano CPU: (None, 3, 14, 14)
    # TensorFlow: (None, 14, 14, 3)

参考:https://github.com/fchollet/keras/blob/master/keras/layers/convolutional.py#L507

另外,您可能很想知道为什么output_shape参数显然没有真正定义输出形状。根据帖子Deconvolution2D layer in keras,这就是原因:

  

回到Keras以及如何实现上述内容。令人困惑的是,output_shape参数实际上并不用于确定图层的输出形状,而是尝试从输入,内核大小和步幅中推导出它,同时假设只提供了有效的output_shapes(尽管它已经提供了#)未在代码中检查是否是这种情况)。 output_shape本身仅用作backprop步骤的输入。因此,您还必须指定stride参数(Keras中的子样本)以获得所需的结果(Keras可以从给定的输入形状,输出形状和内核大小确定)。