* [IE CLDNN] Memory allocation optimizations (#2178) * [GNA] Safety fixes (#2193) * LSTMCell test [GNA] LSTMCell fix for GNA (#2216) * [GNA] fix scale factor calculation for unfused bias after fc (2021.1) (#2195) * [GNA] fix scale factor calculation for unfused bias after fc * change check * add test * apply requested changes * cpplint fix * apply test changes * modify model for test to match ::op:: * [LPT] Copy constant with several outputs before blob update (#2197) * [LPT] Copy constant implementation * [LPT] the same Constant ops as FQ interval boundaries * [Scripts] Fixing issue with exporting path-like env when it undef (#2164) * setupvars.sh: Added logic for exporting path env in case if it not defined * setupvars: Removed duplicated colon * Kept quotes where they were * setupvars: updated copyrights * FakeQuantize + Mul fusion (#2133) * FQ+Mul fusion transform skeleton * FQ+Mul fusion transform tests prep * Basic UT for the transform * Basic implementation of the transform * Parametrized UTs for FQMul transform * Parametrization of FQ+Mul UTs * Make sure that the shapes of constants match * Check if the mul constant matches FQ data * CentOs compilation error fix * PR feedback and adjusted tests * NHWC layout of the mul constant * UT: FQ output limits 4D * Redundant CF pass removed * Rewrite the graph in a different way * Shape checking infrastructure skeleton * Handle some negative cases * Check the rt info in the fusion test * Fuse all Mul nodes detected after FQ node * Dont cast the original FQ node * Dont throw if CF fails in new output range calculation * More UTs * Accept any type of input to FQ in the transformation * Test the fusion when all FQ inputs are non-const * Fusion test when only one output limit is const * Extend error message (#2174) * some nGraph KW fixes (#2176) * Removed redundant methods * Fixed KW for linux * Fix QueryNetwork for networks with KSO (#2202) * Added a test to reproduce QueryNetwork with KSO * Fixed QueryNetwork for networks with KSO * Added additional test * Fixed output names for case with redundant ops before result (#2209) * [IE][VPU]: Workaround to support parameter Beta for layer Swish (#2207) * Workaround to full support Swish layer. It is faster than native Swish for now. * [IE][VPU]: Remove the second call of ngraph::CommonOptimizations (#2221) * Remove the second call of ngraph::CommonOptimizations in myriad plugin * Reuse code with vpu ngraph transformations * Duplicate PR 2167 for release branch: GatherTree description was extended and outdated link fixed (#2235) * add more alrifications to description * move clarification to comment * pseudo code become more accurate * review changes * Add exposing function signatures via Cython (#2244) * [DOC] Reshape feature (#2194) * [IE][VPU][OpenCL] 2021.1 release compiler (#2189) * Statically analyzed issues. (#2261) * [IE][VPU]: Fix K propagation through Reshape (2021.1) (#2180) * Fix K propagation through Reshape * Add test cases * Revert "[IE TESTS] dynavic batch for mvn layer (#1010)" (#2256) This reverts commit2e3378c50f. * Fixed KW warning and review issues (#2262) * [IE][VPU]: update firmware 1381 (#2236) * Reverting devicePriorities to be vector and respect the order, as opposed to the incorrect (recent?) refactoring that introduced the unordered_map that effectively ignores the priorities (#2251) * update OpenCV version to 4.5.0 (#2260) * Add VPUX configuration to compile_tool (#2248) * [IE][TESTS] Fix compareRawBuffers and compareBlobData methods (#2246) Use `<=` comparison instead of `<` with thresholds. This allows to use `0` threshold for bit-exact comparison. * [IE][VPU]: KW fixes (#2186) * Some KW fixes * Fix printTo in vpu ngraph transformations * Fix for static PartialShape detection algorithm (#2177) * Fixes for Interpolate-4. (#2281) * Update get_ov_update_message.py (#2286) * Clone a specific tag for pybind11 (#2296) * [Scripts] Fix setting PYTHONPATH logic (#2305) * setupvars.sh: Added logic for exporting path env in case if it not defined * setupvars: Removed duplicated colon * install_openvino_dependencies: Updated copyrights setupvars.bat: Updated notification about incorrect Python version. Removed checking ICC2019 setupvars.sh: Removed logic with choosing higher version of installed Python. Added dynamic detecting python3 major and minor version for setting path. Add checking minimum required Python version(now 3.6) * Added python3-gi package and fixed libglib2.0-0 package location. (#2294) * [IE TESTS] CoreThreading_LoadNetwork tests were disabled for GPU plugin (#2245) (#2283) * setupvars: Updated notifications, fixed calling python in Windows case (#2318) * Updated operations specification documents (2021.1) (#2268) * Updated documentation structure and remove incorrect added files for Acosh-1, Asinh-1 and Atanh-1 * Fixed broken links * Fixed c samples build (#2278) (#2304) * Fixed c samples build fixed CVS-38816 - Failure to build samples in C * Fixed issue with gflags * Revert "[IE][VPU]: Fix K propagation through Reshape (2021.1) (#2180)" (#2322) This reverts commitd604a03ac0. * Added ONNX Resize-11 and ONNX Resize-13 to supported frameworks layers list. (#2325) * Implement `run_executable.py` to run `TimeTests` several times (#2125) (#2188) CI passed * install_NEO_OCL_driver: Updated exit codes, messages. Updated way to remove old driver on Ubuntu (#2333) * Bump cmake version to 3.13 (#2339) * install_NEO_OCL_driver: Added checking of installed packages before trying to remove them. Added quotes for echo. (#2350) * convert to doxygen comments * add doxygen doc build configurations (#2191) Co-authored-by: Nikolay Tyukaev <ntyukaev_lo@jenkins.inn.intel.com> * [DOCS] Added an evaluate method for custom operation (#2272) * Added an evaluate method for custom operation * Fixed comments * Downgrade cmake for samples (#2372) * Downgrade cmake for samples Downgraded cmake version to default version for Ubuntu 18.04 * Updated supported python version The minimal python version in 2021.1 is 3.5 * Added notes about cmake requirements for samples and demo * Install dependency refactoring. (#2381) * Updated Transformation development doc (#2370) * Delete xfail for resolved known issue (#2385) * Fix layout links for dl streamer and c api (#2375) * fix layouts * change the dl-streamer link Co-authored-by: Nikolay Tyukaev <ntyukaev_lo@jenkins.inn.intel.com> * Added link options for cross-compilation (#2397) * Added new GSG for macOS, made minor changes in Windows GSG (#2070) (#2405) * Added new GSG for macOS, made minor changes in Windows GSG * Update get_started_macos.md Co-authored-by: Anastasiya Ageeva <anastasiya.ageeva@intel.com> * Fixed docs build on Windows (#2383) * layouts and code comments * Replace absolute links to docs.openvinotoolkit.org by relative ones (#2439) * Replaced direct links to docs.openvinotoolkit.org with relative links * Replaced direct links to docs.openvinotoolkit.org with relative links. Added GSGs for Win and macOS * Minor fixes in GSGs * Replaced direct links to docs.openvinotoolkit.org with relative links * Removed links to OpenVINO markdown files that contain anchor - they don't work in the current implementation of the doc process * Fixed Notes * Removed links to OpenVINO markdown files that contain anchor - they don't work in the current implementation of the doc process * fixed link to installing-openvino-linux.md * Update the menu to align with POT doc headers (#2433) * Update the menu to align with POT doc headers It changes the menu to align with Post-training Optimization Toolkit documentation titles. * Corrected one title Run Examples => How to Run Examples * Added closing braсket (#2466) Fixed syntax error (b4b03b1) * Remove the deprecation notice (#2314) * Removed deprecation notice * Removed the note from other files * [DOCS] Update Installation Guide - GPU steps (#2308) * Initial commit * fixing lists * Update installing-openvino-linux.md * Get rid of the note * Added the scrrenshot * Update installing-openvino-linux.md * fixes * separate layout * [Docs] Update MO What's new description (#2481) * Azure CI: Add separated pipelines for Windows, Linux, Mac * Feature/azaytsev/benchmarks 2021 1 (#2501) * Initial changes for 2021.1 * Inserted Graphtool scripts, updated configurations info * Updated FAQ and minor changes to performance_benchmarks.md * Updated for 2021.1 * Updated * incorporated review comments * incorporated review comments for FAQ * fixed link * Update build-instruction.md for MacOsX (#2457) * Update build-instruction.md for MacOsX * Removed call of install_dependencies.sh from the steps * Changed layouts * Feature/azaytsev/cvs-38240 (#2469) * Updated for 2020 version, replaced Ubuntu 16.04 with Ubuntu 20.04 * Updated the release package numbers * Removed FPGA from the documentation * Updated according to the comments in the ticket CVS-37827 (#2448) * Updated according to CVS-38225 * some changes * Update docs for speech libs and demos (#2518) * Made changes to benchmarks according to review comments * Remove `--collect_results_only` (#2523) * Remove `--collect_results_only` from MemCheckTests * Remove CLI keys from README * Added logo info to the Legal_Information, updated Ubuntu, CentOS supported versions * Updated supported Intel® Core™ processors list * Fixed table formatting * [Jenkinsfile] Bump infra (#2546) * [GNA] Documentation updates for 2021.1 (#2460) * [GNA] Documentation updates for 2021.1 * Take Mike's comments into account * More fixes according to review * Fix processor generation names * update api layouts * Added new index page with overview * Changed CMake and Python versions * Fixed links * some layout changes * some layout changes * nGraph Python API tutorial (#2500) * nGraph Python API tutorial * Tweaks * Code review comments * Code review comments * some layout changes * COnverted svg images to png * layouts * update layout * Added a label for nGraph_Python_API.md * fixed links * Fixed image * First draft of nGraph documentation (#2271) * First draft of nGraph documentation * updated according to review comments * Updated * Reviewed the nGraph Transformation section, added missing images * Update nGraph_dg.md * Delete python_api.md Removed since there is already the nGraph_Python_API.md document with a comprehensive overview. Co-authored-by: Andrey Zaytsev <andrey.zaytsev@intel.com> Co-authored-by: CCR\avladimi <anastasiya.ageeva@intel.com> * Feature/azaytsev/docs 2021 1 (#2560) * Removed FPGA from the documentation * Updated according to CVS-38225 * Added logo info to the Legal_Information, updated Ubuntu, CentOS supported versions * Updated supported Intel® Core™ processors list * Added new index page with overview * Changed CMake and Python versions * Fixed links * COnverted svg images to png * Added a label for nGraph_Python_API.md * fixed links * Fixed image * Update SW requirements in build instructions and change latest release to 2021.1 (#2565) * removed links to ../IE_DG/Introduction.md * Removed links to tools overview page as removed * some changes * Remove link to Integrate_your_kernels_into_IE.md * remove openvino_docs_IE_DG_Graph_debug_capabilities from layout as it was removed * Fixed links to images (#2569) * update layouts * Added deprecation note for PassConfig class (#2593) * Post-release fixes and installation path changes * Added pip install documentation (#2465) * Added pip install documentation * Change references * tiny fixes of links * Update installing-openvino-pip.md Co-authored-by: Alina Alborova <alina.alborova@intel.com> * Update OpenVino ONNX CI check (#2599) * Update OpenVino ONNX CI * Change parallel execution to single * Enlarge timeout * Remove timeout * Add timeout to test execution * Added PIP installation and Build from Source to the layout * Fixed formatting issue, removed broken link * Renamed section EXAMPLES to RESOURCES according to review comments * add mo faq navigation by url param * Skip hanging test case of OpenVino ONNX CI (#2608) * Update OpenVino ONNX CI * Change parallel execution to single * Enlarge timeout * Remove timeout * Add timeout to test execution * Skip hanging test * Add description to skip issue * Removed DLDT description * Replaced wrong links * MInor fix for path to the cpp samples * fixes * Update ops.py * Fix style * Improve pip installation guide (#2644) * Improve pip installation guide * Updated after comments * Feature/ntyukaev/separate layout (#2629) * convert to doxygen comments * layouts and code comments * separate layout * Changed layouts * Removed FPGA from the documentation * Updated according to CVS-38225 * some changes * Made changes to benchmarks according to review comments * Added logo info to the Legal_Information, updated Ubuntu, CentOS supported versions * Updated supported Intel® Core™ processors list * Fixed table formatting * update api layouts * Added new index page with overview * Changed CMake and Python versions * Fixed links * some layout changes * some layout changes * some layout changes * COnverted svg images to png * layouts * update layout * Added a label for nGraph_Python_API.md * fixed links * Fixed image * removed links to ../IE_DG/Introduction.md * Removed links to tools overview page as removed * some changes * Remove link to Integrate_your_kernels_into_IE.md * remove openvino_docs_IE_DG_Graph_debug_capabilities from layout as it was removed * update layouts * Post-release fixes and installation path changes * Added PIP installation and Build from Source to the layout * Fixed formatting issue, removed broken link * Renamed section EXAMPLES to RESOURCES according to review comments * add mo faq navigation by url param * Removed DLDT description * Replaced wrong links * MInor fix for path to the cpp samples * fixes * Update ops.py * Fix style Co-authored-by: Nikolay Tyukaev <ntyukaev_lo@jenkins.inn.intel.com> Co-authored-by: Tyukaev <nikolay.tyukaev@intel.com> Co-authored-by: aalborov <alina.alborova@intel.com> Co-authored-by: Rafal Blaczkowski <rafal.blaczkowski@intel.com> Co-authored-by: Alexander Zhogov <alexander.zhogov@intel.com> * Fixed CVS-35316 (#2072) (#2670) Co-authored-by: Anastasiya Ageeva <anastasiya.ageeva@intel.com> * [install_dependencies.sh] install latest cmake if current version is lower 3.13 (#2695) (#2701) * [install_dependencies.sh] install latest cmake if current version is lower 3.13 * add shellcheck for Ubuntu * install python 2.7 for Ubuntu * Removed redundant file * Exclude files that we didn't changed from merging Co-authored-by: Sergey Shlyapnikov <sergey.shlyapnikov@intel.com> Co-authored-by: Denis Orlov <denis.orlov@intel.com> Co-authored-by: Kamil Magierski <kamil.magierski@intel.com> Co-authored-by: Anna Alberska <anna.alberska@intel.com> Co-authored-by: Edward Shogulin <edward.shogulin@intel.com> Co-authored-by: Artyom Anokhov <artyom.anokhov@intel.com> Co-authored-by: Tomasz Dołbniak <tomasz.dolbniak@intel.com> Co-authored-by: Ilya Churaev <ilya.churaev@intel.com> Co-authored-by: Roman Vyunov (Intel) <roman.vyunov@intel.com> Co-authored-by: Maksim Doronin <maksim.doronin@intel.com> Co-authored-by: Svetlana Dolinina <svetlana.a.dolinina@intel.com> Co-authored-by: Evgeny Talanin <evgeny.talanin@intel.com> Co-authored-by: Evgenya Stepyreva <evgenya.stepyreva@intel.com> Co-authored-by: Maxim Kurin <maxim.kurin@intel.com> Co-authored-by: Nikolay Shchegolev <nikolay.shchegolev@intel.com> Co-authored-by: Andrew Bakalin <andrew.bakalin@intel.com> Co-authored-by: Gorokhov Dmitriy <dmitry.gorokhov@intel.com> Co-authored-by: Evgeny Latkin <evgeny.latkin@intel.com> Co-authored-by: Maxim Shevtsov <maxim.y.shevtsov@intel.com> Co-authored-by: Alexey Suhov <alexey.suhov@intel.com> Co-authored-by: Alexander Novak <sasha-novak@yandex.ru> Co-authored-by: Vladislav Vinogradov <vlad.vinogradov@intel.com> Co-authored-by: Vladislav Volkov <vladislav.volkov@intel.com> Co-authored-by: Vladimir Gavrilov <vladimir.gavrilov@intel.com> Co-authored-by: Zoe Cayetano <zoe.cayetano@intel.com> Co-authored-by: Dmitrii Denisov <dmitrii.denisov@intel.com> Co-authored-by: Irina Efode <irina.efode@intel.com> Co-authored-by: Evgeny Lazarev <evgeny.lazarev@intel.com> Co-authored-by: Mikhail Ryzhov <mikhail.ryzhov@intel.com> Co-authored-by: Vitaliy Urusovskij <vitaliy.urusovskij@intel.com> Co-authored-by: Nikolay Tyukaev <ntyukaev_lo@jenkins.inn.intel.com> Co-authored-by: Nikolay Tyukaev <nikolay.tyukaev@intel.com> Co-authored-by: Gleb Kazantaev <gleb.kazantaev@intel.com> Co-authored-by: Rafal Blaczkowski <rafal.blaczkowski@intel.com> Co-authored-by: Ilya Lavrenov <ilya.lavrenov@intel.com> Co-authored-by: Anastasiya Ageeva <anastasiya.ageeva@intel.com> Co-authored-by: Maksim Proshin <mvproshin@gmail.com> Co-authored-by: Alina Alborova <alina.alborova@intel.com> Co-authored-by: Maxim Vafin <maxim.vafin@intel.com> Co-authored-by: azhogov <alexander.zhogov@intel.com> Co-authored-by: Alina Kladieva <alina.kladieva@intel.com> Co-authored-by: Michał Karzyński <4430709+postrational@users.noreply.github.com> Co-authored-by: Anton Romanov <anton.romanov@intel.com>
20 KiB
Interpolate
Versioned name: Interpolate-4
Category: Image processing
Short description: Interpolate layer performs interpolation of independent slices in input tensor by specified dimensions and attributes.
Attributes
-
mode
- Description: specifies type of interpolation
- Range of values: one of
nearest,linear,linear_onnx,cubic - Type: string
- Default value: none
- Required: yes
-
shape_calculation_mode
- Description: specifies which input,
sizesorscales, is used to calculate an output shape. - Range of values: name of a shape calculation mode in string format:
sizes- an output shape is calculated asoutput_shape[axes[i]] = sizes[i]for alli in range(0, len(axes))andoutput_shape[j] = input_shape[j] + pads_begin[j] + pads_end[j]forj not in axes,j in range(0, rank(data)).scales- an output shape is calculated asoutput_shape[axes[i]] = floor(scales[i] * (input_shape[axes[i]] + pads_begin[axes[i]] + pads_end[axes[i]]))for alli in range(0, len(axes))andoutput_shape[j] = input_shape[j] + pads_begin[j] + pads_end[j]forj not in axes,j in range(0, rank(data))
- Type: string
- Default value: none
- Required: yes
- Description: specifies which input,
-
coordinate_transformation_mode
- Description: specifies how to transform the coordinate in the resized tensor to the coordinate in the original tensor
- Range of values: name of the transformation mode in string format (here
scale[x]isoutput_shape[x] / input_shape[x]andx_resizedis a coordinate in axisx, for any axisxfrom the inputaxes):half_pixel- the coordinate in the original tensor axisxis calculated as((x_resized + 0.5) / scale[x]) - 0.5.pytorch_half_pixel- the coordinate in the original tensor axisxis calculated by(x_resized + 0.5) / scale[x] - 0.5 if output_shape[x] > 1 else 0.0.asymmetric- the coordinate in the original tensor axisxis calculated according to the formulax_resized / scale[x].tf_half_pixel_for_nn- the coordinate in the original tensor axisxis(x_resized + 0.5) / scale[x].align_corners- the coordinate in the original tensor axisxis calculated as0 if output_shape[x] == 1 else x_resized * (input_shape[x] - 1) / (output_shape[x] - 1).
- Type: string
- Default value:
half_pixel - Required: no
-
nearest_mode
- Description: specifies round mode when
mode == nearestand is used only whenmode == nearest. - Range of values: name of the round mode in string format:
round_prefer_floor- this mode is known as round half down.round_prefer_ceil- it is round half up mode.floor- this mode computes the largest integer value not greater than rounded value.ceil- this mode computes the smallest integer value not less than rounded value.simple- this mode behaves asceilmode whenInterpolateis downsample, and as dropping the fractional part otherwise.
- Type: string
- Default value:
round_prefer_floor - Required: no
- Description: specifies round mode when
-
antialias
- Description: antialias is a flag that specifies whether to perform anti-aliasing.
- Range of values:
- False - do not perform anti-aliasing
- True - perform anti-aliasing
- Type: boolean
- Default value: False
- Required: no
-
pads_begin
- Description: pads_begin specifies the number of pixels to add to the beginning of the image being interpolated. This addition of pixels is done before interpolation calculation.
- Range of values: list of non-negative integer numbers
- Type:
int[] - Default value:
[0] - Required: no
-
pads_end
- Description: pads_end specifies the number of pixels to add to the end of the image being interpolated. This addition of pixels is done before interpolation calculation.
- Range of values: list of non-negative integer numbers
- Type:
int[] - Default value:
[0] - Required: no
-
cube_coeff
-
Description: cube_coeff specifies the parameter a for cubic interpolation (see, e.g. article). cube_coeff is used only when
mode == cubic.- Range of values: floating point number
- Type: any of supported floating point type
- Default value:
-0.75 - Required: no
Inputs
-
1:
data- Input tensor with data for interpolation. Type of elements is any supported floating point type orint8type. Required. -
2:
sizes- 1D tensor describing output shape for spatial axes. Number of elements matches the number of indices inaxesinput, the order matches as well. Required. -
3:
scales- 1D tensor describing scales for spatial axes. Type of elements is any supported floating point type. Number and order of elements match the number and order of indices inaxesinput. Required. -
4:
axes- 1D tensor specifying dimension indices where interpolation is applied, andaxesis any unordered list of indices of different dimensions of input tensor, e.g.[0, 4],[4, 0],[4, 2, 1],[1, 2, 3]. These indices should be non-negative integers from0torank(data) - 1inclusively. Other dimensions do not change. The order of elements inaxesattribute matters, and mapped directly to elements in the 2nd inputsizes. Optional with default value[0,...,rank(data) - 1].
Outputs
- 1: Resulting interpolated tensor with elements of the same type as input
datatensor. The shape of the output matches inputdatashape except spatial dimensions mentioned inaxesattribute. For other dimensions shape matches sizes fromsizesin order specified inaxes.
Detailed description Calculations are performed according to the following rules.
import math
import numpy as np
from enum import Enum, unique
class GetNearestPixel:
def __init__(self, mode: str):
self.func = {
'round_prefer_floor': GetNearestPixel.prefer_floor_func,
'round_prefer_ceil': GetNearestPixel.prefer_ceil_func,
'floor': GetNearestPixel.floor_func,
'ceil': GetNearestPixel.ceil_func,
'simple': GetNearestPixel.simple_func
}[mode]
def __call__(self, x_original, is_downsample):
return self.func(x_original, is_downsample)
@staticmethod
def prefer_floor_func(x_original, is_downsample):
if x_original == int(x_original) + 0.5:
return int(math.floor(x_original))
else:
return int(round(x_original))
@staticmethod
def prefer_ceil_func(x_original, is_downsample):
return int(round(x_original))
@staticmethod
def floor_func(x_original, is_downsample):
return int(math.floor(x_original))
@staticmethod
def ceil_func(x_original, is_downsample):
return int(math.ceil(x_original))
@staticmethod
def simple_func(x_original, is_downsample):
if is_downsample:
return int(math.ceil(x_original))
else:
return int(x_original)
class GetOriginalCoordinate:
def __init__(self, mode: str):
self.func = {
'half_pixel': GetOriginalCoordinate.half_pixel_func,
'pytorch_half_pixel': GetOriginalCoordinate.pytorch_half_pixel_func,
'asymmetric': GetOriginalCoordinate.asymmetric_func,
'tf_half_pixel_for_nn': GetOriginalCoordinate.tf_half_pixel_for_nn_func,
'align_corners': GetOriginalCoordinate.align_corners_func
}[mode]
def __call__(self, x_resized, x_scale, length_resized, length_original):
return self.func(x_resized, x_scale, length_resized, length_original)
@staticmethod
def half_pixel_func(x_resized, x_scale, length_resized, length_original):
return ((x_resized + 0.5) / x_scale) - 0.5
@staticmethod
def pytorch_half_pixel_func(x_resized, x_scale, length_resized, length_original):
return (x_resized + 0.5) / x_scale - 0.5 if length_resized > 1 else 0.0
@staticmethod
def asymmetric_func(x_resized, x_scale, length_resized, length_original):
return x_resized / x_scale
@staticmethod
def tf_half_pixel_for_nn_func(x_resized, x_scale, length_resized, length_original):
return (x_resized + 0.5) / x_scale
@staticmethod
def align_corners_func(x_resized, x_scale, length_resized, length_original):
return 0 if length_resized == 1 else x_resized * (length_original - 1) / (length_resized - 1)
def get_cubic_coeff(s, a):
abs_s = abs(s)
coeff = np.zeros(4)
coeff[0] = a * (abs_s - 1.0) * (abs_s - 1.0) * abs_s
coeff[1] = ((a + 2.0) * abs_s - (a + 3.0)) * abs_s * abs_s + 1.0
coeff[2] = (((-a -2.0) * abs_s+ (2.0 * a + 3.0)) * abs_s - a) * abs_s
coeff[3] = - a * abs_s * abs_s * (abs_s - 1.0)
return coeff
def triangle_coeffs(dz):
return np.maximum(0.0, 1.0 - np.abs(dz))
@unique
class ShapeCalculationMode(Enum):
SIZES = 0
SCALES = 1
class InterpolateCalculation:
def __init__(self, attrs: dict):
self.mode = attrs['mode']
self.func = {
'nearest': self.nearest_interpolation,
'linear': self.linear_interpolation,
'cubic': self.cubic_interpolation,
'linear_onnx': self.onnx_linear_interpolation
}[self.mode]
self.attrs = attrs
self.pads_begin = attrs.get('pads_begin', [0])
self.pads_end = attrs.get('pads_end', [0])
self.coordinate_transformation_mode = attrs.get('coordinate_transformation_mode', 'half_pixel')
self.nearest_mode = attrs.get('nearest_mode', 'round_prefer_floor')
self.cube_coeff = attrs.get('cube_coeff', -0.75)
self.antialias = attrs.get('antialias', False)
self.shape_calculation_mode = {
'sizes': ShapeCalculationMode.SIZES,
'scales': ShapeCalculationMode.SCALES
}[attrs['shape_calculation_mode']]
self.get_original_coordinate = self.get_coordinate_transformation_mode()
self.get_nearest_pixel = GetNearestPixel(self.nearest_mode)
def get_coordinate_transformation_mode(self):
return GetOriginalCoordinate(self.coordinate_transformation_mode)
def shape_infer(self, input_data, sizes, scales):
result = input_data.shape + self.pads_begin + self.pads_end
if self.shape_calculation_mode == ShapeCalculationMode.SIZES:
for i, axis in enumerate(self.axes):
result[axis] = sizes[i]
else:
for i, axis in enumerate(self.axes):
result[axis] = math.floor(scales[i] * result[axis])
return result
@staticmethod
def correct_pad(pad, rank):
pad_len = len(pad)
if pad_len < rank:
return np.pad(pad, (0, rank - pad_len), 'constant').astype(np.int64)
elif pad_len > rank:
return np.array(pad[: rank - 1]).astype(np.int64)
else:
return np.array(pad, dtype=np.int64)
def __call__(self, input_data, sizes, scales, axes):
rank = input_data.ndim
self.pads_begin = InterpolateCalculation.correct_pad(self.pads_begin, rank)
self.pads_end = InterpolateCalculation.correct_pad(self.pads_end, rank)
self.pads = list(zip(self.pads_begin, self.pads_end))
self.axes = np.array(axes).astype(np.int64)
self.output_shape = self.shape_infer(input_data, sizes, scales)
padded_data = np.pad(input_data, self.pads, 'constant')
if self.shape_calculation_mode == ShapeCalculationMode.SIZES:
num_of_axes = len(self.axes)
self.scales = np.zeros(num_of_axes)
for i, axis in enumerate(axes):
self.scales[i] = self.output_shape[axis] / padded_data.shape[axis]
else:
self.scales = scales
if self.mode == 'nearest':
self.all_scales = np.ones(rank).astype(np.float)
for i, axis in enumerate(self.axes):
self.all_scales[axis] = self.scales[i]
self.input_shape = padded_data.shape
return self.func(padded_data)
def clip_coord(self, coord, axis):
return max(0, min(coord, self.input_shape[axis] - 1))
def cubic_interpolation(self, input_data):
rank = len(self.input_shape)
result = np.zeros(self.output_shape)
num_of_axes = len(self.axes)
indices = [ind for ind in np.ndindex(tuple(4 for _ in range(num_of_axes)))]
for coordinates in np.ndindex(tuple(self.output_shape)):
input_coords = np.array(coordinates, dtype=np.int64)
cubic_coeffs = np.zeros((rank, 4))
for i, axis in enumerate(self.axes):
in_coord = self.get_original_coordinate(coordinates[axis], self.scales[i], self.output_shape[axis], self.input_shape[axis])
in_coord_int = math.floor(in_coord)
input_coords[axis] = in_coord_int
cubic_coeffs[axis] = get_cubic_coeff(in_coord - in_coord_int, self.cube_coeff)
summa = 0.0
for index in indices:
coords_for_sum = input_coords.copy()
coeffs_prod = 1.0
for i, axis in enumerate(self.axes):
coords_for_sum[axis] = self.clip_coord(input_coords[axis] + index[i] - 1, axis)
for i, axis in enumerate(self.axes):
coeffs_prod = coeffs_prod * cubic_coeffs[axis][index[i]]
summa += coeffs_prod * input_data[tuple(coords_for_sum)]
result[coordinates] = summa
return result
def linear_interpolation(self, input_data):
result = np.zeros(self.output_shape)
num_of_axes = len(self.axes)
is_downsample = False
for scale in self.scales:
is_downsample = is_downsample or (scale < 1)
antialias = is_downsample and self.antialias
a = np.zeros(num_of_axes)
for i, _ in enumerate(self.axes):
a[i] = self.scales[i] if antialias else 1.0
prod_of_a = np.prod(a)
r = np.zeros(num_of_axes).astype(np.int64)
for i, _ in enumerate(self.axes):
r[i] = 2 if self.scales[i] > 1.0 else int(math.ceil(2.0/a[i]))
indices = [tuple(np.array(ind).astype(np.int64) - r) for ind in np.ndindex(tuple(2 * r + 1))]
for coordinates in np.ndindex(tuple(self.output_shape)):
icoords = np.array(coordinates).astype(np.float64)
icoords_r = np.array(coordinates).astype(np.float64)
for i, axis in enumerate(self.axes):
in_coord = self.get_original_coordinate(coordinates[axis], self.scales[i], self.output_shape[axis], self.input_shape[axis])
icoords[axis] = in_coord
icoords_r[axis] = round(in_coord)
summa = 0.0
wsum = 0.0
for index in indices:
inner_coords = np.array(coordinates)
for i, axis in enumerate(self.axes):
inner_coords[axis] = index[i] + icoords_r[axis]
conditions = [inner_coords[axis] >= 0 and inner_coords[axis] < self.input_shape[axis] for axis in self.axes]
if not all(conditions):
continue
dz = np.zeros(num_of_axes)
for i, axis in enumerate(self.axes):
dz[i] = icoords[axis] - inner_coords[axis]
w = prod_of_a * np.prod(triangle_coeffs(a * dz))
wsum += w
summa += w * input_data[tuple(inner_coords)]
if wsum == 0:
result[coordinates] = 0.0
else:
result[coordinates] = summa / wsum
return result
def onnx_linear_interpolation(self, input_data):
rank = len(self.input_shape)
assert rank in [2, 4], "mode 'linear_onnx' supports only 2D or 4D tensors"
assert set(self.axes) == {2, 3} or set(self.axes) == {0, 1}, \
"mode 'linear_onnx' supports only case when axes = {2, 3} or axes = {0, 1}"
result = np.zeros(self.output_shape)
if rank == 2:
reshaped_data = np.reshape(input_data, (1, 1, self.input_shape[0], self.input_shape[1]))
result = np.reshape(result, (1, 1, self.output_shape[0], self.output_shape[1]))
else:
reshaped_data = input_data
input_shape = np.array(reshaped_data.shape).astype(np.int64)
output_shape = np.array(result.shape).astype(np.int64)
output_height = output_shape[2]
output_width = output_shape[3]
input_height = input_shape[2]
input_width = input_shape[3]
height_scale = self.scales[0]
width_scale = self.scales[1]
batch_size = input_shape[0]
num_channels = input_shape[1]
y_original = np.zeros(output_height).astype(np.float)
x_original = np.zeros(output_width).astype(np.float)
in_y1 = np.zeros(output_height).astype(np.int64)
in_y2 = np.zeros(output_height).astype(np.int64)
in_x1 = np.zeros(output_width).astype(np.int64)
in_x2 = np.zeros(output_width).astype(np.int64)
dy1 = np.zeros(output_height).astype(np.float)
dy2 = np.zeros(output_height).astype(np.float)
dx1 = np.zeros(output_width).astype(np.float)
dx2 = np.zeros(output_width).astype(np.float)
for y in range(0, output_height):
in_y = self.get_original_coordinate(y, height_scale, output_height, input_height)
y_original[y] = in_y
in_y = max(0, min(in_y, input_height - 1))
in_y1[y] = max(0, min(int(in_y), input_height - 1))
in_y2[y] = min(in_y1[y] + 1, input_height - 1)
dy1[y] = abs(in_y - in_y1[y])
dy2[y] = abs(in_y - in_y2[y])
if in_y1[y] == in_y2[y]:
dy1[y] = 0.5
dy2[y] = 0.5
for x in range(0, output_width):
in_x = self.get_original_coordinate(x, width_scale, output_width, input_width);
x_original[x] = in_x
in_x = max(0.0, min(in_x, input_width - 1));
in_x1[x] = min(in_x, input_width - 1);
in_x2[x] = min(in_x1[x] + 1, input_width - 1);
dx1[x] = abs(in_x - in_x1[x]);
dx2[x] = abs(in_x - in_x2[x]);
if in_x1[x] == in_x2[x]:
dx1[x] = 0.5
dx2[x] = 0.5
for n in range(0, batch_size):
for c in range(0, num_channels):
for y in range(0, output_height):
for x in range(0, output_width):
x11 = reshaped_data[n, c, in_y1[y], in_x1[x]]
x21 = reshaped_data[n, c, in_y1[y], in_x2[x]]
x12 = reshaped_data[n, c, in_y2[y], in_x1[x]]
x22 = reshaped_data[n, c, in_y2[y], in_x2[x]]
temp = dx2[x] * dy2[y] * x11 + dx1[x] * dy2[y] * x21 + dx2[x] * dy1[y] * x12 + dx1[x] * dy1[y] * x22
result[n, c, y, x] = temp
return np.reshape(result, self.output_shape)
def nearest_interpolation(self, input_data):
result = np.zeros(self.output_shape)
num_of_axes = len(self.axes)
for coordinates in np.ndindex(tuple(self.output_shape)):
input_coords = np.array(coordinates, dtype=np.int64)
for axis, scale in enumerate(self.all_scales):
in_coord = self.get_original_coordinate(coordinates[axis], scale, self.output_shape[axis], self.input_shape[axis])
nearest_pixel = self.get_nearest_pixel(in_coord, scale < 1)
input_coords[axis] = max(0, min(nearest_pixel, self.input_shape[axis] - 1))
result[coordinates] = input_data[tuple(input_coords)]
return result
Example
<layer ... type="Interpolate" ...>
<data shape_calculation_mode="scales" pads_begin="0" pads_end="0" mode="linear"/>
<input>
<port id="0">
<dim>1</dim>
<dim>2</dim>
<dim>48</dim>
<dim>80</dim>
</port>
<port id="1">
<dim>2</dim> <!--The values in this input are [24, 160] -->
</port>
<port id="2">
<dim>2</dim> <!--The values in this input are [0.5, 2.0] -->
</port>
<port id="3">
<dim>2</dim> <!--The values in this input are [2, 3] (axes). -->
</port>
</input>
<output>
<port id="0" precision="FP32">
<dim>1</dim>
<dim>2</dim>
<dim>24</dim>
<dim>160</dim>
</port>
</output>
</layer>