深度学习模型转换(tensorflow2caffe)

2019-12-30  本文已影响0人  半笔闪

目前为止已经有很多成熟的深度学习框架,比如tensorflow、caffe、pytorch、paddlepaddle等等,很多时候我们训练时使用了一个框架,但是部署时需要使用另一个框架。就比如,我们训练使用了caffe,但是部署到生产使用的时tensorflow。又比如,我们需要部署到移动设备上,这是我们可能选择了一些移动端深度学习推理框架(ncnn、mnn、armnn等)。但是这些框架的模型文件都是不同的,所以如果我们需要解决上面的情况,就需要对模型进行转换。
其实现在已经又很多开源的转换工具,比如微软出品的mmdnn,但是深入了解模型转换是又必要的,因为新算子的出现、各框架模型版本的跟新等等问题,很多时候我们还是需要自己写转换。

layer {
  name: "ReLU2_2"   #relu层
  type: "ReLU"
  bottom: "conv2_2"
  top: "conv2_2"
}

上面是一个relu层的例子,基本上,caffe层的描述都是这样,name是层的名字,top是下一层的名字,bottom是上一层的名字,type是这一层的类型如(InnerProduct是全连接层等等)。当然还会有其他参数,比如BatchNorm层:

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

不同的层会有相应参数的增减。如果我们的模型是用tensorflow训练的,那么我们就可以根据我们的模型来写出一个deploy.prototxt。

model_path='model/'
saver=tf.train.import_meta_graph(model_path+'model.resnet.ckpt.meta')
with tf.Session() as sess:   
 
 saver.restore(sess,tf.train.latest_checkpoint(model_path))
graph = tf.get_default_graph()

有了graph就可以取到模型中的各种权重参数了,比如:

linear_w=np.squeeze(graph.get_tensor_by_name('linear_model/w1'))

接着,我们创建caffe网络:

cf_prototxt = "deploy.prototxt"
net = caffe.Net(cf_prototxt, caffe.TEST)
#把解析上面从tensorflow得到的linear_w写到caffe的net中对应的层里
net.params['linear'][0].data[:]=np.transpose(linear_w, (1,0))
#当然可能还有偏移量b
linear_b=np.squeeze(graph.get_tensor_by_name('linear_model/b1'))
net.params['linear'][1].data[:]=linear_b

依次类推,我们可以一层一层的把tensorflow参数写进caffe的net中,最终完成模型的转换。

上一篇下一篇

猜你喜欢

热点阅读