def main(args=None): # parse arguments if args is None: args = sys.argv[1:] args = parse_args(args) # Set modified tf session to avoid using the GPUs keras.backend.tensorflow_backend.set_session(get_session()) # optionally load config parameters anchor_parameters = None if args.config: args.config = read_config_file(args.config) if 'anchor_parameters' in args.config: anchor_parameters = parse_anchor_parameters(args.config) # load the model model = models.load_model(args.model_in, backbone_name=args.backbone) # check if this is indeed a training model models.check_training_model(model) # convert the model model = models.convert_model( model, nms=args.nms, class_specific_filter=args.class_specific_filter, anchor_params=anchor_parameters) # save model model.save(args.model_out)
def main(args=None): # parse arguments if args is None: args = sys.argv[1:] args = parse_args(args) # optionally load config parameters if args.config: args.config = read_config_file(args, 'evaluation') #print("----------------------------------") #print("ARGUMENTS IN CONFIG FILE:") #for sec in args.config.sections(): #print(sec, "=", dict(args.config.items(sec))) #print("----------------------------------") # for arg in vars(args): # print(arg, "=", getattr(args, arg)) # exit() # make sure keras is the minimum required version check_keras_version() # optionally choose specific GPU if args.gpu: os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu keras.backend.tensorflow_backend.set_session(get_session()) # make save path if it doesn't exist if args.save_path is not None and not os.path.exists(args.save_path): os.makedirs(args.save_path) # create the generator generator = create_generator(args) # optionally load anchor parameters anchor_params = None if args.config and 'anchor_parameters' in args.config: anchor_params = parse_anchor_parameters(args.config) # load the model print('Loading model, this may take a second...') model = models.load_model(args.model, backbone_name=args.backbone) # optionally convert the model if args.convert_model: model = models.convert_model(model, anchor_params=anchor_params) # print model summary # print(model.summary()) # layer_outputs = [] # layer_names = ['res2c_relu', # C2 # 'res3b3_relu', # C3 # 'res4b22_relu', # C4 # 'P2', # P2 # 'P3', # P3 # 'P4', # P4 # # 'regression_submodel', # Subreg # # 'classification_submodel', # SubClas # 'regression', # Regression # 'classification'] # Classification # # for layer in model.layers: # if layer.name in layer_names: # print('------------------------------------------------------------------------------------------------------------------') # print('Layer found: ', layer.name) # print('\tOutput:', layer.output) # print('------------------------------------------------------------------------------------------------------------------') # layer_outputs.append(layer.output) # # image = preprocess_image(generator.load_image(0)) # image, scale = resize_image(image, args.image_min_side, args.image_max_side) # # activation_model = keras.Model(inputs=model.input, outputs=layer_outputs) # activations = activation_model.predict(np.expand_dims(image, axis=0)) # # def display_activation(activations, col_size, row_size, act_index): # activation = activations[act_index] # activation_index=0 # fig, ax = plt.subplots(row_size, col_size, figsize=(row_size*2.5,col_size*1.5)) # for row in range(0,row_size): # for col in range(0,col_size): # ax[row][col].imshow(activation[0, :, :, activation_index], cmap='gray') # activation_index += 1 # plt.savefig('layer_{}.png'.format(layer_names[act_index])) # # display_activation(activations, 8, 8, 0) # display_activation(activations, 8, 8, 1) # display_activation(activations, 8, 8, 2) # display_activation(activations, 8, 8, 3) # display_activation(activations, 8, 8, 4) # display_activation(activations, 8, 8, 5) # # exit() # start evaluation if args.dataset_type == 'coco': from ..utils.coco_eval import evaluate_coco evaluate_coco(generator, model, args.score_threshold) else: average_precisions = evaluate(generator, model, iou_threshold=args.iou_threshold, score_threshold=args.score_threshold, max_detections=args.max_detections, save_path=args.save_path, mask_base_path=args.mask_folder) # print evaluation total_instances = [] precisions = [] F1s = [] for label, (recall, precision, F1, average_precision, num_annotations) in average_precisions.items(): print('{:.0f} instances of class'.format(num_annotations), generator.label_to_name(label), 'with average precision: {:.4f}'.format(average_precision), 'precision: {:.4f}'.format(precision), 'recall: {:.4f}'.format(recall), 'and F1-score: {:.4f}'.format(F1)) total_instances.append(num_annotations) precisions.append(average_precision) F1s.append(F1) if sum(total_instances) == 0: print('No test instances found.') return print( 'mAP using the weighted average of precisions among classes: {:.4f}' .format( sum([a * b for a, b in zip(total_instances, precisions)]) / sum(total_instances))) print('mAP: {:.4f}'.format( sum(precisions) / sum(x > 0 for x in total_instances))) print('mF1: {:.4f}'.format( sum(F1s) / sum(x > 0 for x in total_instances)))
# **common_args # ) generator = PascalVocGenerator('datasets/VOC2007', 'test', shuffle_groups=False, skip_truncated=False, skip_difficult=True, **common_args) model_path = 'snapshots/2019-08-25/resnet101_pascal_07_0.7352.h5' # load retinanet model import keras.backend as K K.clear_session() K.set_learning_phase(1) model = models.load_model(model_path, backbone_name='resnet101') # if the model is not converted to an inference model, use the line below # see: https://github.com/fizyr/keras-retinanet#converting-a-training-model-to-inference-model model = models.convert_model(model) average_precisions = evaluate(generator, model, epoch=0) # compute per class average precision total_instances = [] precisions = [] for label, (average_precision, num_annotations) in average_precisions.items(): print('{:.0f} instances of class'.format(num_annotations), generator.label_to_name(label), 'with average precision: {:.4f}'.format(average_precision)) total_instances.append(num_annotations) precisions.append(average_precision) mean_ap = sum(precisions) / sum(x > 0 for x in total_instances) print('mAP: {:.4f}'.format(mean_ap))
def main(args=None): # parse arguments if args is None: args = sys.argv[1:] args = parse_args(args) # make sure keras is the minimum required version check_keras_version() # optionally choose specific GPU if args.gpu: os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu keras.backend.tensorflow_backend.set_session(get_session()) # make save path if it doesn't exist if args.save_path is not None and not os.path.exists(args.save_path): os.makedirs(args.save_path) # optionally load config parameters if args.config: args.config = read_config_file(args.config) # create the generator generator = create_generator(args) # optionally load anchor parameters anchor_params = None if args.config and 'anchor_parameters' in args.config: anchor_params = parse_anchor_parameters(args.config) # load the model print('Loading model, this may take a second...') model = models.load_model(args.model, backbone_name=args.backbone) # optionally convert the model if args.convert_model: model = models.convert_model(model, anchor_params=anchor_params) # print model summary # print(model.summary()) # start evaluation if args.dataset_type == 'coco': from ..utils.coco_eval import evaluate_coco evaluate_coco(generator, model, args.score_threshold) else: average_precisions = evaluate(generator, model, iou_threshold=args.iou_threshold, score_threshold=args.score_threshold, max_detections=args.max_detections, save_path=args.save_path) # print evaluation total_instances = [] precisions = [] for label, (average_precision, num_annotations) in average_precisions.items(): print('{:.0f} instances of class'.format(num_annotations), generator.label_to_name(label), 'with average precision: {:.4f}'.format(average_precision)) total_instances.append(num_annotations) precisions.append(average_precision) if sum(total_instances) == 0: print('No test instances found.') return print( 'mAP using the weighted average of precisions among classes: {:.4f}' .format( sum([a * b for a, b in zip(total_instances, precisions)]) / sum(total_instances))) print('mAP: {:.4f}'.format( sum(precisions) / sum(x > 0 for x in total_instances))) return precisions, total_instances
def produce(self, *, inputs: Inputs, timeout: float = None, iterations: int = None) -> CallResult[Outputs]: """ Produce image detection predictions. Parameters ---------- inputs : numpy ndarray of size (n_images, dimension) containing the d3m Index, image name, and bounding box for each image. Returns ------- outputs : A d3m dataframe container with the d3m index, image name, bounding boxes as a string (8 coordinate format), and confidence scores. """ iou_threshold = 0.5 # Bounding box overlap threshold for false positive or true positive score_threshold = 0.05 # The score confidence threshold to use for detections max_detections = 100 # Maxmimum number of detections to use per image # create the generator generator = self._create_generator(self.annotations, self.classes, shuffle_groups=False) # Convert training model to inference model inference_model = models.convert_model(self.training_model) # Assemble output lists ## Generate predicted bounding boxes (8-coordinate format, list) boxes, scores = self._evaluate_model(generator, inference_model, iou_threshold, score_threshold, max_detections, self.hyperparams['output']) ## Convert predicted boxes from a list of arrays to a list of strings boxes = np.array(boxes).tolist() boxes = list(map(lambda x: ",".join(map(str, x)), boxes)) ## Generate list of image names and d3m indices corresponding to predicted bounding boxes img_list = [ os.path.basename(list) for list in self.annotations['img_file'].tolist() ] d3m_idx = inputs.d3mIndex.tolist() print(len(d3m_idx), file=sys.__stdout__) print(len(img_list), file=sys.__stdout__) print(len(boxes), file=sys.__stdout__) print(len(scores), file=sys.__stdout__) ## Assemble in a Pandas DataFrame results = pd.DataFrame({ 'd3mIndex': d3m_idx, 'image': img_list, 'bounding_box': boxes, 'confidence': scores }) # Convert to DataFrame container results_df = d3m_DataFrame(results) ## Assemble first output column ('d3mIndex) col_dict = dict( results_df.metadata.query((metadata_base.ALL_ELEMENTS, 0))) col_dict['structural_type'] = type("1") col_dict['name'] = 'd3mIndex' col_dict['semantic_types'] = ( 'http://schema.org/Integer', 'https://metadata.datadrivendiscovery.org/types/PrimaryKey') results_df.metadata = results_df.metadata.update( (metadata_base.ALL_ELEMENTS, 0), col_dict) ## Assemble second output column ('image') col_dict = dict( results_df.metadata.query((metadata_base.ALL_ELEMENTS, 1))) col_dict['structural_type'] = type("1") col_dict['name'] = 'image' col_dict['semantic_types'] = ( 'http://schema.org/Text', 'https://metadata.datadrivendiscovery.org/types/Attribute') results_df.metadata = results_df.metadata.update( (metadata_base.ALL_ELEMENTS, 1), col_dict) ## Assemble third output column ('bounding_box') col_dict = dict( results_df.metadata.query((metadata_base.ALL_ELEMENTS, 2))) col_dict['structural_type'] = type("1") col_dict['name'] = 'bounding_box' col_dict['semantic_types'] = ( 'http://schema.org/Text', 'https://metadata.datadrivendiscovery.org/types/PredictedTarget', 'https://metadata.datadrivendiscovery.org/types/BoundingPolygon') results_df.metadata = results_df.metadata.update( (metadata_base.ALL_ELEMENTS, 2), col_dict) ## Assemble fourth output column ('confidence') col_dict = dict( results_df.metadata.query((metadata_base.ALL_ELEMENTS, 3))) col_dict['structural_type'] = type("1") col_dict['name'] = 'confidence' col_dict['semantic_types'] = ( 'http://schema.org/Integer', 'https://metadata.datadrivendiscovery.org/types/Score') results_df.metadata = results_df.metadata.update( (metadata_base.ALL_ELEMENTS, 3), col_dict) return CallResult(results_df)
def main(): cfg, args = _parse_args() torch.manual_seed(args.seed) output_base = cfg.OUTPUT_DIR if len(cfg.OUTPUT_DIR) > 0 else './output' exp_name = '-'.join([ datetime.now().strftime("%Y%m%d-%H%M%S"), cfg.MODEL.ARCHITECTURE, str(cfg.INPUT.IMG_SIZE) ]) output_dir = get_outdir(output_base, exp_name) with open(os.path.join(output_dir, 'config.yaml'), 'w', encoding='utf-8') as file_writer: # cfg.dump(stream=file_writer, default_flow_style=False, indent=2, allow_unicode=True) file_writer.write(pyaml.dump(cfg)) logger = setup_logger(file_name=os.path.join(output_dir, 'train.log'), control_log=False, log_level='INFO') # create model model = create_model(cfg.MODEL.ARCHITECTURE, num_classes=cfg.MODEL.NUM_CLASSES, pretrained=True, in_chans=cfg.INPUT.IN_CHANNELS, drop_rate=cfg.MODEL.DROP_RATE, drop_connect_rate=cfg.MODEL.DROP_CONNECT, global_pool=cfg.MODEL.GLOBAL_POOL) os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu gpu_list = list(map(int, args.gpu.split(','))) device = 'cuda' if len(gpu_list) == 1: model.cuda() torch.backends.cudnn.benchmark = True elif len(gpu_list) > 1: model = nn.DataParallel(model, device_ids=gpu_list) model = convert_model(model).cuda() torch.backends.cudnn.benchmark = True else: device = 'cpu' logger.info('device: {}, gpu_list: {}'.format(device, gpu_list)) optimizer = create_optimizer(cfg, model) # optionally initialize from a checkpoint if args.initial_checkpoint and os.path.isfile(args.initial_checkpoint): load_checkpoint(model, args.initial_checkpoint) # optionally resume from a checkpoint resume_state = None resume_epoch = None if args.resume and os.path.isfile(args.resume): resume_state, resume_epoch = resume_checkpoint(model, args.resume) if resume_state and not args.no_resume_opt: if 'optimizer' in resume_state: optimizer.load_state_dict(resume_state['optimizer']) logger.info('Restoring optimizer state from [{}]'.format( args.resume)) start_epoch = 0 if args.start_epoch is not None: start_epoch = args.start_epoch elif resume_epoch is not None: start_epoch = resume_epoch model_ema = None if cfg.SOLVER.EMA: # Important to create EMA model after cuda() model_ema = ModelEma(model, decay=cfg.SOLVER.EMA_DECAY, device=device, resume=args.resume) lr_scheduler, num_epochs = create_scheduler(cfg, optimizer) if lr_scheduler is not None and start_epoch > 0: lr_scheduler.step(start_epoch) # summary print('=' * 60) print(cfg) print('=' * 60) print(model) print('=' * 60) summary(model, (3, cfg.INPUT.IMG_SIZE, cfg.INPUT.IMG_SIZE)) # dataset dataset_train = Dataset(cfg.DATASETS.TRAIN) dataset_valid = Dataset(cfg.DATASETS.TEST) train_loader = create_loader(dataset_train, cfg, is_training=True) valid_loader = create_loader(dataset_valid, cfg, is_training=False) # loss function if cfg.SOLVER.LABEL_SMOOTHING > 0: train_loss_fn = LabelSmoothingCrossEntropy( smoothing=cfg.SOLVER.LABEL_SMOOTHING).to(device) validate_loss_fn = nn.CrossEntropyLoss().to(device) else: train_loss_fn = nn.CrossEntropyLoss().to(device) validate_loss_fn = train_loss_fn eval_metric = cfg.SOLVER.EVAL_METRIC best_metric = None best_epoch = None saver = CheckpointSaver( checkpoint_dir=output_dir, recovery_dir=output_dir, decreasing=True if eval_metric == 'loss' else False) try: for epoch in range(start_epoch, num_epochs): train_metrics = train_epoch(epoch, model, train_loader, optimizer, train_loss_fn, cfg, logger, lr_scheduler=lr_scheduler, saver=saver, device=device, model_ema=model_ema) eval_metrics = validate(epoch, model, valid_loader, validate_loss_fn, cfg, logger) if model_ema is not None: ema_eval_metrics = validate(epoch, model_ema.ema, valid_loader, validate_loss_fn, cfg, logger) eval_metrics = ema_eval_metrics if lr_scheduler is not None: # step LR for next epoch lr_scheduler.step(epoch + 1, eval_metrics[eval_metric]) update_summary(epoch, train_metrics, eval_metrics, os.path.join(output_dir, 'summary.csv'), write_header=best_metric is None) if saver is not None: # save proper checkpoint with eval metric save_metric = eval_metrics[eval_metric] best_metric, best_epoch = saver.save_checkpoint( model, optimizer, cfg, epoch=epoch, model_ema=model_ema, metric=save_metric) except KeyboardInterrupt: pass if best_metric is not None: logger.info('*** Best metric: {0} (epoch {1})'.format( best_metric, best_epoch))
def main(args=None): iou_thres_vec = [] if sys.argv[1:] == []: print('Please give at least one value for IoU threshold.') exit(0) for v in sys.argv[1:]: iou_thres_vec.append(float(v)) print('Doing job for IoU values:', iou_thres_vec) # make sure keras is the minimum required version check_keras_version() # define base paths model_base_path = '/path/snapshots/' data_base_path = '/path/dataset/' out_imgs_base_path = '/path/out_imgs/' # define number of experiments and k-folds experiments = ['1'] #,'2','3','4'] kfolds = ['1'] #,'2','3','4','5'] # loop for each experiment and k-fold for exp in experiments: # set experiment name if exp == '1': data_name = 'cns_stratified' elif exp == '2': data_name = 'cns_unseen_split' elif exp == '3': data_name = 'all_stratified' elif exp == '4': data_name = 'all_unseen_split' for kf in kfolds: # set names model_name = 'resnet101_fpn4_1000_sc4_ar3_cycLRexp-8_allDataAugm_350-450_exp' + exp + '_k' + kf model_path = model_base_path + model_name + '/resnet101_ivm.h5' data_path = data_base_path + 'image_sets/' + data_name + '/k_' + kf save_path = out_imgs_base_path + model_name # copy data image_set to data_base_path files = os.listdir(data_path) for f in files: if f.endswith('.txt'): f = data_path + '/' + f dst = data_base_path + 'image_sets/' # print('File copied\n\tFROM:', f, '\n\tTO:', dst) shutil.copy(f, dst) # optionally choose specific GPU os.environ['CUDA_VISIBLE_DEVICES'] = '0' keras.backend.tensorflow_backend.set_session(get_session()) # load the model print('Loading model, this may take a second...') model = models.load_model(model_path, backbone_name='resnet101') # convert the model model = models.convert_model(model) print('Loaded.') # create the generator generator = IVMGenerator(data_base_path, 'val', image_min_side=1000, image_max_side=1400) # # Grid search # md = 500 nms_thres_vec = np.arange(.05, 1., .05) score_thres_vec = np.arange(.05, 1., .05) # output values outputs = [] # varying params for it in iou_thres_vec: for nt in nms_thres_vec: for st in score_thres_vec: evaluate_model(generator=generator, model=model, nt=nt, it=it, st=st, md=md, save_path=None, mask='/path/dataset/all/masks', output=outputs) # save in data frame format df = pd.DataFrame(data=outputs) # ensure directory created first and save file makedirs(save_path) out_path = save_path + '/params_search.csv' df.to_csv(out_path, index=None, header=True) # # Get best set of parameters # # compute measure avg_measure = (df['f1_score'] + df['average_precision']) / 2 df['avg_measure'] = avg_measure # set best param values best = df.iloc[df['avg_measure'].idxmax()] md = best['max_detections'].astype(int) it = best['iou_threshold'] nt = best['nms_threshold'] st = best['score_threshold'] # create the generator for test dataset generator = IVMGenerator(data_base_path, 'test', image_min_side=1000, image_max_side=1400) # perform inference in test dataset outputs = [] # varying params evaluate_model(generator=generator, model=model, nt=nt, it=it, st=st, md=md, save_path=save_path, mask='/path/dataset/all/masks', output=outputs) # save in data frame format df = pd.DataFrame(data=outputs) out_path = save_path + '/best_output.csv' df.to_csv(out_path, index=None, header=True)
def produce(self, *, inputs: Inputs, timeout: float = None, iterations: int = None) -> CallResult[Outputs]: """ Produce image detection predictions. Parameters ---------- inputs : numpy ndarray of size (n_images, dimension) containing the d3m Index, image name, and bounding box for each image. Returns ------- outputs : A d3m dataframe container with the d3m index, image name, bounding boxes as a string (8 coordinate format), and confidence scores. """ iou_threshold = 0.5 # Bounding box overlap threshold for false positive or true positive score_threshold = 0.05 # The score confidence threshold to use for detections max_detections = 100 # Maxmimum number of detections to use per image # Convert training model to inference model inference_model = models.convert_model(self.training_model) # Generate image paths image_cols = inputs.metadata.get_columns_with_semantic_type('https://metadata.datadrivendiscovery.org/types/FileName') self.base_dir = [inputs.metadata.query((metadata_base.ALL_ELEMENTS, t))['location_base_uris'][0].replace('file:///', '/') for t in image_cols] self.image_paths = np.array([[os.path.join(self.base_dir, filename) for filename in inputs.iloc[:,col]] for self.base_dir, col in zip(self.base_dir, image_cols)]).flatten() self.image_paths = pd.Series(self.image_paths) # Initialize output objects box_list = [] score_list = [] image_name_list = [] # Predict bounding boxes and confidence scores for each image image_list = [x for i, x in enumerate(self.image_paths.tolist()) if self.image_paths.tolist().index(x) == i] start_time = time.time() print('Starting testing...', file = sys.__stdout__) for i in image_list: image = read_image_bgr(i) # preprocess image for network image = preprocess_image(image) image, scale = resize_image(image) boxes, scores, labels = inference_model.predict_on_batch(np.expand_dims(image, axis = 0)) # correct for image scale boxes /= scale for box, score in zip(boxes[0], scores[0]): if score < 0.5: break b = box.astype(int) box_list.append(b) score_list.append(score) image_name_list.append(i * len(b)) print(f'Testing complete. Testing took {time.time()-start_time} seconds.', file = sys.__stdout__) ## Convert predicted boxes from a list of arrays to a list of strings boxes = np.array(box_list).tolist() boxes = list(map(lambda x : [x[0], x[1], x[0], x[3], x[2], x[3], x[2], x[1]], boxes)) # Convert to 8 coordinate format for D3M boxes = list(map(lambda x : ",".join(map(str, x)), boxes)) # Create mapping between image names and D3M index input_df = pd.DataFrame({ 'd3mIndex': inputs.d3mIndex, 'image': [os.path.basename(list) for list in self.image_paths] }) d3mIdx_image_mapping = input_df.set_index('image').T.to_dict('list') # Extract values for image name keys and get missing image predictions (if they exist) image_name_list = [os.path.basename(list) for list in image_name_list] d3mIdx = [d3mIdx_image_mapping.get(key) for key in image_name_list] empty_predictions_image_names = [k for k,v in d3mIdx_image_mapping.items() if v not in d3mIdx] d3mIdx = [item for sublist in d3mIdx for item in sublist] # Flatten list of lists ## Assemble in a Pandas DataFrame results = pd.DataFrame({ 'd3mIndex': d3mIdx, 'bounding_box': boxes, 'confidence': score_list }) # D3M metrics evaluator needs at least one prediction per image. If RetinaNet does not return # predictions for an image, create a dummy empty prediction row to add to results_df for that # missing image. if len(empty_predictions_image_names) != 0: # Create data frame of empty predictions for missing each image and concat with results. # Sort results_df. empty_predictions_df = self._fill_empty_predictions(empty_predictions_image_names, d3mIdx_image_mapping) results_df = pd.concat([results, empty_predictions_df]).sort_values('d3mIndex') # Convert to DataFrame container results_df = d3m_DataFrame(results_df) ## Assemble first output column ('d3mIndex) col_dict = dict(results_df.metadata.query((metadata_base.ALL_ELEMENTS, 0))) col_dict['structural_type'] = type("1") col_dict['name'] = 'd3mIndex' col_dict['semantic_types'] = ('http://schema.org/Integer', 'https://metadata.datadrivendiscovery.org/types/PrimaryKey') results_df.metadata = results_df.metadata.update((metadata_base.ALL_ELEMENTS, 0), col_dict) ## Assemble second output column ('bounding_box') col_dict = dict(results_df.metadata.query((metadata_base.ALL_ELEMENTS, 1))) col_dict['structural_type'] = type("1") col_dict['name'] = 'bounding_box' col_dict['semantic_types'] = ('http://schema.org/Text', 'https://metadata.datadrivendiscovery.org/types/PredictedTarget', 'https://metadata.datadrivendiscovery.org/types/BoundingPolygon') results_df.metadata = results_df.metadata.update((metadata_base.ALL_ELEMENTS, 1), col_dict) ## Assemble third output column ('confidence') col_dict = dict(results_df.metadata.query((metadata_base.ALL_ELEMENTS, 2))) col_dict['structural_type'] = type("1") col_dict['name'] = 'confidence' col_dict['semantic_types'] = ('http://schema.org/Integer', 'https://metadata.datadrivendiscovery.org/types/Score') results_df.metadata = results_df.metadata.update((metadata_base.ALL_ELEMENTS, 2), col_dict) return CallResult(results_df)