参考文章:
tensorflow模型转为caffe
1.提取TensorFlow参数
win10下保存文件名不能有:跟/
caffe input shape:BCHW
convolution shape: out_c,in_c,k_h,k_w
deconvolution shape: in_c,out_c,k_h,k_w
tensoflow input shape:BCHW
convolution shape: k_h,k_w,in_c,out_c
deconvolution shape: k_h,k_w,out_c,in_c
#!/usr/bin/python
import tensorflow as tf
import numpy as np
with tf.Session(config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=True)) as sess:
new_saver = tf.train.import_meta_graph("path/to/.meta")
for var in tf.trainable_variables():
print (var.name)
new_saver.restore(sess, tf.train.latest_checkpoint('path/to/checkpoint wenjianjia'))
all_vars = tf.trainable_variables()
for v in all_vars:
name = v.name
name = name.replace(':','/')
fname = name + '.prototxt'
fname = fname.replace('/', '_')
fname = 'E:/ljjie/algorithm/lanenet-lane-detection-master/pb/caffe/' + fname
print(fname)
v_4d = np.array(sess.run(v))
if v_4d.ndim == 4:
# v_4d.shape [ H, W, I, O ]
v_4d = np.swapaxes(v_4d, 0, 2) # swap H, I
v_4d = np.swapaxes(v_4d, 1, 3) # swap W, O
v_4d = np.swapaxes(v_4d, 0, 1) # swap I, O
# v_4d.shape [ O, I, H, W ]
f = open(fname, 'w')
vshape = v_4d.shape[:]
v_1d = v_4d.reshape(v_4d.shape[0] * v_4d.shape[1] * v_4d.shape[2] * v_4d.shape[3])
f.write(' blobs {\n')
for vv in v_1d:
f.write(' data: %8f' % vv)
f.write('\n')
f.write(' shape {\n')
for s in vshape:
f.write(' dim: ' + str(s)) # print dims
f.write('\n')
f.write(' }\n')
f.write(' }\n')
elif v_4d.ndim == 1: # do not swap
f = open(fname, 'w')
f.write(' blobs {\n')
for vv in v_4d:
f.write(' data: %.8f' % vv)
f.write('\n')
f.write(' shape {\n')
f.write(' dim: ' + str(v_4d.shape[0])) # print dims
f.write('\n')
f.write(' }\n')
f.write(' }\n')
f.close()
2.按照TensorFlow网络结构写caffe.prototxt
可在netscope在线编写,可以检查所写网络是否正确,数据维度是否匹配。
tensorflow的bn层对应caffe的bn+scale层
caffe中卷积层输出计算公式:out=((in+2*pad-k)/s)+1
反卷积计算公式:out=(in-1)*s+k-2*pad
各层的编写就在网上搜着写。
3.caffemodel拼接
caffemodel为prototxt+提取出的权重blob。
首先手动将上一步所写prototxt按照提取出的参数名在相应的地方断开。
其次写index.txt,将层与权重相对应,以便下一步拼接
最后通过cat.sh将拆开的prototxt以及权重拼接起来。
#!/bin/bash
cat index.txt |while read line
do
cat $line >>model.prototxt
done
4.caffemodel生成
按大佬的步骤修改.cpp以及CmakList,基本没啥问题。问题出在编译上。
第一次编译,
mkdir cmake
cd cmake
cmake ..
make
报找不到caffe/caffe.hpp的错,检查cmakelist后发现相应头文件已经被添加了,怀疑没有访问权限,于是加上sudo make,成功编译。
第二次编译,还是报找不到caffe/caffe.hpp的错,但是这次sudo make没用了,于是不在cmake文件夹下编译,直接编译
cmake .
make
编译成功。