我希望能够将Tensorflow模型转换为Caffe模型。
我在谷歌上搜索,但我只能找到从caffe到tensorflow的转换器,但没有相反的结果。
有没有人知道怎么做?
谢谢,艾维
发布于 2018-04-05 08:39:39
我也遇到过同样的问题,并找到了解决方案。代码可以在这里(https://github.com/lFatality/tensorflow2caffe)找到,我还在Youtube的一些视频中记录了代码。
在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。我在TensorBoard的图表中找到了这些名字。如果您在体系结构定义中命名这些层,则这些layer_names可能会更改为您定义的名称。
在原生TensorFlow中,导出需要不同的代码,但是参数的格式应该是相同的,因此后续步骤应该仍然适用。
Part 3涵盖了实际的转换。关键是在创建咖啡因模型时权重的转换(偏差可以在不更改的情况下进行)。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))。3,2,0,1序列可以通过枚举TensorFlow格式(源),然后将其切换为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 filters是number of units in the fc-layer)。在此之后,您可以使用之前使用的转置转换,然后再次调整数组的形状,但情况正好相反。TensorFlow将fc层权重保存为[number of inputs, number of outputs],而Caffe则相反。
如果将两个fc层彼此连接,则不必执行前面描述的复杂过程,但必须通过再次转置(fc_layer_weights.transpose((1,0)))来考虑不同的fc层格式
然后,可以使用设置网络的参数
net.params['layer_name_in_prototxt'][0].data[...] = weights
net.params['layer_name_in_prototxt'][1].data[...] = biases这是一个简单的概述。如果你想要所有的代码,它在我的github存储库中。我希望它能帮上忙。:)
干杯,
致命性
发布于 2017-09-12 01:51:19
正如@Patwie在评论中建议的那样,您必须通过逐层复制权重来手动完成此操作。例如,要将第一个conv层权重从tensorflow检查点复制到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')Note1:此代码尚未经过测试。我不确定这是否会起作用,但我认为它应该会起作用。此外,这仅适用于一个转换层。在实践中,您必须首先分析tensorflow检查点,以检查哪个层的权重位于哪个索引(打印all_vars),然后分别复制每个层的权重。
Note2:一些自动化可以通过迭代初始的conv层来完成,因为它们通常遵循一个设置的模式(Note2->bn1->relu1->conv2->bn2->relu2...)
Note3: Tensorflow可以进一步将每层权重划分为单独的索引。例如:如上所示,对于一个圆锥层,权重和偏移是分开的。此外,对于批量归一化层,伽马、均值和方差被分离。
发布于 2020-12-18 16:32:35
您可以使用微软开发的实用程序MMDNN。MMdnn是一个全面的跨框架工具,用于转换、可视化和诊断深度学习(DL)模型。
https://stackoverflow.com/questions/41138481
复制相似问题