def top5_accuracy(graph, input_nodes, output_nodes, iter_cnt, batch_size, label_offset=0): global BATCH_SIZE, INPUT_NODES, INCLUDE_LABELS, LABEL_OFFSET INPUT_NODES = input_nodes INCLUDE_LABELS = True LABEL_OFFSET = label_offset BATCH_SIZE = batch_size with tf.Session(graph=graph) as sess: input_tensors = { node: sess.graph.get_operation_by_name(node).outputs[0] for node in make_list(input_nodes) } output_tensor = sess.graph.get_operation_by_name( output_nodes).outputs[0] top1_acc = 0 top5_acc = 0 progress = ProgressBar() line = open(IMAGELIST).readlines() for iter in progress(range(iter_cnt)): inputs = input_fn(iter) correct_labels = inputs['labels'] predictions = sess.run( output_tensor, feed_dict={ tensor: inputs[name] for name, tensor in input_tensors.items() }) top1_prediction = np.argmax(predictions, axis=1) top5_prediction = np.argsort(predictions, axis=1)[:, -5:] top1_accuracy = sum(top1_prediction == correct_labels) top5_accuracy = sum( [label in top5_prediction for label in correct_labels]) top1_acc += top1_accuracy top5_acc += top5_accuracy total_samples = float(iter_cnt * batch_size) final_top1_acc = top1_acc / total_samples final_top5_acc = top5_acc / total_samples print('top1_acc:{}, top5_acc:{}'.format(final_top1_acc, final_top5_acc))
def debug_finalnode(self, input_values, **kwargs): input_values = xdnn_util.make_list(input_values) input_names = self.inputs output_names = xdnn_util.make_list(self._args.finalnode) ## running the original graph with tf.Graph().as_default() as graph_org: tf.import_graph_def(self._graph, name='') node_dict, \ output_dict = graph_org.as_graph_def().get_node_dict(outmap=True) input_tensors = [ graph_org.get_operation_by_name(name).outputs[0] for name in input_names ] output_tensors = [ graph_org.get_operation_by_name(name).outputs[0] for name in output_names ] print('org tensor: {}'.format(output_tensors)) with tf.Session() as sess: feed_dict = { tensor: [value] for tensor, value in zip(input_tensors, input_values) } ret = {'org': sess.run(output_tensors, feed_dict)} ## running the partitioned graph graph = self.load_partitioned_graph() input_tensors = [ graph.get_operation_by_name(name).outputs[0] for name in input_names ] output_tensors = [ graph.get_operation_by_name(name).outputs[0] for name in output_names ] # output_tensors = [] # for name in output_names: # consumers = output_dict[name].keys() # name = consumers[0] if consumers else name # inp = [node.name for node in graph.get_operation_by_name(name).inputs if 'transpose' in # node.name] # if inp: # ## use this in case output_names are NOT the last operations in global graph # output_tensors.append(inp[0]) # else: # ## use this in case output_names are the last operations in global graph # output_tensors.append(graph.get_operation_by_name(name).outputs[0]) ########################################## print('fpga tensor: {}'.format(output_tensors)) with tf.Session(graph=graph) as sess: feed_dict = { tensor: [value] for tensor, value in zip(input_tensors, input_values) } ret.update({'fpga': sess.run(output_tensors, feed_dict)}) for org, fpga in zip(ret['org'], ret['fpga']): print('org max {} min {} mean {} std {}'.format( org.max(), org.min(), org.mean(), org.std())) print('FPGA max {} min {} mean {} std {}'.format( fpga.max(), fpga.min(), fpga.mean(), fpga.std())) print('DIFF max {} min {} mean {} std {}'.format( (fpga - org).max(), (fpga - org).min(), (fpga - org).mean(), (fpga - org).std())) return ret
def default_forward_exec(**kwargs): if 'sess' in kwargs: sess = kwargs['sess'] graph = sess.graph else: #config=tf.ConfigProto(log_device_placement=True) graph = self.load_partitioned_graph() sess = tf.Session(graph=graph, config=kwargs.get('config', None)) ## declare input tensors to network graph input_names = kwargs.get('input_names', None) if not input_names: input_names = self.inputs else: for inp in input_names: if not isinstance(inp, _string_types): raise TypeError( 'input_names should be flattened list of name strings' ) input_tensors = [ graph.get_operation_by_name(name).outputs[0] for name in input_names ] ## declare output tensors to network graph output_names = kwargs.get('output_names', None) if not output_names: output_names = self.outputs else: for out in output_names: if not isinstance(out, _string_types): raise TypeError( 'output_names should be flattened list of name strings' ) output_tensors = [ graph.get_operation_by_name(name).outputs[0] for name in output_names ] ## bound the input tensors to input data preprocess = kwargs.get('preprocess', self.preprocess) input_values = xdnn_util.make_list(kwargs.get( 'input_values', None)) feed_dict = { inp_tensor: inp_val if len(inp_val.shape) == len( inp_tensor.shape) else inp_val[None, ...] for inp_tensor, inp_val in zip(input_tensors, preprocess(input_values)) } output_values = sess.run( output_tensors, feed_dict=feed_dict if feed_dict else None) if 'sess' not in kwargs: sess.close() return { tensor.op.name: val for val, tensor in zip(output_values, output_tensors) }
def load_graph(args, **kwargs): ## Loads the graph at args.networkfile. args can be either namedspace, namedtuple. or dictionary ## parameters: ## networkfile: path to the network file or folder ## loadmode: saving protocol of the network file ## startnode: list of source nodes of the graph. (optional. Defaults to all placehoders) ## finalnode: list of sink nodes of the graph. (optional. Defaults to all sinknodes) ## inclusive: include the starnodes. (optional. Defaults to True) ## fixinputnames: fix the input placeholder name. otherwise their names starts with geph__ and ends with a index. (optional. Defaults to True) ## placeholdershape: Dictionary mapping of placehoder shapes to new shapes ## remove_training_nodes: Limits the network to inference nodes if True (optional. Defaults to True) ## remove_redundant_nodes: Limits the network to nodes involved in computing the sinknodes (optional. Defaults to True) ## freeze_blacklist: list of nodes to keep in the graph (optional) ## freeze_whitelist: list of nodes to remove in the graph (optional) ## graph_savepath: path to save the updated graph (optional) ## return: ## imported and modified graph_def ## inputs to graph_def ## outputs from graph_def args = dict2attr(args) args.update(kwargs) print('\n######### load_graph arguments #############') for key in _load_graph_args_keys: print('{}: {}'.format(key, args[key])) print('#############################################\n') sess = None startnode = make_list(args.startnode) finalnode = make_list(args.finalnode) placeholdershape = args.get('placeholdershape', {}) ## load graph_def if not args.networkfile: raise ValueError('networkfile is not specified!') graph_def = tf.GraphDef() with tf.Graph().as_default() as temp_graph: loadmode = args.get('loadmode', 'binary') if loadmode.lower() == 'checkpoint': sess = tf.Session(graph=temp_graph) tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], args.networkfile) graph_def = sess.graph.as_graph_def(add_shapes=True) elif loadmode.lower() == 'text': with open(args.networkfile) as f: graph_def = text_format.Parse(f.read(), tf.GraphDef()) elif loadmode.lower() == 'binary': with _gfile.FastGFile(args.networkfile, 'rb') as f: graph_def.ParseFromString(f.read()) else: raise ValueError( 'unsupported textmode parameter: \"{}\"'.format(loadmode)) ## fill in all output shapes (Not necessary, will be performed in freeze_graph) # tf.import_graph_def(graph_def, name='') # graph_def = temp_graph.as_graph_def(add_shapes=True) inputs = startnode if startnode else discover_sourcenodes(graph_def) outputs = finalnode if finalnode else discover_sinknodes(graph_def) if placeholdershape: node_dict = get_node_dict(graph_def) for name, shape in placeholdershape.items(): print('change palceholder {} shape to {}'.format(name, shape)) node = node_dict[name] set_shape(node, shape) if startnode or finalnode: graph_def = extract_subgraph(graph_def, outputs, inputs, inclusive=args.get('inclusive', True), fixinputnames=args.get( 'fixinputnames', True)) inputs = discover_sourcenodes(graph_def) outputs = discover_sinknodes(graph_def) graph_def, fValidGraph = freeze_graph( sess, graph_def, sinknodes_list=outputs, remove_training_nodes=args.get('remove_training_nodes', True), remove_redundant_nodes=args.get('remove_redundant_nodes', True), freeze_blacklist=args.get('freeze_blacklist', []), freeze_whitelist=args.get('freeze_whitelist', []), filename=args.graph_savepath) if sess: sess.close return graph_def, inputs, outputs, fValidGraph
def freeze_graph(sess, graph_def, remove_training_nodes=True, remove_redundant_nodes=True, sinknodes_list=[], freeze_blacklist=[], freeze_whitelist=[], filename=None): ## freezing a graph_def by removing freeze_blacklist, training nodes(if remove_training_nodes), nodes not ## contributing in sinknode_list computation(if remove_redundant_nodes), while keeping ## freeze_blacklist (which includes the specified sinknodes_list) print('freeze model') sinknodes_list = make_list(sinknodes_list) freeze_blacklist = make_list(freeze_blacklist) freeze_whitelist = make_list(freeze_whitelist) # if sess is not None: # graph_def = sess.graph.as_graph_def(add_shapes=True) ## convert variables to constants for inference model if not sinknodes_list: sinknodes_list = discover_sinknodes(graph_def) if sess is not None: print('.... convert variables to constants') graph_def = tf.graph_util.convert_variables_to_constants( sess, graph_def, sinknodes_list) freeze_whitelist += sinknodes_list print('.... node count {}'.format(len(graph_def.node))) if remove_training_nodes: graph_def = tf.graph_util.remove_training_nodes( graph_def, protected_nodes=freeze_whitelist) print('.... node count after removing training nodes {}'.format( len(graph_def.node))) if remove_redundant_nodes: graph_def = tf.graph_util.extract_sub_graph(graph_def, sinknodes_list) print('.... node count after removing redundant nodes {}'.format( len(graph_def.node))) ## remove freeze_balcklist nodes # add summary nodes to freeze_balcklist freeze_blacklist += ['Summaries', 'MergeSummary'] graph_def_frozen = tf.GraphDef() for node in graph_def.node: pass_cnd = np.array( [blocked not in node.name for blocked in freeze_blacklist]) if pass_cnd.all(): graph_def_frozen.node.extend([node]) print('.... node count after removing blacklisted nodes {}'.format( len(graph_def_frozen.node))) try: fValidGraph = True ## fill in all output shapes with tf.Graph().as_default() as temp_graph: tf.import_graph_def(graph_def_frozen, name='') graph_def_frozen2 = temp_graph.as_graph_def(add_shapes=True) graph_def_frozen = graph_def_frozen2 except Exception as e: fValidGraph = False print(e) print(type(graph_def_frozen)) #assert(False, "invalid graph_def") if filename is not None: print('save graph at {}'.format(filename)) with tf.gfile.GFile(filename, "wb") as f: f.write(graph_def_frozen.SerializeToString()) return graph_def_frozen, fValidGraph
def remove_nodes(self, node_names): for name in make_list(node_names): del self.node[self.get_node_index(name)]