From 33740b13d442be6c21171c1bae8237d6eb7aa498 Mon Sep 17 00:00:00 2001 From: SunAhong1993 <48579383+SunAhong1993@users.noreply.github.com> Date: Fri, 9 Aug 2019 16:20:56 +0800 Subject: [PATCH] Update add_caffe_custom_layer.md --- add_caffe_custom_layer.md | 80 ++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/add_caffe_custom_layer.md b/add_caffe_custom_layer.md index f1f875e..2f393d7 100644 --- a/add_caffe_custom_layer.md +++ b/add_caffe_custom_layer.md @@ -1,8 +1,18 @@ ## 如何转换Caffe自定义Layer -本文档介绍如何将Caffe自定义Layer转换为PaddlePaddle模型中的对应实现, 用户可根据自己需要,添加代码实现自定义层,从而支持模型的完整转换。 +本文档介绍如何将Caffe自定义Layer转换为PaddlePaddle模型中的对应实现, 用户可根据自己需要,添加代码实现自定义层,从而支持模型的完整转换。 +***步骤一 下载代码*** +此处涉及修改源码,应先卸载x2paddle,并且下载源码,主要有以下两步完成: +``` +pip uninstall x2paddle +pip install git+https://github.com/PaddlePaddle/X2Paddle.git@develop +``` + +***步骤二 编译caffe.proto*** +该步骤依赖protobuf编译器,其安装过程有以下两种方式: +> 选择一:pip install protobuf +> 选择二:使用[官方源码](https://github.com/protocolbuffers/protobuf)进行编译 -***步骤一 编译caffe.proto*** 使用脚本./tools/compile.sh将caffe.proto(包含所需的自定义Layer信息)编译成我们所需的目标语言(Python) 使用方式: ``` @@ -10,53 +20,55 @@ bash ./toos/compile.sh /home/root/caffe/src/caffe/proto # /home/root/caffe/src/caffe/proto为caffe.proto的存放路径,生成的caffe_pb2.py也将保存在该路径下 ``` -***步骤二 添加自定义Layer的实现代码*** -- 进入./x2paddle/op_mapper/caffe_custom_layer,创建实现代码的文件,例如mylayer.py -- 仿照./x2paddle/op_mapper/caffe_custom_layer中的其他文件,在mylayer.py中主要实现3个函数: - 1. `def mylayer_shape(input_shape, ...)` - - | 参数 | 类型 | 说明 | - | :---------: | :--: | :---------: | - | input_shape | list | 每个元素代表该层每个输入数据的shape | - | 其余 | 默认为None | 命名为Caffe模型的model.prototxt中mylayer_param中每个参数的名字 | - - 功能:计算出mylayer的输出shape - 返回:一个list,其中每个元素代表每个输出数据的shape +***步骤三 添加自定义Layer的实现代码*** +- 进入./x2paddle/op_mapper/caffe_custom_layer,创建.py文件,例如mylayer.py +- 仿照./x2paddle/op_mapper/caffe_custom_layer中的其他文件,在mylayer.py中主要需要实现3个函数,下面以roipooling.py为例分析代码: + 1. `def roipooling_shape(input_shape, pooled_w=None, pooled_h=None)` + 参数: + 1. input_shape(list):其中每个元素代表该层每个输入数据的shape,为必须传入的参数 + 2. pooled_w(int):代表ROI Pooling的kernel的宽,其命名与.prototxt中roi_pooling_param中的key一致 + 3. pooled_h(int):代表ROI Pooling的kernel的高,其命名与.prototxt中roi_pooling_param中的key一致 - 2. `def mylayer_layer(inputs, input_shape=None, name=None, ...)` - - | 参数 | 类型 | 说明 | - | :---------: | :--: | :---------: | - | inputs | list | 每个元素代表该层每个输入数据 | - | input_shape | list(默认为None) | 每个元素代表该层每个输入数据的shape | - | name | str(默认为None) | mylayer的名字 | - | 其余 | 默认为None | 命名为Caffe模型的model.prototxt中mylayer_param中每个参数的名字 | + 功能:计算出进行ROI Pooling后的shape + 返回:一个list,其中每个元素代表每个输出数据的shape,由于ROI Pooling的输出数据只有一个,所以其list长度为1 + + 2. `def roipooling_layer(inputs, input_shape=None, name=None, pooled_w=None, pooled_h=None, spatial_scale=None)` - 功能:运用PaddlePaddle完成组网来实现`mylayer`的功能 - 返回:一个Variable或Tensor,为组网后的结果 + 参数: + 1. inputs(list):其中每个元素代表该层每个输入数据,为必须传入的参数 + 2. input_shape(list):其中每个元素代表该层每个输入数据的shape,为必须传入的参数 + 3. name(str):ROI Pooling层的名字,为必须传入的参数 + 4. pooled_w(int):代表ROI Pooling的kernel的宽,其命名与.prototxt中roi_pooling_param中的key一致 + 5. pooled_h(int):代表ROI Pooling的kernel的高,其命名与.prototxt中roi_pooling_param中的key一致 + 6. spatial_scale(float):用于将ROI坐标从输入比例转换为池化时使用的比例,其命名与.prototxt中roi_pooling_param中的key一致 + + 功能:运用PaddlePaddle完成组网来实现`roipooling_layer`的功能 + 返回:一个Variable,为组网后的结果 - 3. `def mylayer_weights(name, data=None)` - - | 参数 | 类型 | 说明 | - | :---------: | :--: | :---------: | - | name | str | mylayer的名字 | - | data | list(默认为None) | 由Caffe模型的model.caffemodel获得的关于mylayer的参数 | + 3. `def roipooling_weights(name, data=None)` + + 参数: + 1. name(str):ROI Pooling层的名字,为必须传入的参数 + 2. data(list):由Caffe模型.caffemodel获得的关于roipooling的参数,roipooling的参数为None 功能:为每个参数(例如kernel、bias等)命名;同时,若Caffe中该层参数与PaddlePaddle中参数的格式不一致,则变换操作也在该函数中实现。 返回:一个list,包含每个参数的名字。 -- 在mylayer.py中注册`mylayer`,主要运用下述代码实现: +- 在roipooling.py中注册`roipooling`,主要运用下述代码实现: ``` - register(kind='Mylayer', shape=mylayer_shape, layer=mylayer_layer, weights=mylayer_weights) - # kind为在model.prototxt中mylayer的type + register(kind='ROIPooling', shape=roipooling_shape, layer=roipooling_layer, weights=roipooling_weights) + # kind为在model.prototxt中roipooling的type ``` - 在./x2paddle/op_mapper/caffe_custom_layer/\_\_init\_\_.py中引入该层的使用 ``` - from . import mylayer + from . import roipooling ``` ***步骤三 运行转换代码*** ``` +# 在X2Paddle目录下安装x2paddle +python setup.py install +# 运行转换代码 x2paddle --framework=caffe --prototxt=deploy.proto --weight=deploy.caffemodel -- GitLab