ONNX算子分析-Resize
Resize算子在各个DL framework中定义都比较混乱,而ONNX是一种通用模型格式,值得探索一下onnx中的resize算子定义。
1. ONNX Resize参数
1.1 Attributes
antialias(抗锯齿):默认为0,当为1时linear和cubic下采样会使用抗锯齿滤波器
axes(axis的复数):表示维度的数量
coordinate_transformation_mode(坐标转换模式):
- half_pixel(默认):
- pytorch_half_pixel
- align_corners
- asymmetric
- tf_crop_and_resize
cubic_coeff_a(cubic插值中的a参数):
exclude_outside(排除外面):默认是0,如果是1那么张量外采样权重就被归一化(和为1)
extrapolation_value(外推值):默认是0,当coordinate_transformation_mode为tf_crop_and_resize时生效
keep_aspect_ratio_policy(保持长宽比的策略):
和input中的size配合使用,当scales有设置时无效
- stretch:该模式下不理会原图像的比例,直接放缩到指定的size
- not_larger:比例不变,结果不超过size
- not_smaller:比例不变,结果不小于size
mode(插值方法):
- nearest
- linear
- cubic
nearest_mode(最近邻的模式)
- round_prefer_floor:圆整,一半的时候向下取整,eg. 1.5 -> 1.0
- round_prefer_ceil:圆整,一半的时候向上取整,eg. 1.5 -> 2.0
- floor:向下取整,eg. 1.5 -> 1.0, 1.9 -> 1.0
- ceil:向上取整,eg. 1.5 -> 2.0, 1.1 -> 2.0
1.2 Inputs
- X:N维待插值张量
- roi:1维张量,仅当coordinate_transformation_mode为tf_crop_and_resize时生效
- scales:放缩的倍率,如果sizes被指定,那么scales可以为空字符串
- sizes:输出的目标尺寸
1.3 Ouputs
- Y:N维张量
2. 常用插值算法
要想了解这些插值方法,最好先在一维尺度搞明白其原理,然后拓展到高维度就顺理成章了。
2.1 nearest
主要思想是待插值像素点直接获取离其最近的像素点值。
ONNX中分为4个模式:
- round_prefer_floor:向下取整
- round_prefer_ceil:向上取整
- floor
- ceil
2.2 linear
首先了解一维的线性插值,线性公示可以表示为y=a0+a1x,那么对任意点插值仅需要2个点的坐标和对应值。
因此,二维线性插值(双线性插值bilinear)需要计算3次一维线性插值,需要4个点的坐标和对应值,如下图所示。
在计算线性插值下采样的时候,可以使用卷积加速计算。下图的2x双线性缩小,可以设置2x2卷积核,权重均为0.25,步长为2,计算量从3降到1;从这个角度看,双线性的下采样对应的就是平均池化。
列举1-3维度一维线性插值次数和需要点数,以此类推,n维线性插值需要2n-1次一维线性插值计算,需要2n个最近点的坐标和对应值。
2.3 cubic
https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=1163711
三次插值是多项式插值,下面的思路拓展到多次插值。一维的三次插值公式可以写为y=a0+a1x+a2x2+a3x3,需要4个点坐标及对应值。因此二维的三次插值(双三次插值bicubic)需要16个点坐标和对应值,含有一维插值次数为5次。
linear插值的一维插值次数可以一眼看出,但是cubic插值一维插值次数难以一眼看出,计算后得知n维cubic插值中的一维插值次数,需要点个数为4n
2.4 lanczos
https://www.detailedpedia.com/wiki-Lanczos_resampling
一维兰索斯插值的核函数L(x)如下,a一般取2或者3:
参考文献
赞赏是不耍流氓的鼓励