YOLOv3_TensorFlow
YOLOv3_TensorFlow copied to clipboard
about freeze graph and convert TFlite problem
Hi, thank you so much for sharing your code! I have some questions and hope you could help me.I try to freeze graph and convert *.pb to TFlite model, so that can transport to Android mobile phones.This is my source code as follow:
But,I get a unsupported operation error as shown below:
b'2019-01-29 16:12:22.550452: I tensorflow/contrib/lite/toco/import_tensorflow.cc:1080] Converting unsupported operation: ResizeNearestNeighbor\n
Yes, about TFlite unsupported operation error,Could you help how to modify the yolov3 source code to support operation?
This is my source code as follow: `
--coding: utf-8 --
""" @Project: tensorflow-yolov3 @File : freeze.py @Author : panjq @E-mail : [email protected] @Date : 2019-01-22 18:39:28 """
import os import time import numpy as np import tensorflow as tf import cv2 from utils.nms_utils import gpu_nms from utils.misc_utils import parse_anchors, read_class_names import tensorflow.contrib.lite as lite from utils.plot_utils import get_color_table, plot_one_box from model import yolov3
def show_image(img_ori,boxes_,scores_,classes,num_class,labels_,width_ori,height_ori,new_size): # rescale the coordinates to the original image color_table = get_color_table(num_class) boxes_[:, 0] *= (width_ori / float(new_size[0])) boxes_[:, 2] *= (width_ori / float(new_size[0])) boxes_[:, 1] *= (height_ori / float(new_size[1])) boxes_[:, 3] *= (height_ori / float(new_size[1]))
print("box coords:")
print(boxes_)
print('*' * 30)
print("scores:")
print(scores_)
print('*' * 30)
print("labels:")
print(labels_)
for i in range(len(boxes_)):
x0, y0, x1, y1 = boxes_[i]
scores=scores_[i]
plot_one_box(img_ori, [x0, y0, x1, y1], label=classes[labels_[i]]+':'+str(scores)[:6], color=color_table[labels_[i]])
cv2.imshow('Detection result', img_ori)
# cv2.imwrite('detection_result.jpg', img_ori)
cv2.waitKey(30)
def read_pb_return_tensors(pb_file, return_elements): with tf.gfile.FastGFile(pb_file, 'rb') as f: frozen_graph_def = tf.GraphDef() frozen_graph_def.ParseFromString(f.read()) return_elements = tf.import_graph_def(frozen_graph_def, return_elements=return_elements) input_tensor, output_tensors = return_elements[0], return_elements[1:] return input_tensor, output_tensors
def freeze(sess, output_file, output_node_names):
output_graph_def = tf.graph_util.convert_variables_to_constants(
sess,
sess.graph.as_graph_def(),
output_node_names,
)
with tf.gfile.GFile(output_file, "wb") as f:
f.write(output_graph_def.SerializeToString())
print("=> {} ops written to {}.".format(len(output_graph_def.node), output_file))
def freeze_graph(): # input_checkpoint = 'checkpoint/yolov3.ckpt-99' # cpu_pb_path='checkpoint/yolov3.pb' ckpt_path = "./data/darknet_weights/yolov3.ckpt" pb_path= "./data/darknet_weights/yolov3.pb" # 指定输出的节点名称,该节点名称必须是原模型中存在的节点 output_node_names = ["yolov3/yolov3_head/feature_map_1", "yolov3/yolov3_head/feature_map_2", 'yolov3/yolov3_head/feature_map_3'] saver = tf.train.import_meta_graph(ckpt_path + '.meta', clear_devices=True) with tf.Session() as sess: saver.restore(sess, ckpt_path) # 恢复图并得到数据 for op in sess.graph.get_operations(): print(op.name, op.values()) freeze(sess, pb_path, output_node_names)
def get_feature_map(input_image,pb_path): # 定义一个计算图graph,获得feature_map input_node_names = ["Placeholder:0"] output_node_names = ["yolov3/yolov3_head/feature_map_1:0", "yolov3/yolov3_head/feature_map_2:0", 'yolov3/yolov3_head/feature_map_3:0'] graph=tf.Graph() with graph.as_default(): input_tensor, output_tensors = read_pb_return_tensors(pb_path,input_node_names+output_node_names) with tf.Session(graph=graph) as sess: feature_map= sess.run(output_tensors, feed_dict={input_tensor: input_image}) return feature_map
def pb_test_tf(img_ori,feature_map,classes,num_class,anchors,score_threshold,iou_threshold): ''' :param img_ori: :param feature_map: :param classes: :param num_class: :param anchors: :param score_threshold: :param iou_threshold: :return: ''' height_ori, width_ori = img_ori.shape[:2] img_size = [416, 416] # 定义一个计算图graph,获得输出结果: graph = tf.Graph() with graph.as_default(): feature_map_1, feature_map_2, feature_map_3 = feature_map feature_map_1 = tf.constant(feature_map_1, dtype=tf.float32) feature_map_2 = tf.constant(feature_map_2, dtype=tf.float32) feature_map_3 = tf.constant(feature_map_3, dtype=tf.float32) tf_img_size = tf.constant(value=img_size, dtype=tf.int32) print("img_size:{}".format(img_size))
# model = yolov3FeatureMap.tf_yolov3FeatureMap(num_classes=num_classes, anchors=anchors)
yolo_model = yolov3(num_class, anchors)
with tf.Session(graph=graph) as sess:
pred_boxes, pred_confs, pred_probs = yolo_model.predict2(feature_map_1, feature_map_2, feature_map_3,tf_img_size)
pred_scores = pred_confs * pred_probs
boxes, scores, labels = gpu_nms(pred_boxes, pred_scores, num_class, max_boxes=30, score_thresh=score_threshold,
iou_thresh=iou_threshold)
# saver = tf.train.Saver()
# saver.restore(sess, ckpt_path)
boxes_, scores_, labels_ = sess.run([boxes, scores, labels])
show_image(img_ori, boxes_, scores_, classes, num_class, labels_, width_ori, height_ori,
img_size)
def freeze_graph_test(): image_path = './data/demo_data/dog.jpg' anchor_path = "./data/yolo_anchors.txt" input_size = [416, 416] class_name_path = "./data/coco.names" pb_path= "./data/darknet_weights/yolov3.pb" score_threshold = 0.5 iou_threshold = 0.5
anchors = parse_anchors(anchor_path)
classes = read_class_names(class_name_path)
num_class = len(classes)
# 读取图像数据
img_ori = cv2.imread(image_path)
img_resized = cv2.resize(img_ori, tuple(input_size))
img_resized = cv2.cvtColor(img_resized, cv2.COLOR_BGR2RGB)
img_resized = np.asarray(img_resized, np.float32)
img_resized = img_resized[np.newaxis, :] / 255.
feature_map = get_feature_map(img_resized, pb_path)
pb_test_tf(img_ori, feature_map, classes, num_class, anchors, score_threshold, iou_threshold)
def convert_tflite(): pb_path= "./data/darknet_weights/yolov3.pb" out_tflite ='./data/darknet_weights/converted_model.tflite' SIZE=416 input_arrays = ['Placeholder'] output_node_names = ["yolov3/yolov3_head/feature_map_1", "yolov3/yolov3_head/feature_map_2", 'yolov3/yolov3_head/feature_map_3'] input_shapes = {"Placeholder": [1, SIZE, SIZE, 3]} converter = lite.TFLiteConverter.from_frozen_graph( pb_path, input_arrays, output_node_names, input_shapes) tflite_model = converter.convert() open(out_tflite, "wb").write(tflite_model)
if name == 'main': freeze_graph() print("freeze_graph done...") freeze_graph_test() print("freeze_graph_test done...") convert_tflite() print("convert_tflite done...")
`
Hi, I guess in your TFlite version, ResizeNearestNeighbor of tf.image module has not been supported. According to this Link, you can try newer tflite version. Or you may change this line to other resize functions in tf.image module, please refer to link and have a try.
@PanJinquan Can you please send code for freeze graph. The indentations are not proper above. And were you successful in converting the model to tflite? Please help. I am currently struggling to export model to tflite.
How do get the input node as Placeholder:0
? I use that code to freeze the model but when I test it I got the error ValueError: Requested return tensor 'Placeholder:0' not found in graph def
, thanks!
@yuanzhedong Hi, you can refer to my answer in stackoverflow https://stackoverflow.com/a/49768479/6631854 to get the correct placeholder name.
@wizyoung Thanks for the help!
After running your example I do find Placeholder
in the graph, the shape is 1, -1, -1
:
name: "phase_train"
op: "Placeholder"
attr {
key: "dtype"
value {
type: DT_BOOL
}
}
attr {
key: "shape"
value {
shape {
unknown_rank: true
}
}
}
name: "iterator_handle_flag"
op: "Placeholder"
attr {
key: "dtype"
value {
type: DT_STRING
}
}
attr {
key: "shape"
value {
shape {
}
}
}
name: "Placeholder"
op: "Placeholder"
attr {
key: "dtype"
value {
type: DT_FLOAT
}
}
attr {
key: "shape"
value {
shape {
dim {
size: 1
}
dim {
size: -1
}
dim {
size: -1
}
}
}
}
Here're all the placehoders:
[<tf.Operation 'phase_train' type=Placeholder>, <tf.Operation 'iterator_handle_flag' type=Placeholder>, <tf.Operation 'Placeholder' type=Placeholder>, <tf.Operation 'Placeholder_1' type=Placeholder>, <tf.Operation 'phase_train_1' type=Placeholder>, <tf.Operation 'iterator_handle_flag_1' type=Placeholder>, <tf.Operation 'Placeholder_2' type=Placeholder>, <tf.Operation 'Placeholder_1_1' type=Placeholder>, <tf.Operation 'phase_train_2' type=Placeholder>, <tf.Operation 'iterator_handle_flag_2' type=Placeholder>, <tf.Operation 'Placeholder_3' type=Placeholder>, <tf.Operation 'Placeholder_1_2' type=Placeholder>]
But after I freeze it I can't find the placeholder from the pb file:
code:
import tensorflow as tf
gf = tf.GraphDef()
gf.ParseFromString(open('./to_freeze/model.pb','rb').read())
print([n.name + '=>' + n.op for n in gf.node if n.op in ('Placeholder')])
output:
['phase_train=>Placeholder']
@yuanzhedong @wizyoung any news on this one? I am having the same error:
Merge/MergeSummary (<tf.Tensor 'Merge/MergeSummary:0' shape=() dtype=string>,) => 2243 ops written to ./. ['phase_train=>Placeholder'] freeze_graph done... WARNING:tensorflow:From freeze_graph.py:90: FastGFile.init (from tensorflow.python.platform.gfile) is deprecated and will be removed in a future version. Instructions for updating: Use tf.gfile.GFile. Traceback (most recent call last): File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/importer.py", line 418, in import_graph_def graph._c_graph, serialized, options) # pylint: disable=protected-access tensorflow.python.framework.errors_impl.InvalidArgumentError: Requested return node 'Placeholder' not found in graph def
When I change freeze_graph to load the model before as in
with tf.name_scope('input'):
input_data = tf.placeholder(dtype=tf.float32, shape=[ 1, input_shape[0], input_shape[1], 3], name='input_data')
model = yolov3(len(classes), anchors)
with tf.variable_scope('yolov3'):
feature_map = model.forward(input_data)
sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True))
saver = tf.train.Saver()
saver.restore(sess, FLAGS.trained_checkpoint_prefix)
# the op name of the Placeholder changes in different TensorFlow versions.
# To find out the correct placeholder op name in the Graphdef part of the .meta file:
imported_graph = tf.get_default_graph()
graph_op = imported_graph.get_operations()
with open(FLAGS.output_directory + 'graphdef_output.txt', 'w') as f:
for i in graph_op:
f.write(str(i))
output_node_names = ["yolov3/yolov3_head/feature_map_1", "yolov3/yolov3_head/feature_map_2", 'yolov3/yolov3_head/feature_map_3']
freeze(sess, FLAGS.output_directory, output_node_names)
my output.txt looks better, but I now get the placeholder ['input/input_data=>Placeholder']
Hey everyone, I took the following steps:
- Change the
utils/nms_utils.py
lines 53-55 to:
boxes = tf.concat(boxes_list, axis=0, name='output/box_output')
score = tf.concat(score_list, axis=0, name='output/score_output')
label = tf.concat(label_list, axis=0, name='output/label_output')
Hope this helps!
Hey everyone, I took the following steps:
- Change the
utils/nms_utils.py
lines 53-55 to:boxes = tf.concat(boxes_list, axis=0, name='output/box_output') score = tf.concat(score_list, axis=0, name='output/score_output') label = tf.concat(label_list, axis=0, name='output/label_output')
Hope this helps!
If I did not change the utils/nms_utils.py lines 53-55 at the training phase, will it work?
After frozen to pb file, the model still takes over 5 Gb on GPU. Is it normal?
hello,can you tell me the out_node and input nodes,I think the output nodes are:yolov3/yolov3_head/feature_map_2", 'yolov3/yolov3_head/feature_map_3 But I don't know the input nodes?Help.....
https://lutzroeder.github.io/netron/ Maybe can use this to find it.
@wizyoung @omarabid59 @PanJinquan Can anyone guide me how to use tflite to test image or video ? (I maybe success to convert it to tflite) What should I modify in test_single_image.py?
请问有从rtsp流每隔n帧跑yolov3检测实时人数的脚本吗?
@wizyoung @omarabid59 @PanJinquan Can anyone guide me how to use tflite to test image or video ? (I maybe success to convert it to tflite) What should I modify in test_single_image.py?
I already success. Thanks.
@aluds123 could you share here how you able to achieve it?
hello,can you tell me the out_node and input nodes,I think the output nodes are:yolov3/yolov3_head/feature_map_2", 'yolov3/yolov3_head/feature_map_3 But I don't know the input nodes?Help.....
i got the same problems,had you solved it?
Hi, @BalajiB197 This is a part of code to convert .ckpt to .pb:
frozen_graph_def = graph_util.convert_variables_to_constants( sess, sess.graph_def, ["yolov3/yolov3_head/feature_map_1","yolov3/yolov3_head/feature_map_2","yolov3/yolov3_head/feature_map_3"]) tf.train.write_graph( frozen_graph_def, os.path.dirname(output_file), os.path.basename(output_file), as_text=False) tf.logging.info('Saved frozen graph to %s',output_file)
And I use toco to convert .pb to .tflite:
toco tflite_convert --graph_def_file=abc.pb --output_file=abc.tflite --input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE --inference_type=QUANTIZED_UINT8 --input_shape="1,416, 416,3" --input_array=input_data --output_array=yolov3/yolov3_head/feature_map_1,yolov3/yolov3_head/feature_map_2,yolov3/yolov3_head/feature_map_3 --mean_values 0 --std_dev_values 255 --default_ranges_min 0 --default_ranges_max 6 (I use quantization aware training, so you should modify some parameter like "input_format", "inference_type" .......)
@PanJinquan @aluds123 I have already get pb file but I do not know how to test it. From code above, I select some code.
def freeze_graph_test():
image_path = './data/demo_data/dog.jpg'
anchor_path = "./data/yolo_anchors.txt"
input_size = [416, 416]
class_name_path = "./data/coco.names"
pb_path= "./data/darknet_weights/yolov3.pb"
score_threshold = 0.5
iou_threshold = 0.5
anchors = parse_anchors(anchor_path)
classes = read_class_names(class_name_path)
num_class = len(classes)
# 读取图像数据
img_ori = cv2.imread(image_path)
img_resized = cv2.resize(img_ori, tuple(input_size))
img_resized = cv2.cvtColor(img_resized, cv2.COLOR_BGR2RGB)
img_resized = np.asarray(img_resized, np.float32)
img_resized = img_resized[np.newaxis, :] / 255.
feature_map = get_feature_map(img_resized, pb_path)
pb_test_tf(img_ori, feature_map, classes, num_class, anchors, score_threshold, iou_threshold)
def pb_test_tf(img_ori,feature_map,classes,num_class,anchors,score_threshold,iou_threshold):
'''
:param img_ori:
:param feature_map:
:param classes:
:param num_class:
:param anchors:
:param score_threshold:
:param iou_threshold:
:return:
'''
height_ori, width_ori = img_ori.shape[:2]
img_size = [416, 416]
# 定义一个计算图graph,获得输出结果:
graph = tf.Graph()
with graph.as_default():
feature_map_1, feature_map_2, feature_map_3 = feature_map
feature_map_1 = tf.constant(feature_map_1, dtype=tf.float32)
feature_map_2 = tf.constant(feature_map_2, dtype=tf.float32)
feature_map_3 = tf.constant(feature_map_3, dtype=tf.float32)
tf_img_size = tf.constant(value=img_size, dtype=tf.int32)
print("img_size:{}".format(img_size))
# model = yolov3FeatureMap.tf_yolov3FeatureMap(num_classes=num_classes, anchors=anchors)
yolo_model = yolov3(num_class, anchors)
with tf.Session(graph=graph) as sess:
pred_boxes, pred_confs, pred_probs = yolo_model.predict2(feature_map_1, feature_map_2, feature_map_3,tf_img_size)
pred_scores = pred_confs * pred_probs
boxes, scores, labels = gpu_nms(pred_boxes, pred_scores, num_class, max_boxes=30, score_thresh=score_threshold,
iou_thresh=iou_threshold)
# saver = tf.train.Saver()
# saver.restore(sess, ckpt_path)
boxes_, scores_, labels_ = sess.run([boxes, scores, labels])
show_image(img_ori, boxes_, scores_, classes, num_class, labels_, width_ori, height_ori,
img_size)
def show_image(img_ori,boxes_,scores_,classes,num_class,labels_,width_ori,height_ori,new_size):
# rescale the coordinates to the original image
color_table = get_color_table(num_class)
boxes_[:, 0] *= (width_ori / float(new_size[0]))
boxes_[:, 2] *= (width_ori / float(new_size[0]))
boxes_[:, 1] *= (height_ori / float(new_size[1]))
boxes_[:, 3] *= (height_ori / float(new_size[1]))
print("box coords:")
print(boxes_)
print('*' * 30)
print("scores:")
print(scores_)
print('*' * 30)
print("labels:")
print(labels_)
for i in range(len(boxes_)):
x0, y0, x1, y1 = boxes_[i]
scores=scores_[i]
plot_one_box(img_ori, [x0, y0, x1, y1], label=classes[labels_[i]]+':'+str(scores)[:6], color=color_table[labels_[i]])
cv2.imshow('Detection result', img_ori)
# cv2.imwrite('detection_result.jpg', img_ori)
cv2.waitKey(30)
In function pb_test_tf()
yolo_model = yolov3(num_class, anchors)
pred_boxes, pred_confs, pred_probs = yolo_model.predict2(feature_map_1, feature_map_2, feature_map_3,tf_img_size)
It still uses yolov3 net structure, but it is known to us all that when inference with pb file, we do not need net structure. What we need are pb file, input_node_name(s) and out_put_name(s). Here is a sample code about using pb for inference. https://github.com/github2016-yuan/tensorflow-yolov3/blob/master/image_demo.py Need your help.