class ModelOpenVINO(object): def __init__(self, xml_file_path, bin_file_path=None, mapping_file_path=None, device='CPU', required_inputs=None, required_outputs=None, max_num_requests=1, collect_perf_counters=False, cfg=None, classes=None): from openvino.inference_engine import IENetwork ie = IECore() logging.info('Reading network from IR...') if bin_file_path is None: bin_file_path = osp.splitext(xml_file_path)[0] + '.bin' if mapping_file_path is None: mapping_file_path = osp.splitext(xml_file_path)[0] + '.mapping' self.net = IENetwork(model=xml_file_path, weights=bin_file_path) self.orig_ir_mapping = self.get_mapping(mapping_file_path) self.ir_orig_mapping = {v: k for k, v in self.orig_ir_mapping.items()} self.net_inputs_mapping = OrderedDict({}) self.net_outputs_mapping = OrderedDict({}) self.configure_inputs(required_inputs) self.configure_outputs(required_outputs) if 'CPU' in device: self.check_cpu_support(ie, self.net) logging.info('Loading network to plugin...') self.max_num_requests = max_num_requests self.exec_net = ie.load_network(network=self.net, device_name=device, num_requests=max_num_requests) self.perf_counters = None if collect_perf_counters: self.perf_counters = PerformanceCounters() self.pt_model = None if cfg is not None: self.pt_model = build_detector(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg) if classes is not None: self.pt_model.CLASSES = classes @staticmethod def check_cpu_support(ie, net): logging.info('Check that all layers are supported...') supported_layers = ie.query_network(net, 'CPU') not_supported_layers = [ l for l in net.layers.keys() if l not in supported_layers ] if len(not_supported_layers) != 0: unsupported_info = '\n\t'.join( '{} ({} with params {})'.format( layer_id, net.layers[layer_id].type, str(net.layers[layer_id].params)) for layer_id in not_supported_layers) logging.warning( 'Following layers are not supported ' 'by the CPU plugin:\n\t{}'.format(unsupported_info)) logging.warning( 'Please try to specify cpu extensions library path.') raise ValueError('Some of the layers are not supported.') def get_mapping(self, mapping_file_path=None): mapping = {} if mapping_file_path is not None: logging.info('Loading mapping file...') root = etree.parse(mapping_file_path).getroot() for m in root: if m.tag != 'map': continue framework = m.find('framework') ir = m.find('IR') framework_name = framework.get('name') ir_name = ir.get('name') mapping[framework_name] = ir_name if framework_name != ir_name: # FIXME. This may not be correct for all operations. mapping[framework_name] += '.0' return mapping def try_add_extra_outputs(self, extra_outputs): if extra_outputs is None: return for extra_output in extra_outputs: if extra_output not in self.orig_ir_mapping: continue ir_name = self.orig_ir_mapping[extra_output] try: self.net.add_outputs(ir_name) except RuntimeError: pass def configure_inputs(self, required): self.net_inputs_mapping = OrderedDict( (i, i) for i in self.net.inputs.keys()) self.check_required(self.net_inputs_mapping.keys(), required) def configure_outputs(self, required): self.try_add_extra_outputs(required) self.net_outputs_mapping = OrderedDict( (i, self.ir_orig_mapping[i]) for i in self.net.outputs.keys()) self.check_required(self.orig_ir_mapping.keys(), required) def set_outputs(self, outputs): self.check_required(self.orig_ir_mapping.keys(), outputs) self.net_outputs_mapping = OrderedDict( (self.orig_ir_mapping[i], i) for i in outputs) @staticmethod def check_required(available, required): if required is None: return for x in required: if x not in available: raise ValueError( f'Failed to identify data blob with name "{x}"') def rename_outputs(self, outputs): return { self.net_outputs_mapping[k]: v for k, v in outputs.items() if k in self.net_outputs_mapping } def unify_inputs(self, inputs): if not isinstance(inputs, dict): if len(self.net_inputs_mapping) == 1 and not isinstance( inputs, (list, tuple)): inputs = [inputs] inputs = { k: v for (k, _), v in zip(self.net_inputs_mapping.items(), inputs) } inputs = {self.net_inputs_mapping[k]: v for k, v in inputs.items()} return inputs def __call__(self, inputs): inputs = self.unify_inputs(inputs) outputs = self.exec_net.infer(inputs) if self.perf_counters: perf_counters = self.exec_net.requests[0].get_perf_counts() self.perf_counters.update(perf_counters) return self.rename_outputs(outputs) def print_performance_counters(self): if self.perf_counters: self.perf_counters.print() def show(self, data, result, dataset=None, score_thr=0.3, wait_time=0): if self.pt_model is not None: self.pt_model.show_result(data, result, dataset=dataset, score_thr=score_thr, wait_time=wait_time)
def main(): colormap = 'viridis' job_id = os.environ['PBS_JOBID'] job_id = job_id.rstrip().split('.')[0] log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout) args = build_argparser().parse_args() model_xml = args.model model_bin = os.path.splitext(model_xml)[0] + ".bin" log.info("Loading network files:\n\t{}\n\t{}".format(model_xml, model_bin)) device = args.device fp16 = True if device == "CPU": fp16 = False # Plugin initialization for specified device and load extensions library if specified plugin = IEPlugin(device=device) # Read IR net = IENetwork(model=model_xml, weights=model_bin) assert len( net.inputs.keys()) == 1, "Sample supports only single input topologies" bn = "relu_1/Relu" print(bn) # add the last convolutional layer as output net.add_outputs(bn) fc = "predictions_1/MatMul" # name of the inputs and outputs input_blob = next(iter(net.inputs)) out_blob = "predictions_1/Sigmoid" net.batch_size = 1 exec_net = plugin.load(network=net) n, c, h, w = net.inputs[input_blob].shape print("Current Directory:", os.getcwd()) files = glob.glob(os.getcwd() + args.input[0]) if not os.path.isdir(args.output_dir): os.makedirs(args.output_dir, exist_ok=True) f = open(os.path.join(args.output_dir, job_id, 'result.txt'), 'w') progress_file_path = os.path.join(args.output_dir, job_id, "i_progress.txt") print(progress_file_path) time_images = [] tstart = time.time() for index_f, file in enumerate(files): [image1, image] = read_image(file) t0 = time.time() for i in range(args.number_iter): res = exec_net.infer(inputs={input_blob: image1}) #infer_time.append((time()-t0)*1000) infer_time = (time.time() - t0) * 1000 log.info("Average running time of one iteration: {} ms".format( np.average(np.asarray(infer_time)))) if args.perf_counts: perf_counts = exec_net.requests[0].get_perf_counts() log.info("Performance counters:") print("{:<70} {:<15} {:<15} {:<15} {:<10}".format( 'name', 'layer_type', 'exet_type', 'status', 'real_time, us')) for layer, stats in perf_counts.items(): print("{:<70} {:<15} {:<15} {:<15} {:<10}".format( layer, stats['layer_type'], stats['exec_type'], stats['status'], stats['real_time'])) res_pb = res[out_blob] probs = res_pb[0][0] print("Probability of having disease= " + str(probs) + ", performed in " + str(np.average(np.asarray(infer_time))) + " ms") # Class Activation Map t0 = time.time() cam = class_activation_map_openvino(res, bn, fc, net, fp16) cam_time = (time.time() - t0) * 1000 print("Time for CAM: {} ms".format(cam_time)) fig, ax = plt.subplots(1, 2) # Visualize the CAM heatmap cam = (cam - np.min(cam)) / (np.max(cam) - np.min(cam)) im = ax[0].imshow(cam, cmap=colormap) ax[0].axis('off') plt.colorbar(im, ax=ax[0], fraction=0.046, pad=0.04) # Visualize the CAM overlaid over the X-ray image colormap_val = cm.get_cmap(colormap) imss = np.uint8(colormap_val(cam) * 255) im = Image.fromarray(imss) width, height = image.size cam1 = resize_image(im, (height, width)) heatmap = np.asarray(cam1) img1 = heatmap[:, :, :3] * 0.3 + image ax[1].imshow(np.uint16(img1)) plt.xticks([]), plt.yticks([]) # to hide tick values on X and Y axis plt.savefig(os.path.join(args.output_dir, job_id, 'result' + str(index_f) + '.png'), bbox_inches='tight', pad_inches=0, dpi=300) avg_time = round((infer_time / args.number_iter), 1) #f.write(res + "\n Inference performed in " + str(np.average(np.asarray(infer_time))) + "ms") f.write("Pneumonia probability: " + str(probs) + ", Inference performed in " + str(avg_time) + "ms \n") time_images.append(avg_time) progressUpdate(progress_file_path, index_f * avg_time, index_f + 1, len(files)) total_time = round(time.time() - tstart, 2) stats = {} stats['time'] = str(total_time) stats['frames'] = str(len(files)) stats['fps'] = str(round(len(files) / total_time, 2)) with open(os.path.join(args.output_dir, job_id, 'stats.json'), 'w') as json_file: json.dump(stats, json_file)
class Network: """ Load and configure inference plugins for the specified target devices and performs synchronous and asynchronous modes for the specified infer requests. """ def __init__(self): ### TODO: Initialize any class variables desired ### self.plugin = IECore() self.network = None self.exec_network = None self.input_blob = None self.output_blob = None self.input_info = None def load_model(self, model, cpu_extension): model_xml = model model_bin = os.path.splitext(model_xml)[0] + ".bin" if cpu_extension: self.plugin.add_extension(cpu_extension, "CPU") ### TODO: Load the model ### self.network = IENetwork(model=model_xml, weights=model_bin) self.network.add_outputs(['detection_output']) self.exec_network = self.plugin.load_network(self.network, "CPU") ### TODO: Check for supported layers ### supported_layers = self.plugin.query_network(network=self.network, device_name="CPU") #print(supported_layers) unsupported_layers = [ l for l in self.network.layers.keys() if l not in supported_layers ] if len(unsupported_layers) != 0: print("Unsupported layers found: {}".format(unsupported_layers)) print("Check whether extensions are available to add to IECore.") exit(1) ### TODO: Add any necessary extensions ### ### TODO: Return the loaded inference plugin ### ### Note: You may need to update the function parameters. ### #I understood the input form of the model thanks to: #https://knowledge.udacity.com/questions/196315 #https://knowledge.udacity.com/questions/157050 #https://knowledge.udacity.com/questions/137114 inputs = iter(self.network.inputs) self.input_info = "image_info" self.input_blob = "image_tensor" self.output_blob = next(iter(self.network.outputs)) return def get_input_shape(self): ### TODO: Return the shape of the input layer ### #print(self.input_blob) #print(self.network.inputs[self.input_info].shape) #print(self.network.inputs) return self.network.inputs[self.input_blob].shape def exec_net(self, image): ### TODO: Start an asynchronous request ### #print(self.network.inputs[self.input_info]) #print(image.shape[1:]) self.exec_network.requests[0].async_infer({ self.input_info: [800, 800, 1], self.input_blob: image }) #self.exec_network.start_async(request_id=0, inputs={self.input_blob: image}) ### TODO: Return any necessary information ### ### Note: You may need to update the function parameters. ### return def wait(self): ### TODO: Wait for the request to be complete. ### ### TODO: Return any necessary information ### ### Note: You may need to update the function parameters. ### status = self.exec_network.requests[0].wait(-1) return status def get_output(self): ### TODO: Extract and return the output results ### Note: You may need to update the function parameters. ### return self.exec_network.requests[0].outputs[ 'detection_output'] #[self.output_blob]