Beispiel #1
0
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)
Beispiel #2
0
 def generate_anchors(self, image_shape):
     anchor_params = None
     if self.config and 'anchor_parameters' in self.config:
         anchor_params = parse_anchor_parameters(self.config)
     return anchors_for_shape(image_shape,
                              pyramid_levels=self.fpn_layers,
                              anchor_params=anchor_params,
                              shapes_callback=self.compute_shapes)
Beispiel #3
0
def create_models(backbone_retinanet,
                  num_classes,
                  freeze_backbone=False,
                  lr=1e-5,
                  config=None):
    """ Creates three models (model, training_model, prediction_model).

    Args
        backbone_retinanet : A function to call to create a retinanet model with a given backbone.
        num_classes        : The number of classes to train.
        weights            : The weights to load into the model.
        multi_gpu          : The number of GPUs to use for training.
        freeze_backbone    : If True, disables learning for the backbone.
        config             : Config parameters, None indicates the default configuration.

    Returns
        model            : The base model. This is also the model that is saved in snapshots.
        training_model   : The training model. If multi_gpu=0, this is identical to model.
        prediction_model : The model wrapped with utility functions to perform object detection (applies regression values and performs NMS).
    """

    modifier = freeze_model if freeze_backbone else None

    # load anchor parameters, or pass None (so that defaults will be used)
    anchor_params = None
    num_anchors = None
    if config and 'anchor_parameters' in config:
        anchor_params = parse_anchor_parameters(config)
        num_anchors = anchor_params.num_anchors()

    # Keras recommends initialising a multi-gpu model on the CPU to ease weight sharing, and to prevent OOM errors.
    # optionally wrap in a parallel model

    model = backbone_retinanet(num_classes,
                               num_anchors=num_anchors,
                               modifier=modifier)
    training_model = model
    # make prediction model
    prediction_model = retinanet_bbox(model=model, anchor_params=anchor_params)

    # compile model
    training_model.compile(loss={
        'regression': losses.smooth_l1(),
        'classification': losses.focal()
    },
                           optimizer=keras.optimizers.adam(lr=lr,
                                                           clipnorm=0.001))

    return model, training_model, prediction_model
Beispiel #4
0
def create_models(fl_gamma,
                  fl_alpha,
                  r_weight,
                  c_weight,
                  p_weight,
                  train_type,
                  sample_t,
                  backbone_retinanet,
                  num_classes,
                  weights,
                  class_weights,
                  loss_weights,
                  multi_gpu=0,
                  freeze_backbone=False,
                  lr=1e-5,
                  config=None):
    """ Creates three models (model, training_model, prediction_model).
    Args
        backbone_retinanet : A function to call to create a retinanet model with a given backbone.
        num_classes        : The number of classes to train.
        weights            : The weights to load into the model.
        multi_gpu          : The number of GPUs to use for training.
        freeze_backbone    : If True, disables learning for the backbone.
        config             : Config parameters, None indicates the default configuration.
    Returns
        model            : The base model. This is also the model that is saved in snapshots.
        training_model   : The training model. If multi_gpu=0, this is identical to model.
        prediction_model : The model wrapped with utility functions to perform object detection (applies regression values and performs NMS).
    """

    modifier = freeze_model if freeze_backbone else None

    # load anchor parameters, or pass None (so that defaults will be used)
    anchor_params = None
    num_anchors = None
    if config and 'anchor_parameters' in config:
        anchor_params = parse_anchor_parameters(config)
        num_anchors = anchor_params.num_anchors()

    # Keras recommends initialising a multi-gpu model on the CPU to ease weight sharing, and to prevent OOM errors.
    # optionally wrap in a parallel model
    if multi_gpu > 1:
        from keras.utils import multi_gpu_model
        with tf.device('/cpu:0'):
            model = model_with_weights(backbone_retinanet(
                num_classes, num_anchors=num_anchors, modifier=modifier),
                                       weights=weights,
                                       skip_mismatch=True)
        training_model = multi_gpu_model(model, gpus=multi_gpu)
    else:
        model = model_with_weights(backbone_retinanet(num_classes,
                                                      train_type,
                                                      num_anchors=num_anchors,
                                                      modifier=modifier),
                                   weights=weights,
                                   skip_mismatch=True)
        training_model = model

    # make prediction model
    prediction_model = retinanet_bbox(model=model, anchor_params=anchor_params)

    if train_type == "single":
        # compile model

        training_model.compile(
            loss={
                'regression':
                losses.smooth_l1(r_weight),
                ## HERE THE INPUT ARGUMENTS CAN BE GIVEN: default focal(alpha=0.25, gamma=2.0)
                ## gamma: the actual "focusing parameter"
                'classification':
                losses.focal(c_weight, fl_alpha, fl_gamma, class_weights)
            },
            optimizer=keras.optimizers.adam(lr=lr, clipnorm=0.001),
            #sample_weight_mode="temporal",
            #sample_weights=sample_t
        )

    elif train_type == "multi":
        training_model.compile(
            loss={
                'regression':
                losses.smooth_l1(r_weight),
                ## HERE THE INPUT ARGUMENTS CAN BE GIVEN: default focal(alpha=0.25, gamma=2.0)
                ## gamma: the actual "focusing parameter"
                'classification_artefact':
                losses.focal(c_weight, fl_alpha, fl_gamma),
                'classification_polyp':
                losses.focal2(p_weight, fl_alpha, fl_gamma)
            },
            optimizer=keras.optimizers.adam(lr=lr, clipnorm=0.001)
            #loss_weights=loss_weights
        )

    return model, training_model, prediction_model
Beispiel #5
0
def main(args=None):
    # parse arguments
    if args is None:
        args = sys.argv[1:]
    args = parse_args(args)

    # create object that stores backbone information
    #backbone = models.backbone(args.backbone)
    backbone = models.backbone(args.backbone)

    # 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())

    # optionally load config parameters
    if args.config:
        args.config = read_config_file(args.config)

    # create the generators
    #print(args)
    train_generator, validation_generator = create_generators(
        args, backbone.preprocess_image)

    # Log configs
    #run.log('batch-size', args.batch_size)
    #run.log('gamma', args.fl_gamma)
    #run.log('alpha', args.fl_alpha)
    #run.log('lr', args.lr)
    #run.log('neg-overlap', args.neg_overlap)
    #run.log('pos-overlap', args.pos_overlap)
    #run.log('fpn-layers', args.fpn_layers)

    if args.class_weights is not None:
        if args.class_weights == "cw1":
            polyp_weight = 0.25
            #class_weights = {'classification': {0:a_w, 1:a_w, 2:a_w, 3:a_w, 4:a_w, 5:a_w, 6:a_w, 7:polyp_weight}, 'regression': {0:0.25, 1:0.25, 2:0.25, 3:0.25}}
            #class_weights = {'classification': [polyp_weight, a_w, a_w, a_w, a_w, a_w, a_w, a_w]}
        elif args.class_weights == "cw2":
            polyp_weight = 0.5
        elif args.class_weights == "cw3":
            polyp_weight = 0.75
        a_w = (1 - polyp_weight) / 7
        #class_weights = {'classification': [polyp_weight, a_w, a_w, a_w, a_w, a_w, a_w, a_w]}
        class_weights = [polyp_weight, a_w, a_w, a_w, a_w, a_w, a_w, a_w]
    else:
        class_weights = None

    if args.loss_weights is None:
        loss_weights = [1, 1]
    elif args.loss_weights == "lw0":
        loss_weights = [1, 1, 1]
    elif args.loss_weights == "lw1":
        loss_weights = [1, 1, 3]
    elif args.loss_weights == "lw2":
        loss_weights = [1, 1, 10]
    elif args.loss_weights == "lw3":
        loss_weights = [1, 1, 20]

    # create the model
    if args.snapshot is not None:
        print('Loading model, this may take a second...')
        model = models.load_model(os.path.join(args.data_dir, args.snapshot),
                                  backbone_name=args.backbone)
        training_model = model
        anchor_params = None
        if args.config and 'anchor_parameters' in args.config:
            anchor_params = parse_anchor_parameters(args.config)
        prediction_model = retinanet_bbox(model=model,
                                          anchor_params=anchor_params)
    else:
        if args.weights is None and args.imagenet_weights:
            weights = backbone.download_imagenet()
        else:
            weights = args.weights
        # default to imagenet if nothing else is specified
        ## SO the file that is downloaded is actually only the weights
        ## this means that I should be able to use --weights to give it my own model
        sample_test = np.array([[0.25, 0.25, 0.25, 0.25, 0, 0, 0, 0],
                                [10, 10, 10, 10, 10, 10, 10, 10]])
        print('Creating model, this may take a second...')
        model, training_model, prediction_model = create_models(
            backbone_retinanet=backbone.retinanet,
            num_classes=train_generator.num_classes(),
            weights=weights,
            class_weights=class_weights,
            loss_weights=loss_weights,
            multi_gpu=args.multi_gpu,
            freeze_backbone=args.freeze_backbone,
            lr=args.lr,
            config=args.config,
            fl_gamma=args.fl_gamma,
            fl_alpha=args.fl_alpha,
            c_weight=args.c_weight,
            r_weight=args.r_weight,
            p_weight=args.p_weight,
            train_type=args.train_type,
            sample_t=sample_test)

    # print model summary
    #print(model.summary())

    # this lets the generator compute backbone layer shapes using the actual backbone model
    if 'vgg' in args.backbone or 'densenet' in args.backbone:
        train_generator.compute_shapes = make_shapes_callback(model)
        if validation_generator:
            validation_generator.compute_shapes = train_generator.compute_shapes

    # create the callbacks
    callbacks = create_callbacks(
        model,
        training_model,
        prediction_model,
        validation_generator,
        args,
    )

    # Use multiprocessing if workers > 0
    if args.workers > 0:
        use_multiprocessing = True
    else:
        use_multiprocessing = False

    temp_df = pd.read_csv(
        os.path.join(args.data_dir, args.annotations),
        names=["image_path", "x1", "y1", "x2", "y2", "object_id"])
    im_count = len(set(list(temp_df.image_path)))

    # start training
    training_model.fit_generator(generator=train_generator,
                                 steps_per_epoch=int(im_count /
                                                     args.batch_size),
                                 epochs=args.epochs,
                                 verbose=1,
                                 callbacks=callbacks,
                                 workers=args.workers,
                                 use_multiprocessing=use_multiprocessing,
                                 max_queue_size=args.max_queue_size
                                 #class_weight=class_weights
                                 )
Beispiel #6
0
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)
    print('Done')

    # optionally convert the model
    if args.convert_model:
        model = models.convert_model(model, anchor_params=anchor_params)

    # start evaluation
    if args.dataset_type == 'coco':
        from retinanet.utils.coco_eval import evaluate_coco
        evaluate_coco(generator, model, args.score_threshold)

    elif args.dataset_type == 'ead':

        false_positives, true_positives, iou, average_precisions, image_names, detection_list, scores_list, \
            labels_list, FP_list = evaluate(
                generator,
                model,
                iou_threshold=args.iou_threshold,
                score_threshold=args.score_threshold,
                max_detections=args.max_detections,
                save_path=args.save_path,
                im_threshold=args.im_threshold)

        #  calculate number of FP and TP:
        FP_sum = 0
        TP_sum = 0
        GT_sum = 0
        for i in range(len(false_positives)):
            FP_sum += int(false_positives[i][0])
            TP_sum += int(true_positives[i][0])
            GT_sum += int(true_positives[i][1])
        precision_self = TP_sum / GT_sum
        recall_self = TP_sum / (FP_sum + TP_sum)

        print("AP's: ", average_precisions)
        print("FP: ", false_positives)
        print("Total False Positives: ", FP_sum)
        print("TP: ", true_positives)
        print("Total True Positives: ", TP_sum)
        print("Overall precision: {:.2f}".format(precision_self))
        print("Overall recall: {:.2f}".format(recall_self))

        # 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

        mIoU = np.mean(iou)
        print("len(iou): ", len(iou))
        print_mAP = sum(precisions) / sum(x > 0 for x in total_instances)

        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(print_mAP))
        print('mIoU: {:.4f}'.format(mIoU))
        print('EAD Score (old): {:.4f}'.format(0.8 * print_mAP + 0.2 * mIoU))
        print('EAD Score (new): {:.4f}'.format(0.6 * print_mAP + 0.4 * mIoU))

        return precisions, total_instances, iou, image_names, detection_list, scores_list, labels_list, FP_list

    elif args.dataset_type == 'polyp' and args.mode == 'scoring':

        TP, FP, TN, FN, p_count = evaluate_polyp(
            generator,
            model,
            args.data_dir,
            args.val_dir,
            args.val_annotations,
            args.mode,
            args.classes,
            iou_threshold=args.iou_threshold,
            score_threshold=args.score_threshold,
            max_detections=args.max_detections,
            save_path=args.save_path,
            im_threshold=args.im_threshold)

        prec = precision(TP, FP)
        rec = recall(TP, FN)
        f1_val = f1(prec, rec)
        f2_val = f2(prec, rec)

        print("\nTP: %d\nFP: %d\nFN: %d\nNumber of Polyps: %d\n" %
              (TP, FP, FN, p_count))
        print('precision: {:.4f}'.format(prec))
        print('recall: {:.4f}'.format(rec))
        print('f1: {:.4f}'.format(f1_val))
        print('f2: {:.4f}'.format(f2_val))

        return TP, FP, TN, FN, p_count

    elif args.dataset_type == 'polyp' and args.mode == 'detection':

        detections_df = evaluate_polyp(generator,
                                       model,
                                       args.data_dir,
                                       args.val_dir,
                                       args.val_annotations,
                                       args.mode,
                                       args.classes,
                                       iou_threshold=args.iou_threshold,
                                       score_threshold=args.score_threshold,
                                       max_detections=args.max_detections,
                                       save_path=args.save_path,
                                       im_threshold=args.im_threshold,
                                       save_individual=False)

        return detections_df
Beispiel #7
0
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 retinanet.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