def addReshape(inp, out, shape, graph_def): shapeNode = NodeDef() shapeNode.name = out + '/shape' shapeNode.op = 'Const' text_format.Merge(tensorMsg(shape), shapeNode.attr["value"]) graph_def.node.extend([shapeNode]) reshape = NodeDef() reshape.name = out reshape.op = 'Reshape' reshape.input.append(inp) reshape.input.append(shapeNode.name) graph_def.node.extend([reshape])
def addSoftMax(inp, out, graph_def): softmax = NodeDef() softmax.name = out softmax.op = 'Softmax' text_format.Merge('i: -1', softmax.attr['axis']) softmax.input.append(inp) graph_def.node.extend([softmax])
def addConcatNode(name, inputs): concat = NodeDef() concat.name = name concat.op = 'ConcatV2' for inp in inputs: concat.input.append(inp) concat.input.append(concatAxis.name) graph_def.node.extend([concat])
def addSlice(inp, out, begins, sizes, graph_def): beginsNode = NodeDef() beginsNode.name = out + '/begins' beginsNode.op = 'Const' text_format.Merge(tensorMsg(begins), beginsNode.attr["value"]) graph_def.node.extend([beginsNode]) sizesNode = NodeDef() sizesNode.name = out + '/sizes' sizesNode.op = 'Const' text_format.Merge(tensorMsg(sizes), sizesNode.attr["value"]) graph_def.node.extend([sizesNode]) sliced = NodeDef() sliced.name = out sliced.op = 'Slice' sliced.input.append(inp) sliced.input.append(beginsNode.name) sliced.input.append(sizesNode.name) graph_def.node.extend([sliced])
def const_node(dtype, value, shape): node = NodeDef() node.op = 'Const' node.attr['dtype'].type = dtype.as_datatype_enum node.attr['value'].tensor.dtype = dtype.as_datatype_enum node.attr['value'].tensor.tensor_shape.CopyFrom(as_shape(shape).as_proto()) if value.dtype == np.float32: _extend(node.attr['value'].tensor.float_val, value) elif value.dtype == np.int32: _extend(node.attr['value'].tensor.int_val, value) else: raise Exception('const_node, unknown dtype {}'.format(value.dtype)) return node
def build(self): for i, layer in enumerate(self.model.node): self.layer_map[layer.name] = TensorflowGraphNode(layer) self.layer_name_map[layer.name] = layer.name for pred in layer.input: if pred not in self.layer_map: new_node = NodeDef() new_node.name = pred new_node.op = "NoOp" self.layer_map[pred] = TensorflowGraphNode(new_node) self.layer_name_map[pred] = pred self._make_connection(pred, layer.name) super(TensorflowGraph, self).build()
def build(self): for i, layer in enumerate(self.model.node): self.layer_map[layer.name] = TensorflowGraphNode(layer) for i, layer in enumerate(self.model.node): self.layer_map[layer.name] = TensorflowGraphNode(layer) self.layer_name_map[layer.name] = layer.name for pred in layer.input: if pred not in self.layer_map: new_node = NodeDef() new_node.name = pred new_node.op = "NoOp" self.layer_map[pred] = TensorflowGraphNode(new_node) self.layer_name_map[pred] = pred self._make_connection(pred, layer.name) super(TensorflowGraph, self).build()
# Connect input node to the first layer assert(graph_def.node[0].op == 'Placeholder') # assert(graph_def.node[1].op == 'Conv2D') weights = graph_def.node[1].input[0] for i in range(len(graph_def.node[1].input)): graph_def.node[1].input.pop() graph_def.node[1].input.append(graph_def.node[0].name) graph_def.node[1].input.append(weights) # Create SSD postprocessing head ############################################### # Concatenate predictions of classes, predictions of bounding boxes and proposals. concatAxis = NodeDef() concatAxis.name = 'concat/axis_flatten' concatAxis.op = 'Const' text_format.Merge( 'tensor {' ' dtype: DT_INT32' ' tensor_shape { }' ' int_val: -1' '}', concatAxis.attr["value"]) graph_def.node.extend([concatAxis]) def addConcatNode(name, inputs): concat = NodeDef() concat.name = name concat.op = 'ConcatV2' for inp in inputs: concat.input.append(inp) concat.input.append(concatAxis.name)
for label in ['ClassPredictor', 'BoxEncodingPredictor' if args.box_predictor is 'convolutional' else 'BoxPredictor']: concatInputs = [] for i in range(args.num_layers): # Flatten predictions flatten = NodeDef() if args.box_predictor is 'convolutional': inpName = 'BoxPredictor_%d/%s/BiasAdd' % (i, label) else: if i == 0: inpName = 'WeightSharedConvolutionalBoxPredictor/%s/BiasAdd' % label else: inpName = 'WeightSharedConvolutionalBoxPredictor_%d/%s/BiasAdd' % (i, label) flatten.input.append(inpName) flatten.name = inpName + '/Flatten' flatten.op = 'Flatten' concatInputs.append(flatten.name) graph_def.node.extend([flatten]) addConcatNode('%s/concat' % label, concatInputs, 'concat/axis_flatten') idx = 0 for node in graph_def.node: if node.name == ('BoxPredictor_%d/BoxEncodingPredictor/Conv2D' % idx) or \ node.name == ('WeightSharedConvolutionalBoxPredictor_%d/BoxPredictor/Conv2D' % idx) or \ node.name == 'WeightSharedConvolutionalBoxPredictor/BoxPredictor/Conv2D': text_format.Merge('b: true', node.attr["loc_pred_transposed"]) idx += 1 assert(idx == args.num_layers) # Add layers that generate anchors (bounding boxes proposals).
def addFlatten(inp, out, graph_def): flatten = NodeDef() flatten.name = out flatten.op = 'Flatten' flatten.input.append(inp) graph_def.node.extend([flatten])
softmax = NodeDef() softmax.name = out softmax.op = 'Softmax' text_format.Merge('i: -1', softmax.attr['axis']) softmax.input.append(inp) graph_def.node.extend([softmax]) addReshape('FirstStageBoxPredictor/ClassPredictor/BiasAdd', 'FirstStageBoxPredictor/ClassPredictor/reshape_1', [0, -1, 2]) addSoftMax('FirstStageBoxPredictor/ClassPredictor/reshape_1', 'FirstStageBoxPredictor/ClassPredictor/softmax') # Compare with Reshape_4 flatten = NodeDef() flatten.name = 'FirstStageBoxPredictor/BoxEncodingPredictor/flatten' # Compare with FirstStageBoxPredictor/BoxEncodingPredictor/BiasAdd flatten.op = 'Flatten' flatten.input.append('FirstStageBoxPredictor/BoxEncodingPredictor/BiasAdd') graph_def.node.extend([flatten]) proposals = NodeDef() proposals.name = 'proposals' # Compare with ClipToWindow/Gather/Gather (NOTE: normalized) proposals.op = 'PriorBox' proposals.input.append('FirstStageBoxPredictor/BoxEncodingPredictor/BiasAdd') proposals.input.append(graph_def.node[0].name) # image_tensor text_format.Merge('b: false', proposals.attr["flip"]) text_format.Merge('b: true', proposals.attr["clip"]) text_format.Merge('f: %f' % args.features_stride, proposals.attr["step"]) text_format.Merge('f: 0.0', proposals.attr["offset"]) text_format.Merge(tensorMsg([0.1, 0.1, 0.2, 0.2]), proposals.attr["variance"])
for attr in ['T', 'data_format', 'Tshape', 'N', 'Tidx', 'Tdim', 'use_cudnn_on_gpu', 'Index', 'Tperm', 'is_training', 'Tpaddings', 'Tblock_shape', 'Tcrops']: if attr in graph_def.node[i].attr: del graph_def.node[i].attr[attr] # Append prior box generators min_sizes = [30, 60, 111, 162, 213, 264] max_sizes = [60, 111, 162, 213, 264, 315] steps = [8, 16, 32, 64, 100, 300] aspect_ratios = [[2], [2, 3], [2, 3], [2, 3], [2], [2]] layers = [conv4_3_norm, fc7, conv6_2_h, conv7_2_h, conv8_2_h, conv9_2_h] for i in range(6): priorBox = NodeDef() priorBox.name = 'PriorBox_%d' % i priorBox.op = 'PriorBox' priorBox.input.append(layers[i].name[:layers[i].name.find(':')]) priorBox.input.append(inp_nodes[0]) # data text_format.Merge('i: %d' % min_sizes[i], priorBox.attr["min_size"]) text_format.Merge('i: %d' % max_sizes[i], priorBox.attr["max_size"]) text_format.Merge('b: true', priorBox.attr["flip"]) text_format.Merge('b: false', priorBox.attr["clip"]) text_format.Merge(tensorMsg(aspect_ratios[i]), priorBox.attr["aspect_ratio"]) text_format.Merge(tensorMsg([0.1, 0.1, 0.2, 0.2]), priorBox.attr["variance"]) text_format.Merge('f: %f' % steps[i], priorBox.attr["step"]) text_format.Merge('f: 0.5', priorBox.attr["offset"]) graph_def.node.extend([priorBox]) # Concatenate prior boxes concat = NodeDef()
addReshape('FirstStageBoxPredictor/ClassPredictor/BiasAdd', 'FirstStageBoxPredictor/ClassPredictor/reshape_1', [0, -1, 2], graph_def) addSoftMax('FirstStageBoxPredictor/ClassPredictor/reshape_1', 'FirstStageBoxPredictor/ClassPredictor/softmax', graph_def) # Compare with Reshape_4 addFlatten('FirstStageBoxPredictor/ClassPredictor/softmax', 'FirstStageBoxPredictor/ClassPredictor/softmax/flatten', graph_def) # Compare with FirstStageBoxPredictor/BoxEncodingPredictor/BiasAdd addFlatten('FirstStageBoxPredictor/BoxEncodingPredictor/BiasAdd', 'FirstStageBoxPredictor/BoxEncodingPredictor/flatten', graph_def) proposals = NodeDef() proposals.name = 'proposals' # Compare with ClipToWindow/Gather/Gather (NOTE: normalized) proposals.op = 'PriorBox' proposals.input.append('FirstStageBoxPredictor/BoxEncodingPredictor/BiasAdd') proposals.input.append(graph_def.node[0].name) # image_tensor text_format.Merge('b: false', proposals.attr["flip"]) text_format.Merge('b: true', proposals.attr["clip"]) text_format.Merge('f: %f' % args.features_stride, proposals.attr["step"]) text_format.Merge('f: 0.0', proposals.attr["offset"]) text_format.Merge(tensorMsg([0.1, 0.1, 0.2, 0.2]), proposals.attr["variance"]) widths = [] heights = [] for a in args.aspect_ratios: for s in args.scales: ar = np.sqrt(a) heights.append((args.features_stride**2) * s / ar)
def quantize_graph_def(graph_def, skip=None, output_nodes=None, rel_tol=None, only=None): """ :type graph_def: GraphDef :type skip: set|list :type output_nodes: list :type rel_tol: float :type only: str :return: QuantizedGraph """ if output_nodes is not None and len(output_nodes) > 0: graph_def = extract_sub_graph(graph_def, output_nodes) nodes = [] items = [] for node in graph_def.node: # check skip if should_skip(node, skip): nodes.append(node) continue # try convert to constant try: value = MakeNdarray(node.attr['value'].tensor) # type: np.ndarray except TypeError: nodes.append(node) continue # check repeated field same_value = all_same_value(value, rel_tol) if same_value is not None: nodes.append( const_node(node.attr['dtype'].type, np.array([same_value], dtype=value.dtype), value.shape)) continue # check data size elif value.size < 4096: nodes.append(node) continue # finally processed_node = NodeDef() processed_node.name = node.name processed_node.op = 'Placeholder' processed_node.attr['dtype'].type = node.attr['dtype'].type processed_node.attr['shape'].shape.CopyFrom( as_shape(value.shape).as_proto()) nodes.append(processed_node) item = QuantizedItem() item.name = node.name item.dtype = node.attr['dtype'].type item.shape.extend(value.shape) print('quantize {}'.format(node.name)) _fill(item, value, only=only) items.append(item) graph = QuantizedGraph() graph.graph.versions.CopyFrom(graph_def.versions) graph.graph.library.CopyFrom(graph_def.library) graph.graph.node.extend(nodes) graph.items.extend(items) return graph
graph_def) addSoftMax('FirstStageBoxPredictor/ClassPredictor/reshape_1', 'FirstStageBoxPredictor/ClassPredictor/softmax', graph_def) # Compare with Reshape_4 addFlatten('FirstStageBoxPredictor/ClassPredictor/softmax', 'FirstStageBoxPredictor/ClassPredictor/softmax/flatten', graph_def) # Compare with FirstStageBoxPredictor/BoxEncodingPredictor/BiasAdd addFlatten('FirstStageBoxPredictor/BoxEncodingPredictor/BiasAdd', 'FirstStageBoxPredictor/BoxEncodingPredictor/flatten', graph_def) proposals = NodeDef() proposals.name = 'proposals' # Compare with ClipToWindow/Gather/Gather (NOTE: normalized) proposals.op = 'PriorBox' proposals.input.append('FirstStageBoxPredictor/BoxEncodingPredictor/BiasAdd') proposals.input.append(graph_def.node[0].name) # image_tensor text_format.Merge('b: false', proposals.attr["flip"]) text_format.Merge('b: true', proposals.attr["clip"]) text_format.Merge('f: %f' % args.features_stride, proposals.attr["step"]) text_format.Merge('f: 0.0', proposals.attr["offset"]) text_format.Merge(tensorMsg([0.1, 0.1, 0.2, 0.2]), proposals.attr["variance"]) widths = [] heights = [] for a in args.aspect_ratios: for s in args.scales: ar = np.sqrt(a) heights.append((args.features_stride**2) * s / ar)
concat.input.append(inp) concat.input.append(axisNodeName) graph_def.node.extend([concat]) addConstNode('concat/axis_flatten', [-1]) addConstNode('PriorBox/concat/axis', [-2]) for label in ['ClassPredictor', 'BoxEncodingPredictor']: concatInputs = [] for i in range(args.num_layers): # Flatten predictions flatten = NodeDef() inpName = 'BoxPredictor_%d/%s/BiasAdd' % (i, label) flatten.input.append(inpName) flatten.name = inpName + '/Flatten' flatten.op = 'Flatten' concatInputs.append(flatten.name) graph_def.node.extend([flatten]) addConcatNode('%s/concat' % label, concatInputs, 'concat/axis_flatten') # Add layers that generate anchors (bounding boxes proposals). scales = [args.min_scale + (args.max_scale - args.min_scale) * i / (args.num_layers - 1) for i in range(args.num_layers)] + [1.0] priorBoxes = [] addConstNode('reshape_prior_boxes_to_4d', [1, 2, -1, 1]) for i in range(args.num_layers): priorBox = NodeDef() priorBox.name = 'PriorBox_%d' % i priorBox.op = 'PriorBox'
def addConstNode(name, values, graph_def): node = NodeDef() node.name = name node.op = 'Const' text_format.Merge(tensorMsg(values), node.attr["value"]) graph_def.node.extend([node])