将Tensorflow模型转换为Caffe模型

时间:2016-12-14 09:01:17

标签: tensorflow caffe

我希望能够将Tensorflow模型转换为Caffe模型。

我在谷歌上搜索但是我只能找到从caffe到tensorflow的转换器,但不是相反。

有没有人知道如何做到这一点?

谢谢, EVI

3 个答案:

答案 0 :(得分:5)

我遇到了同样的问题并找到了解决方案。代码可以在这里找到(https://github.com/lFatality/tensorflow2caffe),我还在一些Youtube视频中记录了代码。

Part 1涵盖了在Caffe和VGG-19中构建tflearn的体系结构(TensorFlow的更高级API,对TensorFlow代码的一些更改也应该有效)。

Part 2中,描述了将TensorFlow模型中的权重和偏差导出为numpy文件。在tflearn中,您可以获得如下图层的权重:

#get parameters of a certain layer
conv2d_vars = tflearn.variables.get_layer_variables_by_name(layer_name)
#get weights out of the parameters
weights = model.get_weights(conv2d_vars[0])
#get biases out of the parameters
biases = model.get_weights(conv2d_vars[1])

对于卷积层,layer_name为Conv_2D。完全连接的层称为FullyConnected。如果使用某个类型的多个图层,则使用带有前面下划线的上升整数(例如,第2个转换图层称为Conv_2D_1)。我在TensorBoard的图表中找到了这些名字。如果在体系结构定义中命名图层,则这些layer_names可能会更改为您定义的名称。

在原生TensorFlow中,导出将需要不同的代码,但参数的格式应该相同,因此后续步骤仍然适用。

Part 3涵盖实际转化。当你创建caffemodel时,权重的转换是至关重要的(偏差可以在没有变化的情况下进行)。保存过滤器时,TensorFlow和Caffe使用不同的格式。虽然TensorFlow使用[height, width, depth, number of filters]TensorFlow docs, at the bottom),但Caffe使用[number of filters, depth, height, width]Caffe docs, chapter 'Blob storage and communication')。要在格式之间进行转换,您可以使用transpose函数(例如:weights_of_first_conv_layer.transpose((3,2,0,1))。可以通过枚举TensorFlow格式(原点)然后将其切换为3来获得3,2,0,1序列Caffe格式(目标格式),同时将数字保持在特定变量。) 如果要将张量输出连接到完全连接的层,事情会变得有点棘手。如果您使用输入尺寸为112x112的VGG-19,它看起来像这样。

fc1_weights = data_file[16][0].reshape((4,4,512,4096))
fc1_weights = fc1_w.transpose((3,2,0,1))
fc1_weights = fc1_w.reshape((4096,8192))

如果在张量和完全连接层之间的连接处导出参数,则从TensorFlow获得的是形状为[entries in the tensor, units in the fc-layer]的数组(此处为:[8192, 4096])。您必须找出输出张量的形状,然后重新整形数组,使其符合TensorFlow格式(参见上文number of filtersnumber of units in the fc-layer)。之后,您使用先前使用过的转置转换,然后再次重新整形数组,反之亦然。虽然TensorFlow将fc层权重保存为[number of inputs, number of outputs],但Caffe却反过来 如果您将两个fc层相互连接,则不必执行前面描述的复杂过程,但您必须通过再次转置来考虑不同的fc层格式(fc_layer_weights.transpose((1,0))

然后,您可以使用

设置网络参数
net.params['layer_name_in_prototxt'][0].data[...] = weights
net.params['layer_name_in_prototxt'][1].data[...] = biases

这是一个快速概述。如果你想要所有代码,它就在我的github存储库中。我希望它有所帮助。 :)

干杯,
死亡率

答案 1 :(得分:3)

正如@Patwie的评论中所建议的那样,你必须通过逐层复制权重来手动完成。例如,要将第一个转换层权重从张量流检查点复制到caffemodel,您必须执行以下操作:

sess = tf.Session()
new_saver = tf.train.import_meta_graph("/path/to/checkpoint.meta")
what = new_saver.restore(sess, "/path/to/checkpoint")

all_vars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES)

conv1 = all_vars[0]
bias1 = all_vars[1]

conv_w1, bias_1 = sess.run([conv1,bias1])

net = caffe.Net('path/to/conv.prototxt', caffe.TEST)

net.params['conv_1'][0].data[...] = conv_w1
net.params['conv_1'][1].data[...] = bias_1

...

net.save('modelfromtf.caffemodel')

注1:此代码已经过 NOT 测试。我不确定这是否有效,但我认为应该如此。此外,这仅适用于一个转换层。实际上,您必须首先分析张量流检查点,以检查哪个图层权重在哪个索引处(print all_vars ),然后分别复制每个图层的权重。

注2:某些自动化可以通过迭代初始转换层来完成,因为它们通常遵循设定模式(conv1-> bn1-> relu1-> conv2-> bn2-> relu2 ......)

注3:Tensorflow可以进一步将每个层权重划分为单独的索引。例如:权重偏见是针对conv层分开的,如上所示。此外, gamma mean variance 分离为批量规范化层。

答案 2 :(得分:0)

您可以使用Microsoft开发的实用程序MMDNN。 MMdnn是一个综合的跨框架工具,用于转换,可视化和诊断深度学习(DL)模型。