ONE - On-device Neural Engine
Loading...
Searching...
No Matches
arm_compute::NETransposeConvLayer Class Reference

#include <NETransposeConvLayer.h>

Collaboration diagram for arm_compute::NETransposeConvLayer:

Public Member Functions

 NETransposeConvLayer (std::shared_ptr< IMemoryManager > memory_manager=nullptr)
 
 NETransposeConvLayer (const NETransposeConvLayer &)=delete
 
NETransposeConvLayeroperator= (const NETransposeConvLayer &)=delete
 
 NETransposeConvLayer (NETransposeConvLayer &&)=delete
 
NETransposeConvLayeroperator= (NETransposeConvLayer &&)=delete
 
virtual ~NETransposeConvLayer ()=default
 
void configure (ITensor *input, const ITensor *weights, const ITensor *bias, ITensor *output, const PadStrideInfo &info, unsigned int invalid_right, unsigned int invalid_bottom)
 
void run () override
 
void prepare () override
 

Static Public Member Functions

static Status validate (const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *bias, const ITensorInfo *output, const PadStrideInfo &info, unsigned int invalid_right, unsigned int invalid_bottom)
 

Detailed Description

Function to run the deconvolution layer.

Deconvolution Layer is the backward pass of Convolution Layer. First we transform the input depending on the stride and pad info and then perfrom a 1x1 convolution pass. Input stride defines how many zeroes we should put between each element of the input, pad is the amount of padding and finaly a is a user specified value where a < stride - 1 that increases the padding top and right of the input image.

The relation between input to output is as follows:

\[
      width\_output = (width\_input - 1) \cdot stride\_x - 2 \cdot padding\_x + kernel\_x
 \]

\[
      height\_output = (height\_input - 1) \cdot stride\_y - 2 \cdot padding\_y + kernel\_y
 \]

where width is the size of the first input dimension. height is the size of the second input dimension. width_output is the size of the first output dimension. height_output is the size of the second output dimension. kernel_x and kernel_y are the convolution sizes in x and y. stride_x and stride_y is the input stride of the first and second dimension.

The weights used by Deconvolution are supposed to be the same as the ones used for Convolution. Therefore, it will be necessary to use the weights in the reverse order to perform an actual convolution. This is achieved by using NEReverse.

This function calls the following NEON kernels/functions:

  1. CPPUpsampleEx
  2. NEConvolutionLayer
  3. NEPermute
  4. NEReverse

Definition at line 94 of file NETransposeConvLayer.h.

Constructor & Destructor Documentation

◆ NETransposeConvLayer() [1/3]

arm_compute::NETransposeConvLayer::NETransposeConvLayer ( std::shared_ptr< IMemoryManager >  memory_manager = nullptr)

Constructor

Definition at line 54 of file NETransposeConvLayer.cpp.

55 : _memory_group(std::move(memory_manager)), _conv_f(), _upsample_f(), _flip_weights(),
56 _scaled_output(), _weights_flipped(), _flip_axis(), _original_weights(nullptr), _input(nullptr),
57 _info(), _is_prepared(false)
58{
59}

◆ NETransposeConvLayer() [2/3]

arm_compute::NETransposeConvLayer::NETransposeConvLayer ( const NETransposeConvLayer )
delete

Prevent instances of this class from being copied (As this class contains pointers)

◆ NETransposeConvLayer() [3/3]

arm_compute::NETransposeConvLayer::NETransposeConvLayer ( NETransposeConvLayer &&  )
delete

Allow instances of this class to be moved

◆ ~NETransposeConvLayer()

virtual arm_compute::NETransposeConvLayer::~NETransposeConvLayer ( )
virtualdefault

Default destructor

References validate().

Member Function Documentation

◆ configure()

void arm_compute::NETransposeConvLayer::configure ( ITensor *  input,
const ITensor *  weights,
const ITensor *  bias,
ITensor *  output,
const PadStrideInfo &  info,
unsigned int  invalid_right,
unsigned int  invalid_bottom 
)

