海思AI芯片(HI35xx):tensorflow转caffemodel之两种框架下模型中变量名与层名之间的对应关系(映射关系)

摘要:
要把自己的模型进行移植,后端的移植,前端的移植,前端一般都是用海思芯片(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

结构展示
海思AI芯片(HI35xx):tensorflow转caffemodel之两种框架下模型中变量名与层名之间的对应关系(映射关系)
caffe_yolov3_prama.txt如下:
海思AI芯片(HI35xx):tensorflow转caffemodel之两种框架下模型中变量名与层名之间的对应关系(映射关系)
可能报错:

AttributeError: ‘collections.OrderedDict’ object has no attribute ‘iteritems’
如下图所示:
海思AI芯片(HI35xx):tensorflow转caffemodel之两种框架下模型中变量名与层名之间的对应关系(映射关系)
问题分析:
错误代码: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对比
如下图所示:
海思AI芯片(HI35xx):tensorflow转caffemodel之两种框架下模型中变量名与层名之间的对应关系(映射关系)

上一篇:海思AI芯片(HI35xx):tensorflow转caffemodel之caffe和tensoflow结构参数的差异


下一篇:2021 年最新版 Ubuntu 20.04 配置 Caffe 深度学习环境