Beispiel #1
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,
                              anchor_params=anchor_params,
                              shapes_callback=self.compute_shapes)
Beispiel #2
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 #3
0
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, 'debug')

    # make sure keras is the minimum required version
    check_keras_version()

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

    # create the display window
    #cv2.namedWindow('Image', cv2.WINDOW_NORMAL)

    if args.loop:
        while run(generator, args, anchor_params=anchor_params):
            pass
    else:
        run(generator, args, anchor_params=anchor_params)
Beispiel #4
0
def create_models(backbone_retinanet, num_classes, weights, num_gpus=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.
        num_gpus : 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 num_gpus=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 num_gpus > 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=num_gpus)
    else:
        model = model_with_weights(backbone_retinanet(num_classes,
                                                      # num_anchors=num_anchors,
                                                      modifier=modifier),
                                   weights=weights, skip_mismatch=True)
        training_model = model

    # make prediction model
    # prediction_model = None
    prediction_model = fsaf_bbox(model=model)

    # compile model
    training_model.compile(
        loss={
            'cls_loss': lambda y_true, y_pred: y_pred,
            'regr_loss': lambda y_true, y_pred: y_pred,
        },
        # optimizer=keras.optimizers.adam(lr=lr, clipnorm=0.001)
        optimizer=keras.optimizers.adam(lr=1e-4)
    )

    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)

    # 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)))
Beispiel #6
0
def main(args=None):

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

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

    # create the model
    if args.snapshot is not None:
        print('Loading model, this may take a second...')
        model = models.load_model(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)
        # compile model
        training_model.compile(
            loss={
                'regression': losses.iou_loss(args.loss, args.loss_weight),
                'classification': losses.focal(),
                'centerness': losses.bce(),
            },
            optimizer=keras.optimizers.Adam(lr=1e-5)
            # optimizer=keras.optimizers.sgd(lr=1e-5, momentum=0.9, decay=1e-5, nesterov=True)
        )

    else:
        weights = args.weights
        # default to imagenet if nothing else is specified
        if weights is None and args.imagenet_weights:
            weights = backbone.download_imagenet()

        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,
            num_gpus=args.num_gpus,
            freeze_backbone=args.freeze_backbone,
            lr=args.lr,
            config=args.config,
            args=args)

    parallel_model = multi_gpu_model(training_model, gpus=2)
    parallel_model.compile(loss={
        'regression':
        losses.iou_loss(args.loss, args.loss_weight),
        'classification':
        losses.focal(),
        'centerness':
        losses.bce(),
    },
                           optimizer=keras.optimizers.Adam(lr=1e-4))

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

    if not args.compute_val_loss:
        validation_generator = None

    # start training
    parallel_model.fit_generator(generator=train_generator,
                                 steps_per_epoch=len(train_generator),
                                 epochs=args.epochs,
                                 verbose=1,
                                 callbacks=callbacks,
                                 validation_data=validation_generator)
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 ..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
Beispiel #8
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)

    # 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
    train_generator, validation_generator = create_generators(
        args, backbone.preprocess_image)

    # create the model
    if args.snapshot is not None:
        print('Loading model, this may take a second...')
        model = models.load_model(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)
        # compile model
        training_model.compile(
            loss={
                'regression': losses.iou(),
                'classification': losses.focal(),
                'centerness': losses.bce(),
            },
            optimizer=keras.optimizers.adam(lr=1e-5)
            # optimizer=keras.optimizers.sgd(lr=1e-5, momentum=0.9, decay=1e-5, nesterov=True)
        )
    else:
        weights = args.weights
        # default to imagenet if nothing else is specified
        if weights is None and args.imagenet_weights:
            weights = backbone.download_imagenet()

        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,
            num_gpus=args.num_gpus,
            freeze_backbone=args.freeze_backbone,
            lr=args.lr,
            config=args.config)

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

    if not args.compute_val_loss:
        validation_generator = None

    # start training
    return training_model.fit_generator(
        generator=train_generator,
        initial_epoch=0,
        steps_per_epoch=args.steps,
        epochs=args.epochs,
        verbose=1,
        callbacks=callbacks,
        workers=args.workers,
        use_multiprocessing=args.multiprocessing,
        max_queue_size=args.max_queue_size,
        validation_data=validation_generator)