Set the input, weights, biases and output tensors.

Parameters
[in,out]inputInput tensor. 3 lower dimensions represent a single input, and an optional 4th dimension for batch of inputs. Data types supported: F32/F16/QASYMM8/QASYMM8_SIGNED.
[in]weightsThe 4d weights with dimensions [width, height, IFM, OFM]. Data type supported: Same as input.
[in]biasOptional, ignored if NULL. The biases have one dimension. Data type supported: Data types supported: S32 for QASYMM8 and QASYMM8_SIGNED input, F32 for F32 input, F16 for F16 input.
[out]outputOutput tensor. The output has the same number of dimensions as the input.
[in]infoContains padding and policies to be used in the deconvolution, this is decribed in PadStrideInfo.
[in]invalid_rightThe number of zeros added to right edge of the output.
[in]invalid_bottomThe number of zeros added to bottom edge of the output.

Definition at line 135 of file NETransposeConvLayer.cpp.

138{
139 // Perform validation step
140 ARM_COMPUTE_ERROR_ON_NULLPTR(input, weights, output);
141 ARM_COMPUTE_ERROR_THROW_ON(NETransposeConvLayer::validate(
142 input->info(), weights->info(), (bias == nullptr) ? nullptr : bias->info(), output->info(),
143 info, invalid_right, invalid_bottom));
144
145 const DataLayout data_layout = input->info()->data_layout();
146 const unsigned int width_idx =
147 get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
148 const unsigned int height_idx =
149 get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT);
150 auto out_dims = transposeconv_output_dimensions(
151 input->info()->dimension(width_idx), input->info()->dimension(height_idx),
152 weights->info()->dimension(width_idx), weights->info()->dimension(height_idx), info,
153 invalid_right, invalid_bottom);
154
156 compute_transposeconv_output_shape(out_dims, *input->info(), *weights->info());
157
158 _input = input;
159 _original_weights = weights;
160 _info = info;
161 _is_prepared = false;
162
163 unsigned int pad_left = 0;
164 unsigned int pad_right = 0;
165 unsigned int pad_top = 0;
166 unsigned int pad_bottom = 0;
167 const unsigned int stride_x = info.stride().first;
168 const unsigned int stride_y = info.stride().second;
169
170 // Output auto initialization if not yet initialized
171 auto_init_if_empty(*output->info(), output_shape, 1, input->info()->data_type(),
172 input->info()->quantization_info());
173
174 _flip_axis.allocator()->init(TensorInfo(TensorShape(2U), 1, DataType::U32));
175 _memory_group.manage(&_scaled_output);
176
177 _weights_flipped.allocator()->init(weights->info()->clone()->set_data_layout(data_layout));
178 _flip_weights.configure(weights, &_weights_flipped, &_flip_axis);
179
180 // setup the function to convolve the upscaled output
181 const PadStrideInfo conv_info(1, 1, 0, 0, 0, 0, DimensionRoundingType::CEIL);
182
184 *input->info(), *weights->info(), info, out_dims, invalid_right, invalid_bottom, pad_left,
185 pad_right, pad_top, pad_bottom);
186
187 const PadStrideInfo upsample_info(stride_x, stride_y, pad_left, pad_right, pad_top, pad_bottom,
188 DimensionRoundingType::FLOOR);
189
190 TensorInfo scale_out_info(scale_out_shape, 1, input->info()->data_type(),
191 input->info()->quantization_info());
192 scale_out_info.set_data_layout(data_layout);
193 _scaled_output.allocator()->init(scale_out_info);
194
195 _upsample_f.configure(input, &_scaled_output, upsample_info);
196
197 _conv_f.configure(&_scaled_output, &_weights_flipped, bias, output, conv_info);
198
199 // Setup flip axis data
200 _flip_axis.allocator()->allocate();
201 auto axis_data = reinterpret_cast<uint32_t *>(_flip_axis.buffer());
202 axis_data[0] = static_cast<uint32_t>(width_idx);
203 axis_data[1] = static_cast<uint32_t>(height_idx);
204
205 _scaled_output.allocator()->allocate();
206}
static Status validate(const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *bias, const ITensorInfo *output, const PadStrideInfo &info, unsigned int invalid_right, unsigned int invalid_bottom)
volatile const char info[]
const luci_interpreter::RuntimeShape output_shape
::nncc::core::ADT::tensor::Shape TensorShape
Definition TensorShape.h:25
TensorShape compute_transposeconv_upsampled_shape(const ITensorInfo &input, const ITensorInfo &weights, const PadStrideInfo &info, std::pair< unsigned int, unsigned int > &out_dims, unsigned int invalid_right, unsigned int invalid_bottom, unsigned int &pad_left, unsigned int &pad_right, unsigned int &pad_top, unsigned int &pad_bottom)
TensorShape compute_transposeconv_output_shape(const std::pair< unsigned int, unsigned int > &out_dims, const ITensorInfo &input, const ITensorInfo &weights)
const std::pair< unsigned int, unsigned int > transposeconv_output_dimensions(unsigned int in_width, unsigned int in_height, unsigned int kernel_width, unsigned int kernel_height, const PadStrideInfo &info, unsigned int invalid_right, unsigned int invalid_top)
Definition UtilsEx.cpp:47

