Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text graph for MobileNet-SSD from TensorFlow #387

Merged
merged 1 commit into from Oct 10, 2017
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
@@ -0,0 +1,19 @@
node {
name: "input"
op: "Placeholder"
}
node {
name: "batch_norm"
op: "FusedBatchNorm"
input: "input"
input: "batch_norm/gamma"
input: "batch_norm/beta"
input: "batch_norm/moving_mean"
input: "batch_norm/moving_variance"
attr {
key: "epsilon"
value {
f: 0.0010000000475
}
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,9 @@
node {
name: "input"
op: "Placeholder"
}
node {
name: "flatten"
op: "Flatten"
input: "input"
}
Binary file not shown.
@@ -3,6 +3,7 @@
import os
import argparse
import struct
import cv2 as cv
from prepare_for_dnn import prepare_for_dnn

parser = argparse.ArgumentParser(description='Script for OpenCV\'s DNN module '
@@ -242,16 +243,73 @@ def my_dropout(x):
scaled = tf.image.resize_nearest_neighbor(scaled, size=(9, 12))
save(inp, scaled, 'resize_nearest_neighbor')
################################################################################
inp = tf.placeholder(tf.float32, [1, 2, 3, 4], 'input')
bn = tf.layers.batch_normalization(inp, training=isTraining, fused=False, name='batch_norm',
beta_initializer=tf.random_normal_initializer(),
gamma_initializer=tf.random_normal_initializer(),
moving_mean_initializer=tf.random_uniform_initializer(-2, 1),
moving_variance_initializer=tf.random_uniform_initializer(0.1, 2),)
save(inp, bn, 'batch_norm_text')
# Override the graph by a frozen one.
os.rename('frozen_graph.pb', 'batch_norm_text_net.pb')
################################################################################
inp = tf.placeholder(tf.float32, [2, 4, 5], 'input')
flatten = tf.contrib.layers.flatten(inp)
save(inp, flatten, 'flatten')
################################################################################
# Generate test data for MobileNet-SSD object detection model from TensorFlow
# model zoo, https://github.com/tensorflow/models/tree/master/research/object_detection
# 1. Download and extract ssd_mobilenet_v1_coco.tar.gz
# 2. Place frozen_inference_graph.pb as a ssd_mobilenet_v1_coco.pb nearby this script
with tf.gfile.FastGFile('../ssd_mobilenet_v1_coco.pb') as f:
# Load the model
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())

with tf.Session() as sess:
# Restore session
sess.graph.as_default()
tf.import_graph_def(graph_def, name='')

# Receive output
inp = cv.imread('../street.png')
inp = cv.resize(inp, (300, 300))
inp = inp[:, :, [2, 1, 0]] # BGR2RGB
out = sess.run([sess.graph.get_tensor_by_name('concat:0'), # All detections
sess.graph.get_tensor_by_name('concat_1:0'), # Classification
sess.graph.get_tensor_by_name('num_detections:0'), # Postprocessed output
sess.graph.get_tensor_by_name('detection_scores:0'), #
sess.graph.get_tensor_by_name('detection_boxes:0'), #
sess.graph.get_tensor_by_name('detection_classes:0')], #
feed_dict={'image_tensor:0': inp.reshape(1, inp.shape[0], inp.shape[1], 3)})
np.save('ssd_mobilenet_v1_coco.concat.npy', out[0])
np.save('ssd_mobilenet_v1_coco.concat_1.npy', out[1])
# Pack detections in format [id, class_id, confidence, left, top, right, bottom]
num_detections = int(out[2][0])
detections = np.zeros([1, 1, num_detections, 7], np.float32)
detections[0, 0, :, 0] = 0 # bounding boxes ids
detections[0, 0, :, 1] = out[5][0]
detections[0, 0, :, 2] = out[3][0]
detections[0, 0, :, 3:] = out[4][0][:, [1, 0, 3, 2]]
# Detections are sorted in descending by confidence order. Group them by classes
# to make OpenCV test more simple.
detections = sorted(detections[0, 0, :, :], cmp=lambda x, y: -1 if x[1] < y[1] and x[2] < y[2] else 0)
np.save('ssd_mobilenet_v1_coco.detection_out.npy', detections)
################################################################################

# Uncomment to print the final graph.
# with tf.gfile.FastGFile('fused_batch_norm_net.pb') as f:
# graph_def = tf.GraphDef()
# graph_def.ParseFromString(f.read())
# print graph_def

os.remove('checkpoint')
os.remove('graph.pb')
os.remove('frozen_graph.pb')
os.remove('tmp.ckpt.data-00000-of-00001')
os.remove('tmp.ckpt.index')
os.remove('tmp.ckpt.meta')
def rm(f):
if os.path.exists(f):
os.remove(f)

rm('checkpoint')
rm('graph.pb')
rm('frozen_graph.pb')
rm('tmp.ckpt.data-00000-of-00001')
rm('tmp.ckpt.index')
rm('tmp.ckpt.meta')
Binary file not shown.
@@ -0,0 +1,64 @@
node {
name: "input"
op: "Placeholder"
}
node {
name: "lstm_block_wrapper/BlockLSTM"
op: "BlockLSTM"
input: "lstm_block_wrapper/ToInt64/_1__cf__1"
input: "input"
input: "lstm_block_wrapper/zeros/_0__cf__0"
input: "lstm_block_wrapper/zeros/_0__cf__0"
input: "lstm_block_wrapper/kernel"
input: "lstm_block_wrapper/w_i_diag"
input: "lstm_block_wrapper/w_f_diag"
input: "lstm_block_wrapper/w_o_diag"
input: "lstm_block_wrapper/bias"
attr { key: "cell_clip" value { f: 0.4 } }
attr { key: "forget_bias" value { f: 0.9 } }
attr { key: "use_peephole" value { b: true } }
}
node {
name: "Slice"
op: "Slice"
# Here is a key configuration change: replaced "lstm_block_wrapper/BlockLSTM:6" to
# "lstm_block_wrapper/BlockLSTM" (6th tensor of LSTM block is an output).
input: "lstm_block_wrapper/BlockLSTM"
input: "Slice/begin"
input: "Slice/size"
}
node {
name: "Reshape"
op: "Reshape"
input: "Slice"
input: "Reshape/shape"
}
node {
name: "MatMul"
op: "MatMul"
input: "Reshape"
input: "Variable"
attr {
key: "transpose_a"
value {
b: false
}
}
attr {
key: "transpose_b"
value {
b: false
}
}
}
node {
name: "add"
op: "Add"
input: "MatMul"
input: "Variable_1"
}
node {
name: "Sigmoid"
op: "Sigmoid"
input: "add"
}
Binary file not shown.
@@ -27,41 +27,11 @@ def fuse_constants(tool, in_graph, out_graph, in_node, out_node):
' --outputs=' + out_node + \
' --transforms="fold_constants(ignore_errors=True) sort_by_execution_order"')

# WARNING: If there is LSTM this procedure creates the graph that won't work in TensorFlow anymore.
def simplify_lstm(tool, in_graph, out_graph, in_node, out_node):
# Get all BlockLSTM nodes names.
lstm_names = []
with tf.gfile.FastGFile(in_graph) as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
for node in graph_def.node:
if node.op == 'BlockLSTM':
lstm_names.append(node.name)

# BlockLSTM returns tuple of tensors (i, cs, f, o, ci, co, h)
# where output is h (6th tensor). So we replace an every reference to
# an lstm_node_name:6 onto just an lstm_node_name.
for node in graph_def.node:
for i in range(len(node.input)):
for name in lstm_names:
if node.input[i] == name + ':6':
node.input[i] = name
tf.train.write_graph(graph_def, "", out_graph, as_text=False)

if lstm_names: # There is at least one lstm block.
os.system(tool + ' --in_graph=' + out_graph + \
' --out_graph=' + out_graph + \
' --inputs=' + in_node + \
' --outputs=' + out_node + \
' --transforms="remove_nodes(op=Cast) '
'rename_op(old_op_name=Fill, new_op_name=Const)"')

def prepare_for_dnn(net, ckpt, freeze_graph_tool, optimizer_tool, transform_graph_tool,
input_node_name, output_node_name, out_graph, dtype):
freeze_graph(net, ckpt, freeze_graph_tool, output_node_name)
optimize_for_inference(dtype, optimizer_tool, input_node_name, output_node_name, out_graph)
fuse_constants(transform_graph_tool, out_graph, out_graph, input_node_name, output_node_name)
simplify_lstm(transform_graph_tool, out_graph, out_graph, input_node_name, output_node_name)

if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Script for preparing serialized '
Binary file not shown.
Binary file not shown.
Binary file not shown.
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.