Beispiel #9
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 #10
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 #11
0
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, 'training')
    #     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()

    # create object that stores backbone information
    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())

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

    # # Debuging
    # for i in range(1):
    #     inputs, targets = train_generator.__getitem__(i)
    # exit()

    # create the model
    if args.snapshot is not None:
        print('Loading model, this may take a second...')
        model = models.load_model(args.snapshot, backbone_name=args.backbone)

        # When using as a second step for fine-tuning
        for layer in model.layers:
            layer.trainable = True

        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)

        ###################################################################################### BRUNO

        # compile model
        training_model.compile(loss={
            'regression': losses.smooth_l1(),
            'classification': losses.focal()
        },
                               optimizer=keras.optimizers.adam(lr=args.lr,
                                                               clipnorm=0.001))
    else:
        weights = args.weights
        # default to imagenet if nothing else is specified
        if weights is None and args.imagenet_weights:
            weights = backbone.download_imagenet()

        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,
            multi_gpu=args.multi_gpu,
            freeze_backbone=args.freeze_backbone,
            lr=args.lr,
            config=args.config)

    # Print model design
    # print(model.summary())
    # print(training_model.summary())
    # plot_model(model, to_file='model_plot.png', show_shapes=True, show_layer_names=True)
    # exit()

    # Get the number of samples in the training and validations datasets.
    train_size = train_generator.size()
    val_size = validation_generator.size()
    print('Train on {} samples, val on {} samples, with batch size {}.'.format(
        train_size, val_size, args.batch_size))

    # 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,
        train_size,
        [1e-6, 1e-4],
        args,
    )

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

    # check to see if we are attempting to find an optimal learning rate
    # before training for the full number of epochs
    if args.find_lr:
        # initialize the learning rate finder and then train with learning
        # rates ranging from 1e-10 to 1e+1
        print("[INFO] Finding learning rate...")
        lrf = LearningRateFinder(training_model)
        lrf.find(train_generator,
                 1e-10,
                 1e+1,
                 stepsPerEpoch=np.ceil((train_size / float(args.batch_size))),
                 batchSize=args.batch_size)

        # plot the loss for the various learning rates and save the
        # resulting plot to disk
        lrf.plot_loss()
        plt.savefig("lrfind_plot.png")

        # save values into a csv file
        lrf.save_csv("lr_loss.csv")

        # gracefully exit the script so we can adjust our learning rates
        # in the config and then train the network for our full set of
        # epochs
        print("[INFO] Learning rate finder complete")
        print("[INFO] Examine plot and adjust learning rates before training")
        sys.exit(0)

    # Number of epochs and steps for training new layers
    n_epochs = 350
    steps = train_size // args.batch_size

    # start training
    training_model.fit_generator(generator=train_generator,
                                 validation_data=validation_generator,
                                 steps_per_epoch=steps,
                                 epochs=n_epochs,
                                 verbose=1,
                                 callbacks=callbacks,
                                 workers=args.workers,
                                 use_multiprocessing=use_multiprocessing,
                                 max_queue_size=args.max_queue_size)

    # Unfreeze and continue training, to fine-tune.
    # Train longer if the result is not good.
    if True:
        # for layer in model.layers:
        #     if layer.name is 'bn_conv1':
        #         print("Before\t-> Trainable: {}, Freeze: {}".format(layer.trainable, layer.freeze))

        for layer in model.layers:
            layer.trainable = True

        # recompile to apply the change
        model.compile(
            loss={
                'regression': losses.smooth_l1(),
                'classification': losses.focal()
            },
            # Learning rate must be lower for training the entire network
            optimizer=keras.optimizers.adam(lr=args.lr * 0.1, clipnorm=0.001),
            metrics=['accuracy'])

        if args.multi_gpu > 1:
            from keras.utils import multi_gpu_model
            with tf.device('/gpu:1'):
                training_model = multi_gpu_model(model, gpus=args.multi_gpu)
        else:
            training_model = model

        # recompile to apply the change
        training_model.compile(
            loss={
                'regression': losses.smooth_l1(),
                'classification': losses.focal()
            },
            # Learning rate must be lower for training the entire network
            optimizer=keras.optimizers.adam(lr=args.lr * 0.1, clipnorm=0.001),
            metrics=['accuracy'])
        print('Unfreezing all layers.')

        # for layer in model.layers:
        #     if layer.name is 'bn_conv1':
        #         print("After\t-> Trainable: {}, Freeze: {}".format(layer.trainable, layer.freeze))

        # Print training_model design
        # print(model.summary())
        # print(training_model.summary())

        # create the callbacks
        callbacks = create_callbacks(
            model,
            training_model,
            prediction_model,
            validation_generator,
            train_size,
            [1e-8, 1e-6],
            args,
        )

        batch_size = 2  # note that more GPU memory is required after unfreezing the body
        steps = train_size // batch_size
        print('Train on {} samples, val on {} samples, with batch size {}.'.
              format(train_size, val_size, batch_size))
        training_model.fit_generator(generator=train_generator,
                                     validation_data=validation_generator,
                                     steps_per_epoch=steps,
                                     epochs=args.epochs,
                                     initial_epoch=n_epochs,
                                     verbose=1,
                                     callbacks=callbacks,
                                     workers=args.workers,
                                     use_multiprocessing=use_multiprocessing,
                                     max_queue_size=args.max_queue_size)
Beispiel #12
0
def create_models(backbone_retinanet,
                  num_classes,
                  weights,
                  multi_gpu=2,
                  freeze_backbone=False,
                  lr=1e-5,
                  config=None):
    """!@brief
    Creates three models (model, training_model, prediction_model).

    @param backbone_retinanet : A function to call to create a retinanet model with a given backbone.
    @param num_classes        : The number of classes to train.
    @param weights            : The weights to load into the model.
    @param multi_gpu          : The number of GPUs to use for training.
    @param freeze_backbone    : If True, disables learning for the backbone.
    @param 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('/gpu:1'):
            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)  # , cpu_merge=False) # <- recommended for NV-Link
    else:
        model = model_with_weights(backbone_retinanet(num_classes,
                                                      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)

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

    return model, training_model, prediction_model