References arm_compute::misc::shape_calculator::compute_transposeconv_output_shape(), arm_compute::misc::shape_calculator::compute_transposeconv_upsampled_shape(), info, output_shape, arm_compute::transposeconv_output_dimensions(), and validate().

◆ operator=() [1/2]

NETransposeConvLayer & arm_compute::NETransposeConvLayer::operator= ( const NETransposeConvLayer )
delete

Prevent instances of this class from being copied (As this class contains pointers)

◆ operator=() [2/2]

NETransposeConvLayer & arm_compute::NETransposeConvLayer::operator= ( NETransposeConvLayer &&  )
delete

Allow instances of this class to be moved

◆ prepare()

void arm_compute::NETransposeConvLayer::prepare ( )
override

Definition at line 218 of file NETransposeConvLayer.cpp.

219{
220 if (!_is_prepared)
221 {
222 ARM_COMPUTE_ERROR_ON(!_original_weights->is_used());
223
224 // Run weights flipping and mark original weights tensor as unused
225 _weights_flipped.allocator()->allocate();
226 _flip_weights.run();
227 _original_weights->mark_as_unused();
228
229 // Prepare convolution
230 _conv_f.prepare();
231
232 _is_prepared = true;
233 }
234}

Referenced by run().

◆ run()

void arm_compute::NETransposeConvLayer::run ( )
override

Definition at line 208 of file NETransposeConvLayer.cpp.

209{
210 prepare();
211
212 MemoryGroupResourceScope scope_mg(_memory_group);
213
214 _upsample_f.run();
215 _conv_f.run();
216}

References prepare().

Referenced by package.infer.session::inference().

◆ validate()

Status arm_compute::NETransposeConvLayer::validate ( const ITensorInfo *  input,
const ITensorInfo *  weights,
const ITensorInfo *  bias,
const ITensorInfo *  output,
const PadStrideInfo &  info,
unsigned int  invalid_right,
unsigned int  invalid_bottom 
)
static

Static function to check if given info will lead to a valid configuration of NETransposeConvLayer

Parameters
[in]inputInput tensor info. 3 lower dimensions represent a single input, and an optional 4th dimension for batch of inputs. Data types supported: F32/F16/QASYMM8/QASYMM8_SIGNED.
[in]weightsThe 4d weights info with dimensions [width, height, IFM, OFM]. Data type supported: Same as input.
[in]bias(Optional) The biases have one dimension. Data types supported: S32 for QASYMM8 and QASYMM8_SIGNED input, F32 for F32 input, F16 for F16 input.
[in]outputOutput tensor info. The output has the same number of dimensions as the input.
[in]infoContains padding and policies to be used in the deconvolution, this is decribed in PadStrideInfo.
[in]innvalid_rightThe number of zeros added to right edge of the output.
[in]invalid_bottomThe number of zeros added to bottom edge of the output.
Returns
a status

Definition at line 61 of file NETransposeConvLayer.cpp.

65{
66 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input, weights, output);
67 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::F32, DataType::F16,
68 DataType::QASYMM8, DataType::QASYMM8_SIGNED);
69 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(weights, input);
70 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(weights, input);
71 const unsigned int width_idx =
72 get_data_layout_dimension_index(weights->data_layout(), DataLayoutDimension::WIDTH);
73 const unsigned int height_idx =
74 get_data_layout_dimension_index(weights->data_layout(), DataLayoutDimension::HEIGHT);
75 ARM_COMPUTE_RETURN_ERROR_ON(weights->dimension(width_idx) != weights->dimension(height_idx));
76 ARM_COMPUTE_RETURN_ERROR_ON(weights->dimension(width_idx) < 1);
77
78 auto out_dims = transposeconv_output_dimensions(
79 input->dimension(width_idx), input->dimension(height_idx), weights->dimension(width_idx),
80 weights->dimension(height_idx), info, invalid_right, invalid_bottom);
81
82 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, weights);
83 if (bias != nullptr)
84 {
85 if (is_data_type_quantized_asymmetric(input->data_type()))
86 {
87 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(bias, 1, DataType::S32);
88 }
89 else
90 {
91 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, bias);
92 }
93 }
94
95 if (output->tensor_shape().total_size() > 0)
96 {
97 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, output);
98
99 const TensorShape output_shape = compute_transposeconv_output_shape(out_dims, *input, *weights);
100
101 ARM_COMPUTE_RETURN_ERROR_ON_MSG(output->dimension(Window::DimX) != output_shape.x(),
102 "Output's width is invalid.");
103 ARM_COMPUTE_RETURN_ERROR_ON_MSG(output->dimension(Window::DimY) != output_shape.y(),
104 "Output's height is invalid.");
105 ARM_COMPUTE_RETURN_ERROR_ON_MSG(output->dimension(Window::DimZ) != output_shape.z(),
106 "Output's depth is invalid.");
107 }
108
109 unsigned int pad_left = 0;
110 unsigned int pad_right = 0;
111 unsigned int pad_top = 0;
112 unsigned int pad_bottom = 0;
113 const TensorShape scale_out_shape =
114 compute_transposeconv_upsampled_shape(*input, *weights, info, out_dims, invalid_right,
115 invalid_bottom, pad_left, pad_right, pad_top, pad_bottom);
116 TensorInfo scale_out_info(
117 input->clone()->set_is_resizable(true).reset_padding().set_tensor_shape(scale_out_shape));
118 const PadStrideInfo conv_info(1, 1, 0, 0, 0, 0, DimensionRoundingType::CEIL);
119
120 const unsigned int batches_idx =
121 get_data_layout_dimension_index(weights->data_layout(), DataLayoutDimension::BATCHES);
122 const unsigned int channel_idx =
123 get_data_layout_dimension_index(weights->data_layout(), DataLayoutDimension::CHANNEL);
124 ARM_COMPUTE_RETURN_ERROR_ON(input->dimension(batches_idx) !=
125 scale_out_info.dimension(batches_idx));
126 ARM_COMPUTE_RETURN_ERROR_ON(input->dimension(channel_idx) !=
127 scale_out_info.dimension(channel_idx));
128
129 ARM_COMPUTE_RETURN_ON_ERROR(
130 NEConvolutionLayer::validate(&scale_out_info, weights, bias, output, conv_info, WeightsInfo()));
131
132 return Status{};
133}

References arm_compute::misc::shape_calculator::compute_transposeconv_output_shape(), arm_compute::misc::shape_calculator::compute_transposeconv_upsampled_shape(), info, output_shape, and arm_compute::transposeconv_output_dimensions().

Referenced by configure(), and ~NETransposeConvLayer().


The documentation for this class was generated from the following files: