资讯动态

【深度学习】Caffe: tensorflow的模型到底怎么转成caffemodel??(完整的流程+代码讲解)

发布时间:2026/10/22 12:21:58 来源:尧图企业网站定制
tensorflow的模型到底怎么转成caffemodel1. 简介一般情况下LZ是使用tensorflow的好像之前在学校只要python跑通benchmark再刷高一点就行了。现在在公司要把自己的模型进行移植之前是后端的移植最近前端也提了需求前端一般都是用海思芯片只支持caffe所以为了先测试时间得把tf的模型转成caffemodel。程序猿总有不会的总有要学习的不是嘛然后在网上搜索了很久发现有些教程实在有些复杂今天就以一个简单的网络结构为例进行记录。说明这个网络中只包含卷积层和全连接层后续碰到其他层会继续补充。2. tensorflow模型准备转换模型的第一步是不是得先准备个tensorflow的模型没模型可以先随便训练个有点参数和输出结果就行。经过训练后得到了对应的ckpt模型因为后续要使用pycaffe搭建对应的网络所以我们还得先查看下模型的名称importnumpyasnpimporttensorflowastf#输出变量名和对应的参数withtf.Session()assess:savertf.compat.v1.train.import_meta_graph(../models/model.ckpt.meta)saver.restore(sess,tf.train.latest_checkpoint(../models/))forvarintf.compat.v1.trainable_variables():print(*************************************)print(var.name)# print(np.array(sess.run(var)))这段代码的目的就是为了看下保存的模型名称当然如果把最后一行反注释可以看到对应训练得到的weights和biases所以对于一个公司来说模型是非常重要的在后端实际场景使用中还会转成pb模型并进行加密这样即使对方得到了你的pb文件也没法反解出对应的参数但是如果是ckpt可以看到查出网络结构和参数非常容易。3. 生成对应的prototxt文件之前因为不熟悉都是单纯手动写prototxt实在是太傻了pycaffe可以轻松解决这个问题。先写出主要的框架importcaffe# 定义你的caffe网络结构defdeploy():# 定义你的输入数据data_imgcaffe.layers.Input(shapedict(dim[1,3,102,102]))# 定义你的网络结构# 网络结构要和你的tf模型完全一致为了后续load参数方便最好每层名字也对应一致...returncaffe.to_proto(out)# 定义一个函数将网络结构写入到对应的prototxt中defwrite_deploy():withopen(your_model.prototxt,w)asf:f.write(name:model_name\n)f.write(str(deploy()))if__name____main__:write_deploy()4. 读取对应参数值并生成对应的caffemodel这个时候既需要tensorflow的接口又需要caffe的接口了生成prototxt的时候我们已经获得了对应的网络结构了下面只需要将对应的参数保存到caffe的params中就可以了# load tf model_parametersimporttensorflowastfimportnumpyasnpimportcaffedefgenerate_caffe_model():cf_prototxtyour_model.prototxtcf_modelyour_model.caffemodel# 定义自己的netnetcaffe.Net(cf_prototxt,caffe.TEST)withtf.Session()assess:# 导入tf的网络结构和变量名称savertf.train.import_meta_graph(../models/model.ckpt.meta,clear_devicesTrue)saver.restore(sess,tf.train.latest_checkpoint(../models/))all_varstf.trainable_variables()# 针对不同变量存储对应的参数forvarinall_vars:namevar.name v_paramnp.array(sess.run(var))print(*********************************)# print(name, v_param.ndim, v_param.shape)ifweightsinname:layer_namename[:-10]#.strip(/weights:0)print(layer_name)ifv_param.ndim4:v_4dnp.transpose(v_param,[3,2,0,1])net.params[layer_name][0].data[...]v_4dprint(conv weights {} succefully.format(layer_name))else:v_2dnp.transpose(v_param,[1,0])net.params[layer_name][0].data[...]v_2dprint(fc weights {} succefully.format(layer_name))elifbiasesinname:layer_namename[:-9]#.strip(/biases:0)net.params[layer_name][1].data[...]v_paramprint({} biases succefully.format(layer_name))else:print(please check if something wrong !)continue# 保存caffemodelnet.save(cf_model)print(\n -- Finished. -- \n)转换的时候其实有好几个注意点。a. 卷积tensorflow卷积参数的存储方式是kernel_h, kernel_w, input_channel, output_channelcaffe卷积参数的存储方式是output_channel, input_channel, kernel_h, kernel_w卷积的存储权重和偏差的位置权重存储的位置为conv_params[conv][0]偏差存储的位置为conv_params[conv][1]b. 全连接tensorflow全连接参数的存储方式是input_dim, output_dimcaffe全连接参数存储方式是output_dim, input_dim全连接的存储权重和偏差的位置权重存储的位置为conv_params[fc][0]偏差存储的位置为conv_params[fc][1]5. 验证模型转换是否成功这时就需要使用tensorflow模型和caffe模型inference后的结果对比caffe模型做deploy的代码框架# inference partimportcaffeimportcv2# some preprocess operationdefpreprocess(img):#定义一些预处理操作尽量和tensorflow的预处理方式保持一致returnimgdefdeploy_part():net_fileyour_model.prototxtcaffe_modelyour_model.caffemodeltest_dirtest.bmp# 定义对应的网络netcaffe.Net(net_file,caffe_model,caffe.TEST)imgcv2.imread(test_dir)imgpreprocess(img)imgimg.transpose((2,0,1))net.blobs[Input1].data[...]img outnet.forward()print(out)if__name____main__:deploy_part()这里还有一个问题需要注意的是tensorflow的数据格式一般都是N HW C的方式而在caffe中是N C H Wopencv读入图片的格式为H W C所以在传入数据时需要使用transpose进行转换。这个tensorflow inference后得到的结果这个是caffe deploy后得到的结果从上面两个图中可以看到两者结果的差异体现在小数点后第8位并且这是最后数据的结果基本上结果差异非常的小。对于tensorflow转caffemodel不知道小伙伴们有没有清楚一些呢

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