记录opencv调用自己训练的tensorflow模型过程中遇到的问题!
一、opencv调用tensorflow节点类型有点苛刻,目前发现不支持如下节点:
1.图像预处理(像素值归一化过程中)的加、减、乘、除等节点,所以图里面包含这些节点的pb文件,opencv是无法加载的,训练的时候只能在读取图像是用opencv的方法处理图像,不能用tf.subtract(),或者 tf.div()等tf的操作,如果在图中有这些节点,opencv调用pb文件的时候会报这样的错误!,如下:
OpenCV(3.4.1) Error: Unspecified error (Unknown layer type Sub in op Sub) in cv::dnn::experimental_dnn_v4::`anonymous-namespace'::TFImporter::populateNet, file C:\Program Files\opencv\sources\modules\dnn\src\tensorflow\tf_importer.cpp, line 1582
2.也不能添加tf.argmax()这样的节点,会报和“1”一样错误。解决办法是不能留这样的节点在图中。
二、综上可以知道,opencv调用tensorflow模型需要去除开头的图像预处理,和结尾argmax操作。
在过程中使用一些小工具记录一下:
1.ckpt转pb文件
from tensorflow.python.framework import graph_util
import tensorflow as tf
out_path='F:/A_Projoct-Python/Camera failure/Camera failure/model_2/'
with tf.Session() as sess:
# Load .ckpt file
ckpt_path ='F:/A_Projoct-Python/Camera failure/Camera failure/model_2/model.ckpt-0'
saver = tf.train.import_meta_graph(ckpt_path + '.meta')
saver.restore(sess, ckpt_path)
# Save as .pb file
graph_def = tf.get_default_graph().as_graph_def()
output_graph_def = graph_util.convert_variables_to_constants( sess, graph_def, ['classes'])
with tf.gfile.GFile(out_path+'pb_model_0_no_image_preprocess_class.pb', 'wb') as fid:
serialized_graph = output_graph_def.SerializeToString()
fid.write(serialized_graph)
2.查看pb类型文件的节点名
import tensorflow as tf
import os
#model_dir = './'
out_path='F:/A_Projoct-Python/Camera failure/Camera failure/model_2/'
model_name = 'pb_model_0_no_image_preprocess_class.pb'
def create_graph():
with tf.gfile.FastGFile(os.path.join(out_path+ model_name), 'rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
tf.import_graph_def(graph_def, name='')
create_graph()
tensor_name_list = [tensor.name for tensor in tf.get_default_graph().as_graph_def().node]
for tensor_name in tensor_name_list:
print(tensor_name,'\n')
可以查看是不是有div、sub、和argmax节点。如果有这些节点的话,opencv3.4.0是没办法加载模型的。