tf.nn.conv2d_transpose.md 3.5 KB
Newer Older
J
jiangjiajun 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

## tf.nn.conv2d_transpose

### [tf.nn.conv2d_transpose](https://www.tensorflow.org/api_docs/python/tf/nn/conv2d_transpose)
``` python
tf.nn.conv2d_transpose(
    value,
    filter,
    output_shape,
    strides,
    padding='SAME',
    data_format='NHWC',
    name=None
)
```

J
jiangjiajun 已提交
17
### [paddle.fluid.layers.conv2d_transpose](http://paddlepaddle.org/documentation/docs/zh/1.4/api_cn/layers_cn.html#paddle.fluid.layers.conv2d_transpose)
J
jiangjiajun 已提交
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
``` python
paddle.fluid.layers.conv2d_transpose(
    input, 
    num_filters, 
    output_size=None, 
    filter_size=None, 
    padding=0, 
    stride=1, 
    dilation=1, 
    groups=None, 
    param_attr=None, 
    bias_attr=None, 
    use_cudnn=True, 
    act=None, 
    name=None
)
```

### 功能差异

#### 数据格式

TensorFlow: 默认输入数据格式为`NHWC`,表示`(batch,height, width, in_channels)`, 同时也将`data_format`参数设为`channels_first`,支持`NCHW`格式的数据输入。其中输入、输出、卷积核对应关系如下表所示,

| 输入 | 卷积核 | 输出 |
|--------------------|-------------------|------------------|
|NHWC | (kernel_h, kernel_w, filters_num, in_channels)| (batch, out_h, out_w, filters_num)|
|NDHW | (kernel_h, kernel_w, filters_num, in_channels) | (batch, filters_num, out_h, out_w)|

PaddlePaddle:只支持输入数据格式为`NCHW`,且**卷积核格式**与TensorFlow不同,其中输入、输出、卷积核对应关系如下表所示,

| 输入 | 卷积核 | 输出 |
|--------------------|-------------------|------------------|
|NCHW | (in_channels, filters_num, kernel_h, kernel_w) | (batch, filters_num, out_h, out_w)|

#### Padding机制
TensorFlow: `SAME``VALID`两种选项。当为`SAME`时,padding的计算方式如下所示
```python
# 计算在width上的padding size
# height上的padding计算方式同理
ceil_size = ceil(input_width / stride_width)
pad_size = (ceil_size - 1) * stride_width + filter_width - input_width
pad_left = ceil(pad_size / 2)
pad_right = pad_size - pad_left
```
PaddlePaddle:`padding`参数表示在输入图像四周padding的size大小

#### 输出大小
TensorFlow:当padding为`SAME``VALID`两种情况下,输出大小计算方式如下所示
```python
if padding == 'SAME':
    output_size = input_size * stride
elif padding == 'VALID':
    output_size = input_size * stride + max(kernel_size - stride, 0)
```
PaddlePaddle: 输出大小计算公式如下,差异主要由于TensorFlow在`conv2d_transpose`的最后还存在**裁剪**步骤,因此可参考示例代码,调用`crop`解决
```python
output_size = (input_size - 1) * stride - 2 * padding + dilation * (kernel - 1) + 1
```

### 代码示例
```python
# TensorFlow使用conv2d_transpose
# 输入shape: [-1, 20, 20, 3]
inputs = tf.placeholder(dtype=tf.float32, shape=[None, 20, 20, 3])
filter = tf.random_uniform(shape=[5, 5, 3, 3], 0.0 1.0)
batch = tf.shape(inputs)[0]
# conv2d_transpose输出shape: [-1, 40, 40, 3]
result = tf.nn.conv2d_transpose(inputs, filter, output_shape=[batch, 40, 40, 3], 
                         strides=[1, 2, 2, 1], padding='SAME')

#PaddlePaddle中使用conv2d_transpose
# 输入Shape:(None, 3, 20, 20)
inputs = fluid.layers.data(dtype='float32', shape=[3, 20, 20], name='inputs)
# conv2d_transpose输出shape:[-1, 3, 41, 41]
outputs = fluid.layers.conv2d_transpose(pad_inputs, 3, filter_size=[5, 5], 
                        padding=[1, 1],  stride=[2, 2], bias_attr=False)
# 裁剪后结果即为与TensorFlow一致
outputs = fluid.layers.crop(outputs, shape=[-1, 3, 40, 40])