本文正在参加「金石计划 . 分割6万现金大奖」

欢迎重视我的公众号 [极智视界],获取我的更多笔记共享

  大家好,我是极智视界,本文介绍一下 谈谈昇腾 CANN AIPP

  昇腾 CANN 的全称是 Compute Architecture for Neural Networks,是昇腾针对 AI 场景推出的异构核算架构。前几天写了一篇《极智AI | 昇腾 CANN ATC 模型转化》,里面介绍了昇腾 CANN ATC 模型转化东西。而这儿的 AIPP 是在 ATC 东西里的一个高级功用,类似于昇腾的 DVPP (数字视觉预处理)。AIPP(Artificial Intelligence Pre-Processing)智能图画预处理,用于在 AI Core 上完结图画预处理,包括改动图画尺寸、色域转化(转化图画格局)、减均值/乘系数(改动图画像素),数据处理之后再进行真正的模型推理。 AIPP 与DVPP比较,因为 DVPP 各组件依据处理速度和处理占有量的考虑,对输出有特别的束缚,如输出图片需求长宽对齐,且其输出格局通常为 YUV420SP 等格局。这样的设定虽在视频剖析的场景下有非常宽广的输入,但深度学习模型的输入通常为 RGB 或 BRG,且输入图片尺寸各异,因此 ATC 东西流程中供给了 AIPP 功用模块。

  AIPP 是一个非常实用高性能的模块,非常实用 体现在你能够把很多自身游离于模型之外的前处理做到模型里面,而且这些前处理都是非常常见的,如色域转化、归一化、图画缩放、通道转化等;高性能 体现在 AIPP 是直接调用 AI Core 进行核算的,所以性能非常强悍。总结来说,AIPP 主要具有如下的才干:

极智AI | 谈谈昇腾 CANN AIPP

  来看 ATC 是怎样运用 AIPP,一般能够通过 --insert_op_conf 来指定 AIPP 装备文件,将 AIPP 算子刺进模型。这儿以 caffe 结构的 resnet50 模型刺进 AIPP 算子为例进行阐明:

atc --model=/path/resnet50.prototxt \
  --weight=/path/resnet50.caffemodel \
  --framework=0 \
  --insert_op_conf=/path/insert_op.cfg  \
  --output=/path/out/caffe_resnet50 \
  --soc_version=${soc_version}

  对上面的参数进行阐明:

  • –model & –weight:原始模型文件;
  • –framework:0 表明输入的模型是 caffe 结构的;
  • –insert_op_conf:输入 AIPP 装备文件 (模版如下);
  • –ouput:生成的 om 模型文件;
  • –soc_version:昇腾卡版本;

  下面是 AIPP 的装备文件模版 (包含了 AIPP 各个功用模块的具体阐明):

