摘要:
要把自己的模型进行移植,后端的移植,前端的移植,前端一般都是用海思芯片(Hi3516DV300),只支持caffe,所以为了先测试时间得把tf的模型转成caffemodel。这里是将tf1.x转为caffemode,后续补全darknet转为caffemode
一、查看caffe每一层的参数结构
代码:
# python3
caffe_root = '/home/qif/smf/caffe/' #这是你自己安装caffe的路径
import sys
sys.path.insert(0, caffe_root + 'python')
import caffe
deploy_proto = r"./yolov3_deploy.prototxt"
caffe_model = r"./yolov3_helmet.caffemodel"
net = caffe.Net(deploy_proto, caffe_model, caffe.TEST)
with open("caffe_yolov3_prama.txt", "w") as fw:
# 注意python2与python3的区别,如果是python2,则将net.params.items()改为:net.params.iteritems()
for layer_name, param in net.params.items():
# print(layer_name + ": " + str(len(param)))
for i in range(len(param)):
info_str = layer_name + ': ' + str(i) + "/" + str(len(param)) + str(param[i].data.shape) + str(param[i].data.ndim)
print(info_str)
fw.write(info_str + "\n")
fw.write(str(param[i].data))
fw.write("\n\n")
第i次循环体内部
layer_name提取的是net的第i层的名称
param提取的是net的第i层的参数
在test.py所在文件夹下打开终端:
sudo python3 test.py
结构展示
caffe_yolov3_prama.txt如下:
可能报错:
AttributeError: ‘collections.OrderedDict’ object has no attribute ‘iteritems’
如下图所示:
问题分析:
错误代码:for layer_name, param in net.params.iteritems():
错误描述:AttributeError: ‘collections.OrderedDict’ object has no attribute ‘iteritems’
原因:python3中用items()代替python2中的iteritems(),同理还有iterkeys等,都需要去掉iter前缀
正确代码:for layer_name, param in net.params.items():
查看CNN各层的activations值的结构(即每一层的输出)
# 显示每一层
for layer_name, blob in net.blobs.iteritems():
print layer_name + '\t' + str(blob.data.shape)
第i次循环体内部
layer_name提取的是net的第i层的名称
blob提取的是net的第i层的输出数据(4d)
二、查看tensorflow1.x每一层的参数结构与变量值
首先要对tensorflow模型有个初步的了解:
tensorflow通过tf.train.Saver()实现模型的保存和提取,其中的save方法将模型保存到指定路径,在目标路径下会形成四个文件:
其中:
(1) checkpoint 文本文件,记录了模型文件的路径信息列表
(2) model.ckpt.data-00000-of-00001 记录了网络权重信息
(3) model.ckpt.index 保存了模型中的参数索引
(4) model.ckpt.meta 二进制文件,保存了模型的计算图结构信息(模型的网络结构)
因此在提取参数的时候,在meta中找到参数名,然后通过index,从数据中提取数据具体的值.
代码:
import tensorflow as tf
# checkpoint为模型保存地址
checkpoint_path = './models'
with open("tf_yolov3_prama.txt", "w") as fw:
# 得到checkpoint文件中所有的参数(名字,形状)元组
for var_name, varshape in tf.contrib.framework.list_variables(checkpoint_path):
# 得到上述参数的值
var = tf.contrib.framework.load_variable(checkpoint_path, var_name)
# var_name为变量的name scope
# var 是该name scope对应的值
info_str = str(var_name) +":" +str(varshape) + "\n"
fw.write(info_str)
fw.write(str(var) + "\n" + "\n")
print(var_name," : ",varshape)
print(var)
上面这段代码将输出的是全部的变量,比如weights,biases, BN层的均值和方差,Scale层的gamma和beta
import numpy as np
import tensorflow as tf
#输出变量名和对应的参数
with tf.Session() as sess:
saver = tf.compat.v1.train.import_meta_graph('./models/*.meta')
saver.restore(sess, tf.train.latest_checkpoint('./models/'))
for var in tf.compat.v1.trainable_variables(): # 打印出来的时候,可训练的变量
print("*************************************")
print(var.name) # 变量名字
print(np.array(sess.run(var))) #变量的值
上面这段代码将输出的是可训练的变量,比如weights,biases, Scale层的gamma和beta
上面两端代码的目的就是为了看下保存的模型名称,所以对于一个公司来说,模型是非常重要的,在后端实际场景使用中还会转成pb模型并进行加密,这样即使对方得到了你的pb文件,也没法反解出对应的参数,但是如果是ckpt,可以看到查出网络结构和参数非常容易。
三、两个框架下,生成的参数txt对比
如下图所示: