NCNN转模型——Caffe转NCNN

一、转模型方法

NCNN编译完成后生成的工具中有一个caffe2ncnn,使用这个工具可以将caffe模型转成ncnn模型,该工具的命令参数格式为:./caffe2ncnn [caffeproto] [caffemodel] [ncnnparam] [ncnnbin],比如:

ncnn/build/tools/caffe/caffe2ncnn deploy.prototxt model.caffemodel model.param model.bin

二、NCNN模型文件说明

成功后会生成model.param和model.bin两个文件。model.param是ncnn网络结构文件,如:

7767517
19 19
Input            data             0 1 data 0=64 1=64 2=3
Convolution      conv1            1 1 data conv1 0=32 1=5 2=1 3=1 4=0 5=1 6=2400
ReLU             relu1            1 1 conv1 conv1_relu1
Pooling          pool1            1 1 conv1_relu1 pool1 0=0 1=2 2=2 3=0 4=0
Convolution      conv2            1 1 pool1 conv2 0=64 1=3 2=1 3=1 4=0 5=1 6=18432
ReLU             relu2            1 1 conv2 conv2_relu2
Pooling          pool2            1 1 conv2_relu2 pool2 0=0 1=2 2=2 3=0 4=0
Convolution      conv3            1 1 pool2 conv3 0=64 1=3 2=1 3=1 4=0 5=1 6=36864
ReLU             relu3            1 1 conv3 conv3_relu3
Pooling          pool3            1 1 conv3_relu3 pool3 0=0 1=2 2=2 3=0 4=0
Convolution      conv4            1 1 pool3 conv4 0=128 1=2 2=1 3=1 4=0 5=1 6=32768
ReLU             relu4            1 1 conv4 conv4_relu4
Pooling          pool4            1 1 conv4_relu4 pool4 0=0 1=2 2=2 3=0 4=0
Convolution      conv5            1 1 pool4 conv5 0=128 1=2 2=1 3=1 4=0 5=1 6=65536
ReLU             relu5            1 1 conv5 conv5_relu5
InnerProduct     ip1              1 1 conv5_relu5 ip1 0=512 1=1 2=262144
ReLU             relu5            1 1 ip1 ip1_relu5
InnerProduct     ip2              1 1 ip1_relu5 ip2 0=2 1=1 2=1024
Softmax          softmax          1 1 ip2 softmax 0=0 1=1

第一行:7767517
param版本

第二行:[layer count] [blob count]
• layer count:后续的层line的数量,必须是所有层的准确数量
• blob count:所有blob的数量,一般情况下是大于等于层的数量的

第三行及之后:[layer type] [layer name] [input count] [output count] [input blobs] [output blobs] [layer specific params]
• layer type : 层类型的名字,例如Convolution、Softmax等
• layer name : 层的名字,在所有的层名字里面必须是唯一的
• input count : 本层输入的blob的数量
• output count : 本层输出的blob的数量
• input blobs : 所有输入blob的名字列表,由空格隔开,必须是在所有层的所有输入blob的名字里是唯一的
• output blobs : 所有输出blob的名字列表,由空格隔开,必须是在所有层的所有输出blob的名字里是唯一的
• layer specific params : key=value对的列表,由空格隔开

model.bin为与model.param中结构对应的模型参数。

需要注意的是,有时候转出来的model.param需要手动调整,比如caffe中的某些层在NCNN中不支持(如Tile)需要替换或删除,但不能影响model.param中定义的网络各层参数量,否则model.bin中的参数与model.param对应不上就会导致出错。

三、遇到过的问题

1.报find_blob_index_by_name blob1_splitncnn_3 failed的错误
deploy.prototxt格式问题,需要将

input: "blob1"
input_dim: N
input_dim: C
input_dim: H
input_dim: W

替换成如下格式

layer{
  name: "blob1"
  type: "Input"
  top: "blob1"
  input_param {
  shape: {
    dim: N 
	dim: C 
	dim: H 
	dim: W 
	} 
  }
}

2、caffe中的Tile层在ncnn中不支持,且ncnn中的expand层(ExpandDim)与pytorch中的expand_as功能不同,但ncnn中支持两个不同shape的blob相乘,如:N*C*1*1的blob与N*C*H*W的blob相加或相乘等等,这是通过BinaryOp来实现的,但两个blob的shape不相等时,不能用Eltwise层来实现相乘或相加,因为ncnn的Eltwise层中没有进行shape相同检查。

3、ncnn中支持Interp层,原生caffe中一般不支持,所以自定义caffe中的Interp层转到ncnn时,需要注意缩放参数的修改。

4、pytorch和ncnn中支持InstanceNorm层,但caffe中不支持,不过caffe中可以通过BatchNorm层来代替(前提是batch=1),在转ncnn时,需要先将.prototxt中的BatchNorm换成InstanceNorm,如果转换完成之后再在.param中修改,会把.caffemodel中替代InstanceNorm的BatchNorm的参数转到ncnn模型中,ncnn在加载.bin中的参数时会去按顺序获取层的参数(如BatchNorm的mean,var等),而ncnn中的InstanceNorm层的mean、var等是计算当前batch的,即会跳过从caffemodel中转过来的mean、var等参数,这就导致后面的所有层加载的参数发生顺序错乱,最终导致结果出错。比如:InstanceNorm层后面的BatchNorm层读取到的mean,var等参数都是错误的,甚至var为负数,导致sqrt(var)=nan的现象。

5、如果InstanceNorm中没有做线性变换(y=alpha*x+beta),那么caffe转ncnn时,.param中InstanceNorm的第三个参数affine要设置成0,即2=0。因为caffe中的BatchNorm中没有这个参数。
否则加载参数时会报模型参数不匹配的错误,如:"layer load_model 229 instance_norm1 failed"。

6、删减或增加层数之后,注意修改.param中的层数和blob数,否则会报错:
"load_model error at layer 355, parameter file has inconsistent content."

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值