# AIPP的装备以aipp_op开端,标识这是一个AIPP算子的装备,aipp_op支撑装备多个
aipp_op {

#========================= 全局设置(start) =================================
# aipp_mode指定了AIPP的模式,必须装备
# 类型:enum
# 取值规模:dynamic/static,dynamic 表明动态AIPP,static 表明静态AIPP
aipp_mode: 

# related_input_rank参数为可选,标识对模型的第几个输入做AIPP处理,从0开端,默以为0。例如模型有两个输入,需求对第2个输入做AIPP,则装备related_input_rank为1。
# 类型: 整型
# 装备规模 >= 0
related_input_rank: 0

# related_input_name参数为可选,标识对模型的第几个输入做AIPP处理,此处需求填写为模型输入的name(input对应的值)或者模型首层节点的输出(top参数对应的取值)。该参数只适用于Caffe网络模型,且不能与related_input_rank参数同时运用。
# 例如模型有两个输入,且输入name分别为data、im_info,需求对第二个输入做AIPP,则装备related_input_name为im_info。
# 类型:string
# 装备规模:无
related_input_name: ""

#========================= 全局设置(end) =====================================

#========================= 动态AIPP需设置,静态AIPP无需设置(start) ====================
# 输入图画最大的size,动态AIPP必须装备(假如为动态batch场景,N为最大档位数的取值)
# 类型:int
max_src_image_size: 0
# 若输入图画格局为YUV400_U8,则max_src_image_size>=N * src_image_size_w * src_image_size_h * 1。
# 若输入图画格局为YUV420SP_U8,则max_src_image_size>=N * src_image_size_w * src_image_size_h * 1.5。
# 若输入图画格局为XRGB8888_U8,则max_src_image_size>=N * src_image_size_w * src_image_size_h * 4。
# 若输入图画格局为RGB888_U8,则max_src_image_size>=N * src_image_size_w * src_image_size_h * 3。

# 是否支撑旋转,保存字段,暂不支撑该功用
# 类型:bool
# 取值规模:true/false,true表明支撑旋转,false表明不支撑旋转
support_rotation: false
#========================= 动态AIPP需设置,静态AIPP无需设置(end)====================

#========================= 静态AIPP需设置,动态AIPP无需设置 (start)=================
# 输入图画格局,可选
# 类型: enum
# 取值规模:YUV420SP_U8、XRGB8888_U8、RGB888_U8、YUV400_U8
input_format: 
# 阐明:模型转化完毕后,在对应的*.om模型文件中,上述参数分别以1、2、3、4枚举值呈现。

# 原始图画的宽度、高度
# 类型:int32
# 取值规模 & 束缚:宽度取值规模为[2,4096]或0;高度取值规模为[1,4096]或0,关于YUV420SP_U8类型的图画,要求原始图画的宽和高取值是偶数
src_image_size_w: 0
src_image_size_h: 0
# 阐明:请依据实际图片的宽、高装备src_image_size_w和src_image_size_h;只要crop,padding功用都没有敞开的场景,src_image_size_w和src_image_size_h才干取值为0或不装备,该场景下会取网络模型输入界说的w和h,而且网络模型输入界说的w取值规模为[2,4096],h取值规模为[1,4096]。
# C方向的填充值,保存字段,暂不支撑该功用
# 类型: float16
# 取值规模:[-65504, 65504]
cpadding_value: 0.0

#========= crop参数设置(装备样例请拜见AIPP装备 > Crop/Padding装备阐明) =========
# AIPP处理图片时是否支撑抠图
# 类型:bool
# 取值规模:true/false,true表明支撑,false表明不支撑
crop: false

# 抠图起始位置水平、笔直方向坐标,抠图大小为网络输入界说的w和h
# 类型:int32
# 取值规模 & 束缚: [0,4095]、关于YUV420SP_U8类型的图画,要求取值是偶数
# 阐明:load_start_pos_w<src_image_size_w,load_start_pos_h<src_image_size_h
load_start_pos_w: 0
load_start_pos_h: 0

# 抠图后的图画size
# 类型:int32
# 取值规模 & 束缚: [0,4096]、load_start_pos_w + crop_size_w <= src_image_size_w、load_start_pos_h + crop_size_h <= src_image_size_h
crop_size_w: 0
crop_size_h: 0
# 阐明:若敞开抠图功用,而且没有装备padding,该场景下crop_size_w和crop_size_h才干取值为0或不装备,此时抠图大小(crop_size[W|H])的宽和高取值来自模型文件--input_shape中的宽和高,而且--input_shape中的宽和高取值规模为[1,4096]。

# 抠图束缚如下:
# 若input_format取值为YUV420SP_U8,则load_start_pos_w、load_start_pos_h必须为偶数。
# 若input_format取值为其他值,对load_start_pos_w、load_start_pos_h无束缚。
# 若敞开抠图功用,则src_image_size[W|H] >= crop_size[W|H]+load_start_pos[W|H]。


#================================== resize参数设置 ================================
# AIPP处理图片时是否支撑缩放,保存字段,暂不支撑该功用
# 类型:bool
# 取值规模:true/false,true表明支撑,false表明不支撑
resize: false
# 缩放后图画的宽度和高度,保存字段,暂不支撑该功用
# 类型:int32
# 取值规模 & 束缚:resize_output_h:[16,4096]或0;resize_output_w:[16,1920]或0;resize_output_w/resize_input_w∈[1/16,16]、resize_output_h/resize_input_h∈[1/16,16]
resize_output_w: 0
resize_output_h: 0
# 阐明:若敞开了缩放功用,而且没有装备padding,该场景下resize_output_w和resize_output_h才干取值为0或不装备,此时缩放后图画的宽和高取值来自模型文件--input_shape中的宽和高,而且--input_shape中的高取值规模为[16,4096],宽取值规模为[16,1920]。


#======== padding参数设置(装备样例请拜见AIPP装备 > Crop/Padding装备阐明) =========
# AIPP处理图片时padding使能开关
# 类型:bool
# 取值规模:true/false,true表明支撑,false表明不支撑
padding: false
# H和W的填充值,静态AIPP装备
# 类型: int32
# 取值规模:[0,32]
left_padding_size: 0
right_padding_size: 0
top_padding_size: 0
bottom_padding_size: 0
# 阐明:AIPP经过padding后,输出的H和W要与模型需求的H和W保持一致,其间W取值要<=1080。

# 上下左右方向上padding的像素取值,静态AIPP装备
# 类型:uint8/int8/float16
# 取值规模分别为:[0,255]、[-128, 127]、[-65504, 65504]
padding_value: 0
# 阐明:该参数取值需求与最终AIPP输出图片的数据类型保持一致。


#================================ rotation参数设置 ==================================
# AIPP处理图片时的旋转视点,保存字段,暂不支撑该功用
# 类型:uint8
# 规模:{0, 1, 2, 3} 0不旋转,1顺时针90,2顺时针180,3顺时针270
rotation_angle: 0


#========= 色域转化参数设置(装备样例请拜见AIPP装备 > 色域转化装备阐明) =============
# 色域转化开关,静态AIPP装备
# 类型:bool
# 取值规模:true/false,true表明敞开色域转化,false表明封闭
csc_switch: false

# R通道与B通道交流开关/U通道与V通道交流开关
# 类型:bool
# 取值规模:true/false,true表明敞开通道交流,false表明封闭
rbuv_swap_switch :false

# RGBA->ARGB, YUVA->AYUV交流开关
# 类型:bool
# 取值规模:true/false,true表明敞开,false表明封闭
ax_swap_switch: false

# 单行处理模式(只处理抠图后的第一行)开关,保存字段,暂不支撑该功用
# 类型:bool
# 取值规模:true/false,true表明敞开单行处理模式,false表明封闭
single_line_mode: false

# 若色域转化开关为false,则本功用不起作用。
# 若输入图片通道数为4,则疏忽A通道或X通道。
# YUV转BGR:
# | B |  | matrix_r0c0 matrix_r0c1 matrix_r0c2 | | Y - input_bias_0 |
# | G | = | matrix_r1c0 matrix_r1c1 matrix_r1c2 | | U - input_bias_1 | >> 8
# | R |  | matrix_r2c0 matrix_r2c1 matrix_r2c2 | | V - input_bias_2 |
# BGR转YUV:
# | Y |  | matrix_r0c0 matrix_r0c1 matrix_r0c2 | | B |     | output_bias_0 |
# | U | = | matrix_r1c0 matrix_r1c1 matrix_r1c2 | | G | >> 8 + | output_bias_1 |
# | V |  | matrix_r2c0 matrix_r2c1 matrix_r2c2 | | R |     | output_bias_2 |

# 3*3 CSC矩阵元素
# 类型:int16
# 取值规模:[-32677 ,32676] 
matrix_r0c0: 298
matrix_r0c1: 516
matrix_r0c2: 0
matrix_r1c0: 298
matrix_r1c1: -100
matrix_r1c2: -208
matrix_r2c0: 298
matrix_r2c1: 0
matrix_r2c2: 409

# RGB转YUV时的输出偏移
# 类型:uint8
# 取值规模:[0, 255]
output_bias_0: 16
output_bias_1: 128
output_bias_2: 128

# YUV转RGB时的输入偏移
# 类型:uint8
# 取值规模:[0, 255]
input_bias_0: 16
input_bias_1: 128
input_bias_2: 128


#============================== 减均值、乘系数设置 =================================
# 核算规矩如下:
# 当uint8->uint8时,本功用不起作用
# 当uint8->fp16时,pixel_out_chx(i) = [pixel_in_chx(i) – mean_chn_i – min_chn_i] * var_reci_chn

# 每个通道的均值
# 类型:uint8
# 取值规模:[0, 255]
mean_chn_0: 0
mean_chn_1: 0
mean_chn_2: 0
mean_chn_3: 0

# 每个通道的最小值
# 类型:float16
# 取值规模:[0, 255]
min_chn_0: 0.0
min_chn_1: 0.0
min_chn_2: 0.0
min_chn_3: 0.0

# 每个通道方差的倒数
# 类型:float16
# 取值规模:[-65504, 65504]
var_reci_chn_0: 1.0
var_reci_chn_1: 1.0
var_reci_chn_2: 1.0
var_reci_chn_3: 1.0
}

