caffe安装_keras/tensorflow1.x模型转换为caffe推理模型

015bbe1413e02f24b36397c5f155a22d.png

前言

在工业界混的人,每个人都有自己习惯的框架,有时为了部署不得不在框架之间进行模型转换。踩了几个坑之后,终于转换成功,这里记录一下分享一下。gayhub链接:

xggIoU/tensorflow_keras_to_caffe​github.com
225cddf9b1df6db6441d5c4fea939db9.png

envs/tools

tensorflow1.13.2、keras2.2.4、caffe1.0、python3.6、pycharm、Anoconda、MMdnn0.2.4、ubuntu18.04

准备工作

  • 如果你像我一样caffe只是转换过程需要,而平常不用它来train,你可以简单的利用conda安装编译好了的caffe,命令行:
python conda install caffe-gpu
  • 如果你的模型本身现在本来就是keras model,那么上述环境中所述的MMdnn就不需要了。
  • 如果你的模型现在是tensorflow model,例如ckpt model,那么就需要微软的MMdnn进行转换,虽然这个工具目前还不能无缝转换所有不同框架模型,但是tf与keras的互相转换还是无痛的,毕竟可以说是同一个框架。命令行转换示例:
python mmconvert -sf tensorflow -in your_model_name.ckpt.meta -iw your_model_name.ckpt --inNodeName input_name --inputShape 224,224,3 --dstNodeName output1 ouput2 -df keras -om your_keras_model.h5

开始转换

这里不讲具体的转换过程,你可以自己去看转换脚本,很容易就能看懂。并且对照着已有的脚本代码也容易就能实现自己用到的layer的转换。使用很简单,指定好你的keras模型路径,指定好你想要的caffe模型的输出prototxt、caffemodel名字,最后run就ok了。像这样:

if __name__=='__main__':
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    sess = tf.Session(config=config)
    K.set_session(sess)
    kModel=load_keras_model('../your_keras_model.h5')
    prototxt='../your_caffe_model.prototxt'
    caffemodel='../your_caffe_model.caffemodel'
    generate_caffe_model(kModel, prototxt, caffemodel)

目前实现的可转换layer如下:

- InputLayer
- Dense
- Dropout
- ZeroPadding2D
- Multiply、Concatenate、Maximum、Add
- Conv2D、Conv2DTranspose
- BatchNormalization
- MaxPooling2D、AveragePooling2D、GlobalAveragePooling2D
- relu、prelu、elu、softmax、sigmoid、tanh

这样就已经能转换绝大部分模型了,如果没实现你用到的layer,你可自行在函数generate_layer(blobs, layer, n, net_params)添加你的layer即可。

Tips(坑)

  • 如果你的模型是tensorflow模型,并且使用了转置卷积conv2d_transpose(caffe中为Deconvolution),那么千万避免使用高级api,例如slim.conv2d_transpose,而是需要使用更低级的tf.nn.conv2d_transpose接口。否则会转换失败(看了下,貌似实现是不一样的)。
  • 另外,tf/keras中卷积的padding与caffe的padding方式不一样,tf/keras在padding方式为same情况下存在只pad右下的情况,而caffe是上下左右都pad,会导致结果有误差。tf中的same pad具体计算如下,以宽度为例:
width_padd=(new_width-1)*stride+kernel_size-ori_width
padd_left=width_padd//2
padd_right=width_padd-padd_left

为了解决这个问题,在tf/keras中建议对卷积改造一下,手动加pad,就像这样:

def conv2d(inputs, filters, kernel_size, strides=1,rate=1,biases_initializer=tf.zeros_initializer, activation_fn=tf.nn.relu):#stride>1时padding,valid卷积实现same
    def _fixed_padding(inputs, kernel_size):
        pad_total = kernel_size - 1
        pad_beg = pad_total // 2
        pad_end = pad_total - pad_beg

        padded_inputs = tf.pad(inputs, [[0, 0], [pad_beg, pad_end],
                                        [pad_beg, pad_end], [0, 0]], mode='CONSTANT')
        return padded_inputs

    if strides > 1:
        inputs = _fixed_padding(inputs, kernel_size)
    inputs = slim.conv2d(inputs, filters, kernel_size, stride=strides,rate=rate,biases_initializer=biases_initializer,
                       activation_fn=activation_fn,padding=('SAME' if strides == 1 else 'VALID'),weights_initializer=tf.initializers.he_normal())
    return inputs

如此一来,在转换过程中去掉pad层,(去掉keras中的ZeroPadding2D层),就能直接只使用caffe中的卷积层,实现一致的输出。

希望对你有帮助!

reference

keras2caffe,我修改了其中的bug,简化了代码,只转换为inference model。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值