摘要:
要把自己的模型進行移植,後端的移植,前端的移植,前端一般都是用海思芯片(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對比
如下圖所示: