예제 #1
0
def create_models(backbone_retinanet,
                  num_classes,
                  weights,
                  args,
                  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

    # 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,
                                                          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,
                                                      modifier=modifier),
                                   weights=weights,
                                   skip_mismatch=True)
        training_model = model

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

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

    return model, training_model, prediction_model
예제 #2
0
def main():

    from pprint import pprint

    config = B2Config()

    # pprint(vars(config))
    # exit()

    batch_size = 4
    num_classes = 15
    epochs = 5
    steps_per_epoch = 1000


    parser = Parser(
      config=config,
      batch_size=batch_size,
      num_classes=num_classes) 

    training_model = efficientdet(config, num_classes, weights=None)

    # compile model
    training_model.compile(
        optimizer=Adam(lr=1e-3), 
        loss={
            'regression': smooth_l1(),
            'classification': focal()})

    # print(training_model.summary())

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


    train_dataset_function = parser.get_dataset(filenames='./DATA/train*.tfrecord')

    training_model.fit(
        train_dataset_function, 
        epochs=epochs, 
        steps_per_epoch=steps_per_epoch,)
        # callbacks=callbacks)

    os.makedirs("./checkpoints", exist_ok=True)

    training_model.save("./checkpoints/efficientdetB2_final")
예제 #3
0
    def __init__(self, backbone):
        # a dictionary mapping custom layer names to the correct classes
        self.custom_objects = {
            'UpsampleLike': layers.UpsampleLike,
            'PriorProbability': initializers.PriorProbability,
            'RegressBoxes': layers.RegressBoxes,
            'FilterDetections': layers.FilterDetections,
            'Anchors': layers.Anchors,
            'ClipBoxes': layers.ClipBoxes,
            '_focal': losses.focal(),
            'bce_': losses.bce(),
            'iou_': losses.iou(),
        }

        self.backbone = backbone
        self.validate()
예제 #4
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)

    # create the generator
    generator = create_generator(args)

    # load the model
    print('Loading model, this may take a second...')
    model = keras.models.load_model(args.model, custom_objects=custom_objects)

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

    loss = {'regression': losses.smooth_l1(), 'classification': losses.focal()}

    # start evaluation
    average_precisions = evaluate(
        generator,
        model,
        # loss,
        iou_threshold=args.iou_threshold,
        score_threshold=args.score_threshold,
        max_detections=args.max_detections,
        save_path=args.save_path)

    # print evaluation
    for label, average_precision in average_precisions.items():
        print(generator.label_to_name(label),
              '{:.4f}'.format(average_precision))
    print('mAP: {:.4f}'.format(
        sum(average_precisions.values()) / len(average_precisions)))
예제 #5
0
    def _create_models(self,
                       backbone_retinanet,
                       num_classes,
                       weights,
                       freeze_backbone=False,
                       lr=1e-5):
        """ 
        Creates three models (model, training_model, prediction_model).

        Parameters
        ----------
            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. 
            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
        anchor_params = None
        num_anchors = None

        model = self._model_with_weights(backbone_retinanet(
            num_classes, num_anchors=num_anchors, modifier=modifier),
                                         weights=weights,
                                         skip_mismatch=True)
        training_model = model
        prediction_model = retinanet_bbox(model=model,
                                          anchor_params=anchor_params)
        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
예제 #6
0
파일: backbones.py 프로젝트: purvang3/CV_DL
    def __init__(self, backbone):
        import custom_layers as layers
        import losses
        import initializers
        self.custom_objects = {
            'PriorProbability': initializers.PriorProbability,

            'UpsampleLike': layers.UpsampleLike,
            'RegressBoxes': layers.RegressBoxes,
            'FilterDetections': layers.FilterDetections,
            'Anchors': layers.Anchors,
            'ClipBoxes': layers.ClipBoxes,
            # 'BatchNormalization': layers.BatchNormalization,

            '_smooth_l1': losses.smooth_l1(),
            '_focal': losses.focal(),
        }

        self.backbone = backbone
        self.validate()
예제 #7
0
    def train(self, epochs, backbone_name, evaluation):
        #Compile model
        self.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)
        )
        # create the generators
        train_generator, validation_generator = create_generators(
            self.config, self.dataset)

        # create the callbacks
        callbacks = create_callbacks(
            self.config,
            backbone_name,
            self.model,
            self.training_model,
            self.prediction_model,
            validation_generator,
            evaluation,
            self.log_dir,
        )
        # start training
        return self.training_model.fit_generator(
            generator=train_generator,
            initial_epoch=0,
            steps_per_epoch=self.config.STEPS_PER_EPOCH,
            epochs=epochs,
            verbose=1,
            callbacks=callbacks,
            max_queue_size=10,
            validation_data=validation_generator)
예제 #8
0
def level_select(cls_pred, regr_pred, gt_boxes, feature_shapes, strides, pos_scale=0.2):
    """

    Args:
        cls_pred: (sum(fh * fw), num_classes)
        regr_pred:  (sum(fh * fw), 4)
        gt_boxes:  (MAX_NUM_GT_BOXES, 5)
        feature_shapes: (5, 2)
        strides:
        pos_scale:

    Returns:

    """
    gt_labels = tf.cast(gt_boxes[:, 4], tf.int32)
    gt_boxes = gt_boxes[:, :4]
    focal_loss = focal()
    iou_loss = iou()
    gt_boxes, non_zeros = trim_zeros_graph(gt_boxes)
    num_gt_boxes = tf.shape(gt_boxes)[0]
    gt_labels = tf.boolean_mask(gt_labels, non_zeros)
    level_losses = []
    for level_id in range(len(strides)):
        stride = strides[level_id]
        fh = feature_shapes[level_id][0]
        fw = feature_shapes[level_id][1]
        fa = tf.reduce_prod(feature_shapes, axis=-1)
        start_idx = tf.reduce_sum(fa[:level_id])
        end_idx = start_idx + fh * fw
        cls_pred_i = tf.reshape(cls_pred[start_idx:end_idx], (fh, fw, tf.shape(cls_pred)[-1]))
        regr_pred_i = tf.reshape(regr_pred[start_idx:end_idx], (fh, fw, tf.shape(regr_pred)[-1]))
        proj_boxes = gt_boxes / stride
        x1, y1, x2, y2 = prop_box_graph(proj_boxes, pos_scale, fw, fh)

        def compute_gt_box_loss(args):
            x1_ = args[0]
            y1_ = args[1]
            x2_ = args[2]
            y2_ = args[3]
            gt_box = args[4]
            gt_label = args[5]
            locs_cls_pred_i = cls_pred_i[y1_:y2_, x1_:x2_, :]
            locs_cls_pred_i = tf.reshape(locs_cls_pred_i, (-1, tf.shape(locs_cls_pred_i)[-1]))
            locs_cls_true_i = tf.zeros_like(locs_cls_pred_i)
            gt_label_col = tf.ones_like(locs_cls_true_i[:, 0:1])
            locs_cls_true_i = tf.concat([locs_cls_true_i[:, :gt_label],
                                         gt_label_col,
                                         locs_cls_true_i[:, gt_label + 1:],
                                         ], axis=-1)
            loss_cls = focal_loss(K.expand_dims(locs_cls_true_i, axis=0), K.expand_dims(locs_cls_pred_i, axis=0))
            locs_regr_pred_i = regr_pred_i[y1_:y2_, x1_:x2_, :]
            locs_regr_pred_i = tf.reshape(locs_regr_pred_i, (-1, tf.shape(locs_regr_pred_i)[-1]))

            locs_x = K.arange(x1_, x2_, dtype=tf.float32)
            locs_y = K.arange(y1_, y2_, dtype=tf.float32)
            shift_x = (locs_x + 0.5) * stride
            shift_y = (locs_y + 0.5) * stride
            shift_xx, shift_yy = tf.meshgrid(shift_x, shift_y)
            shift_xx = tf.reshape(shift_xx, (-1,))
            shift_yy = tf.reshape(shift_yy, (-1,))
            shifts = K.stack((shift_xx, shift_yy, shift_xx, shift_yy), axis=-1)
            l = tf.maximum(shifts[:, 0] - gt_box[0], 0)
            t = tf.maximum(shifts[:, 1] - gt_box[1], 0)
            r = tf.maximum(gt_box[2] - shifts[:, 2], 0)
            b = tf.maximum(gt_box[3] - shifts[:, 3], 0)
            locs_regr_true_i = tf.stack([l, t, r, b], axis=-1)
            locs_regr_true_i /= 4.0
            loss_regr = iou_loss(K.expand_dims(locs_regr_true_i, axis=0), K.expand_dims(locs_regr_pred_i, axis=0))
            return loss_cls + loss_regr

        level_loss = tf.map_fn(
            compute_gt_box_loss,
            elems=[x1, y1, x2, y2, gt_boxes, gt_labels],
            dtype=tf.float32
        )
        level_losses.append(level_loss)
    losses = tf.stack(level_losses, axis=-1)
    gt_box_levels = tf.argmin(losses, axis=-1)
    padding_gt_box_levels = tf.ones((MAX_NUM_GT_BOXES - num_gt_boxes), dtype=tf.int64) * -1
    gt_box_levels = tf.concat([gt_box_levels, padding_gt_box_levels], axis=0)
    return gt_box_levels
예제 #9
0
def main(args=None):
    """
    Train an EfficientPose model.

    Args:
        args: parseargs object containing configuration for the training procedure.
    """

    allow_gpu_growth_memory()

    # parse arguments
    if args is None:
        args = sys.argv[1:]
    args = parse_args(args)

    # create the generators
    print("\nCreating the Generators...")
    train_generator, validation_generator = create_generators(args)
    print("Done!")

    num_rotation_parameters = train_generator.get_num_rotation_parameters()
    num_classes = train_generator.num_classes()
    num_anchors = train_generator.num_anchors

    # optionally choose specific GPU
    if args.gpu:
        os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu

    print("\nBuilding the Model...")
    model, prediction_model, all_layers = build_EfficientPose(
        args.phi,
        num_classes=num_classes,
        num_anchors=num_anchors,
        freeze_bn=not args.no_freeze_bn,
        score_threshold=args.score_threshold,
        num_rotation_parameters=num_rotation_parameters)
    print("Done!")
    # load pretrained weights
    if args.weights:
        if args.weights == 'imagenet':
            model_name = 'efficientnet-b{}'.format(args.phi)
            file_name = '{}_weights_tf_dim_ordering_tf_kernels_autoaugment_notop.h5'.format(
                model_name)
            file_hash = WEIGHTS_HASHES[model_name][1]
            weights_path = keras.utils.get_file(file_name,
                                                BASE_WEIGHTS_PATH + file_name,
                                                cache_subdir='models',
                                                file_hash=file_hash)
            model.load_weights(weights_path, by_name=True)
        else:
            print('Loading model, this may take a second...')
            custom_load_weights(filepath=args.weights,
                                layers=all_layers,
                                skip_mismatch=True)
            print("\nDone!")

    # freeze backbone layers
    if args.freeze_backbone:
        # 227, 329, 329, 374, 464, 566, 656
        for i in range(1, [227, 329, 329, 374, 464, 566, 656][args.phi]):
            model.layers[i].trainable = False

    # compile model
    model.compile(
        optimizer=Adam(lr=args.lr, clipnorm=0.001),
        loss={
            'regression':
            smooth_l1(),
            'classification':
            focal(),
            'transformation':
            transformation_loss(model_3d_points_np=train_generator.
                                get_all_3d_model_points_array_for_loss(),
                                num_rotation_parameter=num_rotation_parameters)
        },
        loss_weights={
            'regression': 1.0,
            'classification': 1.0,
            'transformation': 0.02
        })

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

    if not args.compute_val_loss:
        validation_generator = None
    elif args.compute_val_loss and validation_generator is None:
        raise ValueError(
            'When you have no validation data, you should not specify --compute-val-loss.'
        )

    # start training
    return model.fit_generator(generator=train_generator,
                               steps_per_epoch=args.steps,
                               initial_epoch=0,
                               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)
예제 #10
0
파일: sapd_layers.py 프로젝트: zhjpqq/SAPD
def build_meta_select_target(cls_pred,
                             regr_pred,
                             gt_boxes,
                             feature_shapes,
                             strides,
                             shrink_ratio=0.2):
    gt_labels = tf.cast(gt_boxes[:, 4], tf.int32)
    gt_boxes = gt_boxes[:, :4]
    max_gt_boxes = tf.shape(gt_boxes)[0]
    focal_loss = focal()
    iou_loss = iou()
    gt_boxes, non_zeros = trim_padding_boxes(gt_boxes)
    num_gt_boxes = tf.shape(gt_boxes)[0]
    gt_labels = tf.boolean_mask(gt_labels, non_zeros)
    level_losses = []
    for level_id in range(len(strides)):
        stride = strides[level_id]
        fh = feature_shapes[level_id][0]
        fw = feature_shapes[level_id][1]
        fa = tf.reduce_prod(feature_shapes, axis=-1)
        start_idx = tf.reduce_sum(fa[:level_id])
        end_idx = start_idx + fh * fw
        cls_pred_i = tf.reshape(cls_pred[start_idx:end_idx],
                                (fh, fw, tf.shape(cls_pred)[-1]))
        regr_pred_i = tf.reshape(regr_pred[start_idx:end_idx],
                                 (fh, fw, tf.shape(regr_pred)[-1]))
        # (num_gt_boxes, )
        x1, y1, x2, y2 = shrink_and_project_boxes(gt_boxes,
                                                  fw,
                                                  fh,
                                                  stride,
                                                  shrink_ratio=shrink_ratio)

        def compute_gt_box_loss(args):
            x1_ = args[0]
            y1_ = args[1]
            x2_ = args[2]
            y2_ = args[3]
            gt_box = args[4]
            gt_label = args[5]

            def do_match_pixels_in_level():
                locs_cls_pred_i = cls_pred_i[y1_:y2_, x1_:x2_, :]
                locs_cls_pred_i = tf.reshape(
                    locs_cls_pred_i, (-1, tf.shape(locs_cls_pred_i)[-1]))
                locs_cls_true_i = tf.zeros_like(locs_cls_pred_i)
                gt_label_col = tf.ones_like(locs_cls_true_i[:, 0:1])
                locs_cls_true_i = tf.concat([
                    locs_cls_true_i[:, :gt_label],
                    gt_label_col,
                    locs_cls_true_i[:, gt_label + 1:],
                ],
                                            axis=-1)
                loss_cls = focal_loss(tf.expand_dims(locs_cls_true_i, axis=0),
                                      tf.expand_dims(locs_cls_pred_i, axis=0))
                locs_regr_pred_i = regr_pred_i[y1_:y2_, x1_:x2_, :]
                locs_regr_pred_i = tf.reshape(
                    locs_regr_pred_i, (-1, tf.shape(locs_regr_pred_i)[-1]))
                locs_x = tf.cast(tf.range(x1_, x2_), dtype=tf.float32)
                locs_y = tf.cast(tf.range(y1_, y2_), dtype=tf.float32)
                shift_x = (locs_x + 0.5) * stride
                shift_y = (locs_y + 0.5) * stride
                shift_xx, shift_yy = tf.meshgrid(shift_x, shift_y)
                shift_xx = tf.reshape(shift_xx, (-1, ))
                shift_yy = tf.reshape(shift_yy, (-1, ))
                shifts = tf.stack((shift_xx, shift_yy, shift_xx, shift_yy),
                                  axis=-1)
                l = tf.maximum(shifts[:, 0] - gt_box[0], 0)
                t = tf.maximum(shifts[:, 1] - gt_box[1], 0)
                r = tf.maximum(gt_box[2] - shifts[:, 2], 0)
                b = tf.maximum(gt_box[3] - shifts[:, 3], 0)
                locs_regr_true_i = tf.stack([l, t, r, b], axis=-1)
                locs_regr_true_i = locs_regr_true_i / 4.0 / stride
                loss_regr = iou_loss(tf.expand_dims(locs_regr_true_i, axis=0),
                                     tf.expand_dims(locs_regr_pred_i, axis=0))
                return loss_cls + loss_regr

            def do_not_match_pixels_in_level():
                box_loss = tf.constant(1e7, dtype=tf.float32)
                return box_loss

            level_box_loss = tf.cond(
                tf.equal(tf.cast(x1_, tf.int32), tf.cast(x2_, tf.int32))
                | tf.equal(tf.cast(y1_, tf.int32), tf.cast(y2_, tf.int32)),
                do_not_match_pixels_in_level, do_match_pixels_in_level)
            return level_box_loss

        level_loss = tf.map_fn(compute_gt_box_loss,
                               elems=[x1, y1, x2, y2, gt_boxes, gt_labels],
                               dtype=tf.float32)
        level_losses.append(level_loss)
    losses = tf.stack(level_losses, axis=-1)
    gt_box_levels = tf.argmin(losses, axis=-1, output_type=tf.int32)
    padding_gt_box_levels = tf.ones(
        (max_gt_boxes - num_gt_boxes), dtype=tf.int32) * -1
    gt_box_levels = tf.concat([gt_box_levels, padding_gt_box_levels], axis=0)
    return gt_box_levels
예제 #11
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)
예제 #12
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)
예제 #13
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
예제 #14
0
def efficientdet_training(config, LOCAL_ANNOTATIONS_PATH, LOCAL_ROOT_PATH,
                          LOCAL_CLASSES_PATH, LOCAL_VALIDATIONS_PATH,
                          LOCAL_LOGS_PATH, LOCAL_SNAPSHOTS_PATH):

    (model, prediction_model, train_generator, evaluation_generator,
     validation_generator, config) = load_efficient_det(
         config, LOCAL_ANNOTATIONS_PATH, LOCAL_ROOT_PATH, LOCAL_CLASSES_PATH,
         LOCAL_VALIDATIONS_PATH, LOCAL_LOGS_PATH, LOCAL_SNAPSHOTS_PATH)
    #model.summary()

    # create the callbacks
    if config['validation']:
        callbacks = create_callbacks(model, prediction_model,
                                     evaluation_generator,
                                     validation_generator, LOCAL_LOGS_PATH,
                                     LOCAL_SNAPSHOTS_PATH, config)
    else:
        callbacks = create_callbacks(model, prediction_model,
                                     evaluation_generator, train_generator,
                                     LOCAL_LOGS_PATH, LOCAL_SNAPSHOTS_PATH,
                                     config)
    model.compile(optimizer=Adam(lr=1e-3),
                  loss={
                      'regression': smooth_l1(),
                      'classification': focal(gamma=config['focal_gamma'])
                  })

    os.makedirs(LOCAL_LOGS_PATH, exist_ok=True)
    with open(os.path.join(LOCAL_LOGS_PATH, 'config.yaml'), 'w') as file:
        yaml.dump(config, file)
    with open(LOCAL_LOGS_PATH + '/stdout.txt', 'w') as f:
        with redirect_stdout(f):
            print('Path : ', LOCAL_ROOT_PATH)
            start = datetime.now()
            print(f'Started training at: {start}')
            if not validation_generator:
                results = model.fit_generator(
                    generator=train_generator,
                    steps_per_epoch=config['steps_per_epoch'],
                    initial_epoch=0,
                    epochs=config['nb_epoch'],
                    verbose=1,
                    callbacks=callbacks,
                    workers=config['workers'],
                    use_multiprocessing=config['multiprocessing'],
                    max_queue_size=config['max_queue_size'])
            else:
                results = model.fit_generator(
                    generator=train_generator,
                    steps_per_epoch=config['steps_per_epoch'],
                    initial_epoch=0,
                    epochs=config['nb_epoch'],
                    verbose=1,
                    callbacks=callbacks,
                    workers=config['workers'],
                    use_multiprocessing=config['multiprocessing'],
                    max_queue_size=config['max_queue_size'],
                    validation_data=validation_generator)
            end = datetime.now()
            print(f'Completed training at: {end}')
            print(f'Total training time: {diff(start, end)}')
예제 #15
0
def convert(args):
    rot_parameters = {"axis_angle": 3, "rotation_matrix": 9, "quaternion": 4}
    model = model_clean.EfficientPose(
        args.phi,
        num_classes=args.num_classes,
        num_anchors=args.num_anchors,
        freeze_bn=False,
        score_threshold=args.score_threshold,
        num_rotation_parameters=rot_parameters[args.rotation_representation],
        lite=args.lite,
        no_se=args.no_se,
        use_groupnorm=args.use_groupnorm)

    _, _, tflite_model = model.get_models()
    tflite_model(
        [tf.random.normal((1, 512, 512, 3)),
         tf.random.normal((1, 6))])
    #   inp = tf.keras.layers.Input((512,512,3), dtype=tf.uint8)
    #   inp2 = tf.keras.layers.Input((6,))

    #   tflite_raw_model = tfkeras.EfficientNetB0(input_tensor=preprocess_image(inp))
    #   tflite_raw_model = tf.keras.Model(inputs=[inp, inp2], outputs=tflite_raw_model)
    weight_loader.load_weights_rec(tflite_model, args.weights)

    if args.freeze_bn:
        weight_loader.freeze_bn(tflite_model)

    if args.q_aware:
        gen, val = create_generators(args)
        q_aware_model = tfmot.quantization.keras.quantize_model(tflite_model)
        q_aware_model.compile(
            optimizer="adam",
            loss={
                'regression':
                smooth_l1(),
                'classification':
                focal(),
                'transformation':
                transformation_loss(model_3d_points_np=gen.
                                    get_all_3d_model_points_array_for_loss(),
                                    num_rotation_parameter=3)
            },
            loss_weights={
                'regression': 1.0,
                'classification': 1.0,
                'transformation': 0.02
            })
        q_aware_model.fit(gen,
                          steps_per_epoch=1000,
                          initial_epoch=0,
                          epochs=5,
                          verbose=1,
                          validation_data=val)

    #tflite_raw_model.save("models/model.h5")
    tflite_model(
        [tf.random.normal((1, 512, 512, 3)),
         tf.random.normal((1, 6))])
    converter = tf.lite.TFLiteConverter.from_keras_model(tflite_model)
    converter.experimental_new_converter = True
    converter.target_spec.supported_ops = [
        tf.lite.OpsSet.TFLITE_BUILTINS,  # enable TensorFlow Lite ops.
        tf.lite.OpsSet.SELECT_TF_OPS  # enable TensorFlow ops.
    ]
    #converter.representative_dataset = tf.lite.RepresentativeDataset(create_generators(args))
    #converter.optimizations = [tf.lite.Optimize.DEFAULT]
    converter.allow_custom_ops = True
    tflite_model = converter.convert()

    outfile = os.path.join(
        args.models_dir,
        f"{args.base_name}_phi{args.phi}{'_lite' if args.lite else ''}.tflite")
    os.makedirs(args.models_dir, exist_ok=True)
    with open(outfile, 'wb') as f:
        f.write(tflite_model)

    if args.benchmark:
        run_benchmark.benchmark(args)
예제 #16
0
def main(config_file=None):
    cwd = os.getcwd()

    # parse configuration file
    if config_file is None:
        config_file = sys.argv[-1]
        config_file = os.path.join(cwd, config_file)
    config_file_name = config_file.split('/')[-1]
    configs = parse_config(config_file)

    # save config file
    if configs['Train']['save_configs']:
        # confirm save dir
        config_save_path = 'logs/' + configs['Name']
        config_save_path = os.path.join(cwd, config_save_path)
        if not os.path.exists(config_save_path):
            os.mkdir(os.path.join(cwd, config_save_path))
        # copy config file
        config_dst_name = configs['Name'] + '.json'
        config_file_dst = os.path.join(config_save_path, config_dst_name)
        shutil.copy(config_file, config_file_dst)

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

    # optionally choose specific GPU
    if configs['Train']['gpu']:
        os.environ['CUDA_VISIBLE_DEVICES'] = configs['Train']['gpu']
    keras.backend.tensorflow_backend.set_session(get_session())

    # create the generators
    train_generator, validation_generator = create_generators(configs)

    # create the model
    if configs['Train']['load_snapshot'] is not None:
        print('Loading model, this may take a second...')
        model = models.load_model(configs['Train']['load_snapshot'],
                                  backbone=configs['Train']['backbone'])
        training_model = prediction_model = model
    else:
        weights = configs['Train']['weights']
        # default to imagenet if nothing else is specified
        if weights is None and configs['Train']['imagenet_weights']:
            weights = models.download_imagenet(configs['Train']['backbone'])

        print('Creating model, this may take a second...')
        backbone = configs['Train']['backbone']
        num_classes = train_generator.num_classes()
        multi_gpu = configs['Train']['multi_gpu']
        freeze_backbone = configs['Train']['freeze_backbone']

        modifier = freeze_model if freeze_backbone else None

        # 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:
            with tf.device('/cpu:0'):
                retinanet = models.retinanet_backbone(
                    configs['Train']['backbone'])(num_classes,
                                                  backbone=backbone,
                                                  modifier=modifier)
                model = model_with_weights(retinanet,
                                           weights=weights,
                                           skip_mismatch=True)
            training_model = multi_gpu_model(model, gpus=multi_gpu)
        else:
            retinanet = models.retinanet_backbone(
                configs['Train']['backbone'])(num_classes,
                                              backbone=backbone,
                                              modifier=modifier)
            training_model = model = model_with_weights(retinanet,
                                                        weights=weights,
                                                        skip_mismatch=True)

        # make prediction model
        prediction_model = retinanet_bbox(model=model,
                                          anchor_param=configs['Anchors'])

        # compile model
        subnet_loss = {
            'regression': losses.smooth_l1(),
            'classification': losses.focal()
        }

        # run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
        # run_metadata = tf.RunMetadata()

        if configs['Train']['lr_multiplier_layer']:
            optimizer = AdamWithLRMult(
                lr=configs['Train']['init_lr'],
                lr_multipliers=configs['Train']['lr_multiplier_layer'],
                debug_verbose=False,
                clipnorm=0.001)
        else:
            optimizer = keras.optimizers.adam(configs['Train']['init_lr'],
                                              clipnorm=0.001)

        training_model.compile(loss=subnet_loss, optimizer=optimizer)

        # training_model.compile(loss=subnet_loss, optimizer=keras.optimizers.adam(configs['Train']['init_lr'], clipnorm=0.001))

    # this lets the generator compute backbone layer shapes using the actual backbone model
    if 'vgg' in configs['Train']['backbone'] or 'densenet' in configs['Train'][
            'backbone']:
        compute_anchor_targets = functools.partial(
            anchor_targets_bbox, shapes_callback=make_shapes_callback(model))
        train_generator.compute_anchor_targets = compute_anchor_targets
        if validation_generator is not None:
            validation_generator.compute_anchor_targets = compute_anchor_targets

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

    # start training
    training_model.fit_generator(
        train_generator,
        validation_data=validation_generator,
        validation_steps=39,
        steps_per_epoch=configs['Train']['steps'],
        epochs=configs['Train']['epochs'],
        verbose=1,
        callbacks=callbacks,
    )
 def __init__(self, t=1.0, alpha=1.0, reduce=True):
     super(KDLoss, self).__init__()
     self.t = t
     self.alpha = alpha
     self.focal = losses.focal(reduce=True)
     self.reduce = reduce
예제 #18
0
import losses
import utils.customized_optimizer

import numpy as np
"""
A dictionary mapping custom layer names to the correct classes.
"""
custom_objects = {
    'UpsampleLike': layers.UpsampleLike,
    'PriorProbability': initializers.PriorProbability,
    'RegressBoxes': layers.RegressBoxes,
    'FilterDetections': layers.FilterDetections,
    'Anchors': layers.Anchors,
    'ClipBoxes': layers.ClipBoxes,
    '_smooth_l1': losses.smooth_l1(),
    '_focal': losses.focal(),
    'AdamWithLRMult': utils.customized_optimizer.AdamWithLRMult
}


def default_classification_model(num_classes,
                                 num_anchors,
                                 pyramid_feature_size=256,
                                 prior_probability=0.01,
                                 classification_feature_size=256,
                                 name='classification_submodel'):
    """ Creates the default regression submodel.

    Args
        num_classes                 : Number of classes to predict a score for at each feature level.
        num_anchors                 : Number of anchors to predict classification scores for at each feature level.
예제 #19
0
def main():
    backbone = models.backbone('resnet50')
    # create the generators
    #train_generator, validation_generator = create_generators(args, backbone.preprocess_image)
    random_transform = True
    val_annotations = './data/processed/val.csv'
    annotations = './data/processed/train.csv'
    classes = './data/processed/classes.csv'
    common_args = {
        'batch_size': 8,
        'image_min_side': 224,
        'image_max_side': 1333,
        'preprocess_image': backbone.preprocess_image,
    }
    # create random transform generator for augmenting training data
    if random_transform:
        transform_generator = random_transform_generator(
            min_rotation=-0.05,
            max_rotation=0.05,
            min_translation=(-0.1, -0.1),
            max_translation=(0.1, 0.1),
            #min_shear=-0.1,
            #max_shear=0.1,
            min_scaling=(0.8, 0.8),
            max_scaling=(1.2, 1.2),
            flip_x_chance=0.5,
            #flip_y_chance=0.5,
        )
    else:
        transform_generator = random_transform_generator(flip_x_chance=0.5)
    train_generator = CSVGenerator(annotations,
                                   classes,
                                   transform_generator=transform_generator,
                                   **common_args)

    if val_annotations:
        validation_generator = CSVGenerator(val_annotations, classes,
                                            **common_args)
    else:
        validation_generator = None

    #train_generator, validation_generator = create_generators(args, backbone.preprocess_image)
    num_classes = 1  # change
    model = backbone.retinanet(num_classes, backbone='resnet50')
    training_model = model

    # prediction_model = retinanet_bbox(model=model)
    nms = True
    class_specific_filter = True
    name = 'retinanet-bbox'
    anchor_params = AnchorParameters.default
    # compute the anchors
    features = [
        model.get_layer(p_name).output
        for p_name in ['P3', 'P4', 'P5', 'P6', 'P7']
    ]

    anchor = [
        layers.Anchors(size=anchor_params.sizes[i],
                       stride=anchor_params.strides[i],
                       ratios=anchor_params.ratios,
                       scales=anchor_params.scales,
                       name='anchors_{}'.format(i))(f)
        for i, f in enumerate(features)
    ]
    anchors = keras.layers.Concatenate(axis=1, name='anchors')(anchor)
    # we expect the anchors, regression and classification values as first output
    regression = model.outputs[0]  # check
    classification = model.outputs[1]

    # "other" can be any additional output from custom submodels, by default this will be []
    other = model.outputs[2:]

    # apply predicted regression to anchors
    boxes = layers.RegressBoxes(name='boxes')([anchors, regression])
    boxes = layers.ClipBoxes(name='clipped_boxes')([model.inputs[0], boxes])

    # filter detections (apply NMS / score threshold / select top-k)
    detections = layers.FilterDetections(
        nms=nms,
        class_specific_filter=class_specific_filter,
        name='filtered_detections')([boxes, classification] + other)

    outputs = detections

    # construct the model
    prediction_model = keras.models.Model(inputs=model.inputs,
                                          outputs=outputs,
                                          name=name)

    # end of prediction_model = retinanet_bbox(model=model)

    # compile model
    training_model.compile(loss={
        'regression': losses.smooth_l1(),
        'classification': losses.focal()
    },
                           optimizer=keras.optimizers.SGD(lr=1e-2,
                                                          momentum=0.9,
                                                          decay=.0001,
                                                          nesterov=True,
                                                          clipnorm=1)
                           # , clipnorm=0.001)
                           )
    print(model.summary())
    # start of create_callbacks
    #callbacks = create_callbacks(model,training_model,prediction_model,validation_generator,args,)
    callbacks = []
    tensorboard_callback = None
    tensorboard_callback = keras.callbacks.TensorBoard(
        log_dir='',
        histogram_freq=0,
        batch_size=8,
        write_graph=True,
        write_grads=False,
        write_images=False,
        embeddings_freq=0,
        embeddings_layer_names=None,
        embeddings_metadata=None)
    callbacks.append(tensorboard_callback)
    evaluation = Evaluate(validation_generator,
                          tensorboard=tensorboard_callback,
                          weighted_average=False)
    evaluation = RedirectModel(evaluation, prediction_model)
    callbacks.append(evaluation)
    makedirs('./snapshots/')
    checkpoint = keras.callbacks.ModelCheckpoint(os.path.join(
        './snapshots/', '{backbone}_{dataset_type}_{{epoch:02d}}.h5'.format(
            backbone='resnet50', dataset_type='csv')),
                                                 verbose=1,
                                                 save_best_only=False,
                                                 monitor="mAP",
                                                 mode='max')

    checkpoint = RedirectModel(checkpoint, model)
    callbacks.append(checkpoint)
    callbacks.append(
        keras.callbacks.ReduceLROnPlateau(monitor='loss',
                                          factor=0.9,
                                          patience=4,
                                          verbose=1,
                                          mode='auto',
                                          min_delta=0.0001,
                                          cooldown=0,
                                          min_lr=0))
    steps = 2500
    epochs = 25

    # start training
    history = training_model.fit(
        generator=train_generator,
        steps_per_epoch=steps,
        epochs=epochs,
        verbose=1,
        callbacks=callbacks,
    )

    timestr = time.strftime("%Y-%m-%d-%H%M")

    history_path = os.path.join(
        './snapshots/', '{timestr}_{backbone}.csv'.format(timestr=timestr,
                                                          backbone='resnet50',
                                                          dataset_type='csv'))
    pd.DataFrame(history.history).to_csv(history_path)
예제 #20
0
def main(args=None):
    # parse arguments
    if args is None:
        args = sys.argv[1:]
    args = parse_args(args)

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

    num_classes = train_generator.num_classes()
    num_anchors = train_generator.num_anchors

    # optionally choose specific GPU
    if args.gpu:
        os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu

    K.set_session(get_session())

    model, prediction_model = efficientdet(
        args.phi,
        num_classes=num_classes,
        num_anchors=num_anchors,
        weighted_bifpn=args.weighted_bifpn,
        freeze_bn=args.freeze_bn,
        detect_quadrangle=args.detect_quadrangle)
    # load pretrained weights
    if args.snapshot:
        if args.snapshot == 'imagenet':
            model_name = 'efficientnet-b{}'.format(args.phi)
            file_name = '{}_weights_tf_dim_ordering_tf_kernels_autoaugment_notop.h5'.format(
                model_name)
            file_hash = WEIGHTS_HASHES[model_name][1]
            weights_path = keras.utils.get_file(file_name,
                                                BASE_WEIGHTS_PATH + file_name,
                                                cache_subdir='models',
                                                file_hash=file_hash)
            model.load_weights(weights_path, by_name=True)
        else:
            print('Loading model, this may take a second...')
            model.load_weights(args.snapshot, by_name=True)

    # freeze backbone layers
    if args.freeze_backbone:
        # 227, 329, 329, 374, 464, 566, 656
        for i in range(1, [227, 329, 329, 374, 464, 566, 656][args.phi]):
            model.layers[i].trainable = False

    if args.gpu and len(args.gpu.split(',')) > 1:
        model = keras.utils.multi_gpu_model(model,
                                            gpus=list(
                                                map(int, args.gpu.split(','))))

    # compile model
    model.compile(
        optimizer=Adam(lr=1e-3),
        loss={
            'regression':
            smooth_l1_quad() if args.detect_quadrangle else smooth_l1(),
            'classification':
            focal()
        },
    )

    # print(model.summary())

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

    if not args.compute_val_loss:
        validation_generator = None
    elif args.compute_val_loss and validation_generator is None:
        raise ValueError(
            'When you have no validation data, you should not specify --compute-val-loss.'
        )

    # start training
    return model.fit_generator(generator=train_generator,
                               steps_per_epoch=args.steps,
                               initial_epoch=0,
                               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)
예제 #21
0
def main(train_csv, val_csv, classes_csv, epoch_num, phi_num, steps_epoch,
         batch_num, model_path):

    batch_size = batch_num  #def 1
    phi = phi_num  #def 0
    is_text_detect = False
    is_detect_quadrangle = False
    rand_transf_augm = True
    train_ann_path = train_csv
    train_class_path = classes_csv
    val_ann_path = val_csv
    val_class_path = classes_csv
    epochs = epoch_num
    workers = 1
    steps_p_epoch = steps_epoch
    use_multiproc = True
    max_que_size = 10
    comp_loss = True
    gpu = 0
    freeze_bn_arg = True
    weighted_bi = False

    # create the generators
    train_generator, validation_generator = create_generators(
        batch_size, phi, is_text_detect, is_detect_quadrangle,
        rand_transf_augm, train_ann_path, val_ann_path, train_class_path,
        val_class_path)

    num_classes = train_generator.num_classes()
    num_anchors = train_generator.num_anchors

    # optionally choose specific GPU
    if gpu:
        os.environ['CUDA_VISIBLE_DEVICES'] = gpu

    # K.set_session(get_session())

    model, prediction_model = efficientdet(
        phi,
        num_classes=num_classes,
        num_anchors=num_anchors,
        weighted_bifpn=weighted_bi,
        freeze_bn=freeze_bn_arg,
        detect_quadrangle=is_detect_quadrangle)

    # freeze backbone layers
    if freeze_bn_arg:
        # 227, 329, 329, 374, 464, 566, 656
        for i in range(1, [227, 329, 329, 374, 464, 566, 656][phi]):
            model.layers[i].trainable = False

    model.compile(
        optimizer=Adam(lr=1e-3),
        loss={
            'regression':
            smooth_l1_quad() if is_detect_quadrangle else smooth_l1(),
            'classification': focal()
        },
    )

    # print(model.summary())

    # create the callbacks
    callbacks = create_callbacks(model_path)

    if not comp_loss:
        validation_generator = None
    elif comp_loss and validation_generator is None:
        raise ValueError(
            'When you have no validation data, you should not specify --compute-val-loss.'
        )

    # start training
    return model.fit_generator(generator=train_generator,
                               steps_per_epoch=steps_p_epoch,
                               initial_epoch=0,
                               epochs=epochs,
                               verbose=1,
                               callbacks=callbacks,
                               workers=workers,
                               use_multiprocessing=use_multiproc,
                               max_queue_size=max_que_size,
                               validation_data=validation_generator)