tensorflow模型转化为caffe模型并调用预测

主宰稳场 提交于 2019-11-28 16:17:54

tensorflow模型转化为caffe模型并调用预测

本文一共分为三个部分首先根据tensorflow的网络结构代码写caffe的deploy.prototxt,再用python代码写XXXX.caffemodel文档,最后调用caffe模型进行预测.

根据tensorflow的网络结构代码写caffe的deploy.prototxt

写完之后可以将代码输入到这里(工具)检测写法是否正确:
验证工具
书写规则如下,我给的每一种类型的其参数是必须写的参数,如果想知道每一层更详细的参数,可以参考:caffe网络结构详解下载
Name是每一层的名字,top是经过这一层数据传向的层,bottom这一层的上一层数据
(1)输入层Input:

12345678910111213
layer {  name: "input"  type: "Input"  top: "data"  input_param {    shape {      dim: 1      dim: 32      dim: 1      dim: 1    }  }}

一定要指定shape层,第一个dim为batchsize也就是一次性可以处理多少个数据,第二个dim为channel,如果处理的是图像也就是图片的通道数.如果处理的是向量,这个就是向量的长度,第三个dim为图像的高度,第四个dim为图像的宽度.如果是向量则第三第四都为1.
(2)全连接层InnerProduct

123456789
layer{    name:"linear"    type:"InnerProduct"    bottom:"data"    top:"linear"    inner_product_param {      num_output: 1024   }}

num_output是下一层向量数目
(3)BatchNorm层

123456789
layer {   bottom: "linear"   top: "bn1"   name: "bn1"   type: "BatchNorm"   batch_norm_param {      use_global_stats: true   }}

这个参数在测试阶段为true,在训练阶段为false
(4)Scale层

123456789
layer {   bottom: "bn1"   top: "bn1"   name: "scale1"   type: "Scale"   scale_param {      bias_term: true   }}

在转换模型的时候,tensorflow的一个 normalization layer相当于caffe的一个连续 batchNorm + Scale:
Convert batch normalization layer in tensorflow to caffe: 1 batchnorm layer in tf is equivalent to a successive of two layer : batchNorm + Scale:
(5)RELU

123456
layer {   bottom: "bn1"   top: "ReLU1"   name: "ReLU1"   type: "ReLU"}

(6)Eltwise

1234567
layer {   bottom: "sum_up"   bottom: "ReLU5"   top: "sum_up2"   name: "sum_up2"   type:"Eltwise"}

在残差网络中需要用这个层相加.

用python代码写模型参数文档

(1)读tensorflow的模型

12345678910
import tensorflow as tfsys.path.insert(0,"/path_to_caffe/python")print(sys.path)import caffeimport numpy as npsess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True))from tensorflow.python import pywrap_tensorflowcheckpoint_path = "./checkpoint-4874200"reader = pywrap_tensorflow.NewCheckpointReader(checkpoint_path)var_to_shape_map = reader.get_variable_to_shape_map()

(在tensorflow较高版本中,模型文档三个 分别为xxx.meta xxxx.index xxx.0000-data-0001)
(2)创建caffe网络

12
cf_prototxt = "./2dto3d_deploy.prototxt"net = caffe.Net(cf_prototxt, caffe.TEST)

(3)将参数读取写入
全解连接层的w和b

12345678
linear_w=np.squeeze(reader.get_tensor('linear_model/w1'))tmp=np.linalg.norm(linear_w)linear_w1=linear_w*1*(tmp>1)/tmp + linear_w*(tmp<=1)net.params['linear'][0].data[:]=np.transpose(linear_w1, (1,0))linear_b=np.squeeze(reader.get_tensor('linear_model/b1'))net.params['linear'][1].data[:]=linear_b

BN层由于tensoflow和caffe有差异
在转化的时候记住caffe的bn+scale层等于tensorflow的bn层次
具体的转化有以下规则:

123456
net.params[bn_name][0].data[:] = tf_movingmean#epsilon 0.001 is the default value used by tf.contrib.layers.batch_norm!!net.params[bn_name][1].data[:] = tf_movingvariance + 0.001net.params[bn_name][2].data[:] = 1 # important, set it to be 1net.params[scale_name][0].data[:] = tf_gammanet.params[scale_name][1].data[:] = tf_beta

相关的具体讨论可以参考:bn层转化
下面给出bn层转化的一个试例

12345678910
bn1_tf_movingmean=np.squeeze(reader.get_tensor('linear_model/batch_normalization/moving_mean'))bn1_tf_movingvariance=np.squeeze(reader.get_tensor('linear_model/batch_normalization/moving_variance'))bn1_tf_gamma=np.squeeze(reader.get_tensor('linear_model/batch_normalization/gamma'))bn1_tf_beta=np.squeeze(reader.get_tensor('linear_model/batch_normalization/beta'))net.params['bn1'][0].data[:] = bn1_tf_movingmean# epsilon 0.001 is the default value used by tf.contrib.layers.batch_norm!!net.params['bn1'][1].data[:] = bn1_tf_movingvariance+ 0.001net.params['bn1'][2].data[:] = 1 # important, set it to be 1net.params['scale1'][0].data[:] = bn1_tf_gammanet.params['scale1'][1].data[:] = bn1_tf_beta

(3)最后写入文档

1
net.save('a.caffemodel')

调用caffe模型预测验证

123456789101112131415
import syssys.path.insert(0,"/path_to_caffe/python")print(sys.path)import caffeimport numpy as npa=[-1.59036,2.64035,-1.84236,2.63166,-1.60718,4.62976,-1.53916,5.21137,-1.26383,2.65532,-1.29271,4.93954,-1.38703,5.27324,-1.58944,0.633358,-1.59042,1.12005,-1.53584,0.696239,-1.08071,0.598781,-0.603272,-0.938632,0.0140431,-2.17247,-1.89872,0.648127,-2.23398,-0.798227,-2.80334,-1.86967]p2d=np.array(a)y=np.reshape(p2d,(1,32,1,1))caffe.set_mode_gpu()model_def = './2dto3d_deploy.prototxt'model_pretrained ='./a.caffemodel'net = caffe.Net(model_def,model_pretrained,caffe.TEST)net.blobs['data'].data[...]=yout = net.forward() #前像传播预测print (out)

以上测试数据的正确预测结果为:
{‘linear6’: array([[-1.1093297 , 0.13423912, -0.71337676, -0.3413014 , 0.60594785,
-0.503688 , -0.44055757, 0.61926687, -0.3807128 , 1.1093313 ,
-0.13424 , 0.7133761 , 0.57371044, 0.56901824, -0.12641048,
0.05005788, 0.47413373, 0.14192167, -0.3304365 , -0.7288994 ,
0.4668903 , 0.06698397, -0.6077603 , 0.33841628, 0.02581951,
-0.36136347, -0.09946679, 0.07204475, -0.29733503, 0.13283135,
0.85128194, -1.0867463 , 0.6229229 , 1.1905218 , -3.798849 ,
0.13268307, 1.8069856 , -3.7732291 , -0.5529848 , -0.9289112 ,
-0.9280683 , 0.14142033, -1.392531 , -2.9245243 , -0.55180794,
-1.8918784 , -2.9869053 , -1.0472283 ]], dtype=float32)}

附件下载

最后我给出了一个示例转换的所有文档附件下载地址
其中有如下内容:
(1) linear_model.py 为网络结构的定义文档可以参考这个文档的代码按照规则写出
(2) 2dto3d_deploy.prototxt
(3)checkpoint*文档是tensorflow模型文档
(4)caffe_script.py为写模型参数文档运行之后生产a.caffemodel
(5)predict.py根据2dto3d_deploy.prototxt和a.caffemodel进行预测看结果是否正确已经给出一组测试数据
(6)caffe网络模型深入理解各层详解.pdf

 

 

 

 

 

 

 

 

原文链接 大专栏  https://www.dazhuanlan.com/2019/08/19/5d59ba6a9af46/

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!