#========================= 静态AIPP需设置,动态AIPP无需设置 (end)=======================

  需求注意的是,AIPP 归一化功用中,一般咱们运用的归一化参数来自于 ImageNet 的统计,以 RGB 来说,即:mean[0.485, 0.456, 0.406],var[0.229, 0.224, 0.225]。归一化的核算方式一般为:((pixel(x)/255.0) – mean)/var。所以这儿的 AIPP 该怎么装备呢?AIPP 里需求把 mean 转化到 [0~255],也即 mean*255相应的 var 转化到 1/(var*255),那么 AIPP 就能够这么装备:

aipp_op{
  ...
  mean_chn_0: 123  # 原 0.485 -> 123 R
  mean_chn_1: 117  # 原 0.456 -> 117 G
  mean_chn_2: 104  # 原 0.406 -> 104 B
  var_reci_chn_0: 0.0171  # 原 0.229 -> 0.0171 R
  var_reci_chn_1: 0.0175  # 原 0.224 -> 0.0175 G
  var_reci_chn_2: 0.0174  # 原 0.225 -> 0.0174 B
}

  好了,以上共享了 谈谈昇腾 CANN AIPP,期望我的共享能对你的学习有一点协助。

<br/>

 【公众号传送】

《极智AI | 谈谈昇腾 CANN AIPP》


极智AI | 谈谈昇腾 CANN AIPP