Pad¶
Versioned name: Pad-12
Category: Data movement
Short description: Pad operation extends an input tensor on edges. The amount and value of padded elements are defined by inputs and attributes.
Detailed Description: The pad_mode attribute specifies a rule by which new element values are generated. For example, whether they are filled with a given constant or generated based on the input tensor content. The number of new elements to be added (positive value) or removed (negative value) is set by the pads_begin
and pads_end
inputs.
The following examples illustrate how output tensor is generated for the Pad layer for a given inputs:
Positive pads example:¶
pads_begin = [0, 1]
pads_end = [2, 3]
DATA =
[[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]]
depending on the pad_mode attribute:
pad_mode = "constant"
:
OUTPUT =
[[ 0, 1, 2, 3, 4, 0, 0, 0 ]
[ 0, 5, 6, 7, 8, 0, 0, 0 ]
[ 0, 9, 10, 11, 12, 0, 0, 0 ]
[ 0, 0, 0, 0, 0, 0, 0, 0 ]
[ 0, 0, 0, 0, 0, 0, 0, 0 ]]
pad_mode = "edge"
:
OUTPUT =
[[ 1, 1, 2, 3, 4, 4, 4, 4 ]
[ 5, 5, 6, 7, 8, 8, 8, 8 ]
[ 9, 9, 10, 11, 12, 12, 12, 12 ]
[ 9, 9, 10, 11, 12, 12, 12, 12 ]
[ 9, 9, 10, 11, 12, 12, 12, 12 ]]
pad_mode = "reflect"
:
OUTPUT =
[[ 2, 1, 2, 3, 4, 3, 2, 1 ]
[ 6, 5, 6, 7, 8, 7, 6, 5 ]
[ 10, 9, 10, 11, 12, 11, 10, 9 ]
[ 6, 5, 6, 7, 8, 7, 6, 5 ]
[ 2, 1, 2, 3, 4, 3, 2, 1 ]]
pad_mode = "symmetric"
:
OUTPUT =
[[ 1, 1, 2, 3, 4, 4, 3, 2 ]
[ 5, 5, 6, 7, 8, 8, 7, 6 ]
[ 9, 9, 10, 11, 12, 12, 11, 10 ]
[ 9, 9, 10, 11, 12, 12, 11, 10 ]
[ 5, 5, 6, 7, 8, 8, 7, 6 ]]
Negative pads example:¶
pads_begin = [-1, -1]
pads_end = [-1, -1]
DATA =
[[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]]
Shape(3, 4)
for all of the pad_mode attribute options:
pad_mode = "constant"
pad_mode = "edge"
pad_mode = "reflect"
pad_mode = "symmetric"
OUTPUT =
[[ 6, 7 ]]
Shape(1, 2)
Mixed pads example:¶
pads_begin = [2, -1]
pads_end = [-1, 3]
DATA =
[[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]]
Shape(3, 4)
pad_mode = "constant"
:
OUTPUT =
[[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[2, 3, 4, 0, 0, 0],
[6, 7, 8, 0, 0, 0]]
Shape(4, 6)
pad_mode = "edge"
:
OUTPUT Shape(4, 6) =
[[2, 3, 4, 4, 4, 4],
[2, 3, 4, 4, 4, 4],
[2, 3, 4, 4, 4, 4],
[6, 7, 8, 8, 8, 8]]
Shape(4, 6)
pad_mode = "reflect"
:
OUTPUT =
[[10, 11, 12, 11, 10, 9],
[6, 7, 8, 7, 6, 5],
[2, 3, 4, 3, 2, 1],
[6, 7, 8, 7, 6, 5]]
Shape(4, 6)
pad_mode = "symmetric"
:
OUTPUT =
[[6, 7, 8, 8, 7, 6],
[2, 3, 4, 4, 3, 2],
[2, 3, 4, 4, 3, 2],
[6, 7, 8, 8, 7, 6]]
Shape(4, 6)
Attributes
pad_mode
Description: pad_mode specifies the method used to generate the padding values.
Range of values: Name of the method in string format:
constant
- padded values are taken from the pad_value input. If the input is not provided, the padding elements are equal to zero.edge
- padded values are copied from the respective edge of the inputdata
tensor.reflect
- padded values are a reflection of the input data tensor. Values on the edges are not duplicated,pads_begin[D]
andpads_end[D]
must be not greater thandata.shape[D] – 1
for any validD
.symmetric
- padded values are symmetrically added from the inputdata
tensor. This method is similar to thereflect
, but values on edges are duplicated. Refer to the examples above for more details.pads_begin[D]
andpads_end[D]
must be not greater thandata.shape[D]
for any validD
.
Type:
string
Required: yes
Inputs
1:
data
tensor of arbitrary shape and type T. Required.2:
pads_begin
1D tensor of type T_INT. Number of elements matches the shape rank of data input. Specifies the number of padding elements to add at the beginning of each axis. Negative value means cropping the corresponding dimension’s value. Required.3:
pads_end
1D tensor of type T_INT. Number of elements matches the shape rank of data input. Specifies the number of padding elements to add at the end of each axis. Negative value means cropping the corresponding dimension’s value. Required.4:
pad_value
scalar tensor of type T. Takes effect only ifpad_mode == "constant"
only. All padding elements are populated with this value or with 0 if the input is not provided. This input should not be set with other values ofpad_mode
. Optional.
Outputs
1: Padded output tensor of type T with dimensions
max(pads_begin[D] + data.shape[D] + pads_end[D], 0)
for eachD
from0
tolen(data.shape) - 1
.
Types
T: any numeric type.
T_INT: any integer type.
Example: constant mode (positive pads)
<layer ... type="Pad" ...>
<data pad_mode="constant"/>
<input>
<port id="0">
<dim>1</dim>
<dim>3</dim>
<dim>32</dim>
<dim>40</dim>
</port>
<port id="1">
<dim>4</dim> <!-- pads_begin = [0, 5, 2, 1] -->
</port>
<port id="2">
<dim>4</dim> <!-- pads_end = [1, 0, 3, 7] -->
</port>
<port id="3">
<!-- pad_value = 15.0 -->
</port>
</input>
<output>
<port id="0">
<dim>2</dim> <!-- 2 = 0 + 1 + 1 = pads_begin[0] + input.shape[0] + pads_end[0] -->
<dim>8</dim> <!-- 8 = 5 + 3 + 0 = pads_begin[1] + input.shape[1] + pads_end[1] -->
<dim>37</dim> <!-- 37 = 2 + 32 + 3 = pads_begin[2] + input.shape[2] + pads_end[2] -->
<dim>48</dim> <!-- 48 = 1 + 40 + 7 = pads_begin[3] + input.shape[3] + pads_end[3] -->
<!-- all new elements are filled with 15.0 value -->
</port>
</output>
</layer>
Example: constant mode (positive and negative pads)
<layer ... type="Pad" ...>
<data pad_mode="constant"/>
<input>
<port id="0">
<dim>2</dim>
<dim>3</dim>
<dim>32</dim>
<dim>40</dim>
</port>
<port id="1">
<dim>4</dim> <!-- pads_begin = [0, -2, -8, 1] -->
</port>
<port id="2">
<dim>4</dim> <!-- pads_end = [-1, 4, -6, 7] -->
</port>
<port id="3">
<!-- pad_value = 15.0 -->
</port>
</input>
<output>
<port id="0">
<dim>1</dim> <!-- 2 = 0 + 2 + (-1) = pads_begin[0] + input.shape[0] + pads_end[0] -->
<dim>5</dim> <!-- 5 = (-2) + 3 + 4 = pads_begin[1] + input.shape[1] + pads_end[1] -->
<dim>18</dim> <!-- 18 = (-8) + 32 (-6) = pads_begin[2] + input.shape[2] + pads_end[2] -->
<dim>48</dim> <!-- 48 = 1 + 40 + 7 = pads_begin[3] + input.shape[3] + pads_end[3] -->
<!-- all new elements are filled with 15.0 value -->
</port>
</output>
</layer>
Example: edge mode
<layer ... type="Pad" ...>
<data pad_mode="edge"/>
<input>
<port id="0">
<dim>1</dim>
<dim>3</dim>
<dim>32</dim>
<dim>40</dim>
</port>
<port id="1">
<dim>4</dim> <!-- pads_begin = [0, 5, 2, 1] -->
</port>
<port id="2">
<dim>4</dim> <!-- pads_end = [1, 0, 3, 7] -->
</port>
</input>
<output>
<port id="0">
<dim>2</dim> <!-- 2 = 0 + 1 + 1 = pads_begin[0] + input.shape[0] + pads_end[0] -->
<dim>8</dim> <!-- 8 = 5 + 3 + 0 = pads_begin[1] + input.shape[1] + pads_end[1] -->
<dim>37</dim> <!-- 37 = 2 + 32 + 3 = pads_begin[2] + input.shape[2] + pads_end[2] -->
<dim>48</dim> <!-- 48 = 1 + 40 + 7 = pads_begin[3] + input.shape[3] + pads_end[3] -->
</port>
</output>
</layer>