附录Ⅰ. 如何添加新的Layer
1. 概述¶
本节仅适用于caffe 模型。对于sigmastar 还未实现的layer,用sigmastar 提供底层算子来组合实现。底层算子与 tensorflow 的算子类似,支持的算子参考DLA SDK支持:TensofFlow 支持算子 支持算子转换流程如下图
CaffeConvert Tool (代码位置:SGS_IPU_SDK/Scripts/ConvertTool/ConvertTool.py
) caffe 模型转换工具借鉴了小米开源框架mace 的设计,要添加新的layer,请先到Xiaomi MACE下载原始代码,按照mace 官方文档配置 好编译环境,或者直接使用我们提供的docker 环境。 下面以reorg layer
为例子,讲解如何添加新的layer,主要修改以下几个文件
2. Caffe proto 文件修改¶
2.1 修改caffe proto¶
Mace 原始代码下载后,用SGS_IPU_SDK/Scripts/CaffeConvertTool/third_party/caffe/caffe.proto
替换掉mace 工程 路径下mace/third_party/caffe 下caffe.proto 文件。因为sigmastar 在mace 基础上做了二次开发,所以sigmstar 支持 的caffe layer 已经远远多于原生的mace 支持数量。要添加新的layer,请以sigmastar 的caffe proto 文件作为基础 添加。
optional ReorgParameter reorg_param = 157;
}
message ReorgParameter {
optional uint32 stride = 1;
optional bool reverse = 2 [default = false];
}
2.2 编译proto 文件¶
在mace 开发环境中
cd pathToMace/
bazel build third_party/caffe/caffe_py
在bazel-genfiles 下生成caffe_pb2.py 将上面修改后的caffe.proto 和生成的caffe_pb2.py 替换SGS_IPU_SDK/Scripts/CaffeConvertTool/third_party/caffe
同 名文件,然后按照如下顺序修改代码
3. 修改caffe_converter.py¶
文件路径SGS_IPU_SDK/Scripts/CaffeConvertTool/mace/python/tools/converter_tool/caffe_converter.py
该文件的作用是把caffe模型转换为mace模型,并保存该layer的参数
Reorg':self.convert_Reorg,
...
...
def convert_Reorg(self, caffe_op):
op = self.convert_general_op(caffe_op)
op.type = "Reorg"
param = caffe_op.layer.reorg_param
stride_arg = op.arg.add()
stride_arg.name = "stride"
stride_arg.i = 1 #default is true
if param.HasField('stride'):
stride_arg.i = int(param.stride)
4. 修改shape_inference.py¶
文件路径SGS_IPU_SDK/Scripts/CaffeConvertTool/mace/python/tools/converter_tool/shape_inference.py
该文件的作用是计算layer的output shape
Reorg': self.infer_shape_Reorg,
...
...
def infer_shape_Reorg(self, op):
#only support stride is 2
output_shape = self._output_shape_cache[op.input[0]]
input_shape = list(self._output_shape_cache[op.input[0]])
input_n = input_shape[0]
input_c = input_shape[1]
input_h = input_shape[2]
input_w = input_shape[3]
output_shape = [input_n,int(input_c*4),int(input_h/2),int(input_w/2)]
self.add_output_shape(op, [output_shape])
5. 修改SGSModel_transform.py¶
如下图所示,我们发现reorg在NCHW的排列顺序下,它实际上是对数据做了一个重排。
因此,我们最后拆解出来的算子组合是
按照算子组合顺序,编写代码 文件路径SGS_IPU_SDK/Scripts/CaffeConvertTool/mace/python/tools/SGSModel_transform.py
该文件作用是增加该layer 的拆解函数。即用Sigmastar 提供的基本算子实现该layer。
Reorg':self.split_Reorg,
...
...
def split_Reorg(self, op):
#only support strid is 2
[n,c,h,w] = op.output_shape[0].dims[:]
c = int(c/4)
op_name = op.name
xi = op.input[0]
...
...
6. Layer拆解注意事项与技巧¶
6.1. Layer拆解注意事项与技巧 数据维度的问题¶
在caffe网络中,使用NCHW数据排列。而sigmastar使用NHWC的顺序进行数据计算(与tensorflow类似)。所以在模型转换成sim模型的时候,会对所有4维度的shape和数据做一次转换。即NCHW转到NHWC 参考代码:SGS_IPU_SDK/Scripts/CaffeConvertTool/mace/python/tools/SGSModel_converter.py
对于tensor data的转换
def _creatBuffer(self):
...
...
if len(ori_shape) == 4:
#transpose data to NHWC
six.print_("Reshape ",tensor.name,"to NHWC")
data = np.array(ori_data)
data = data.reshape(ori_shape)
data = data.transpose(0,2,3,1)
def _creatTensor(self):
...
...
if len(shape) == 4 and data_format == mace_pb2.DT_NCHW:
Transformer.transpose_shape(shape, [0, 2, 3, 1])
tflite.Tensor.TensorStartShapeVector(self._builder,len(shape))
(1)有axis参数的,要注意顺序交换
比如`concat layer,caffe model里面,它要对C纬度做concat,其axis为1。网络转换后,C为换到了最低维,所 以要修改axis为3,代码如下。相似的还有split、PRelu等
def split_Concat(self, op):
...
...
if len(output_shape[0].dims) == 4:#nchw -> nhwc
if arg[i].i == 1:
arg[i].i = 3
else if arg[i].i == 2:
arg[i].i = 1
else if arg[i].i == 3:
arg[i].i = 2
(3)在NCHW 数据排列下有很强规律的layer,可以先转到NCHW 下操作。比如上面提到的reorg layer。
(4)用sdk 里面提供的Netron 工具打开转换后的sim 模型,方便查看各种属性和shape。
6.2. 建议拆解流程¶
综上所述,在拆解的过程中,我们建议按照如下流程进行
6.3. 数据对比及验证¶
前期可以用python 创建tensorflow 算子的方法,进行验证。 当验证完成,再修改SGS_IPU_SDK 的相关代码,参考Dump_Debug Tool章节,dump 出最后结果与golden 比对。