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
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) model = model_with_weights(backbone.fsaf(train_generator.num_classes(), modifier=None), weights=args.snapshot, skip_mismatch=True) training_model = model 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.sgd(lr=1e-5, momentum=0.9, nesterov=True, decay=1e-6) optimizer=keras.optimizers.adam(lr=1e-5) ) 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, backbone_retinanet=backbone.fsaf, 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, steps_per_epoch=args.steps, initial_epoch=9, 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 )
# **common_args # ) generator = PascalVocGenerator( 'datasets/voc_test/VOC2007', 'test', shuffle_groups=False, skip_truncated=False, skip_difficult=True, **common_args ) model_path = '/home/adam/workspace/github/xuannianz/carrot/fsaf/snapshots/2019-10-05/resnet101_pascal_47_0.7652.h5' # load retinanet model # import keras.backend as K # K.set_learning_phase(1) from models.resnet import resnet_fsaf from models.retinanet import fsaf_bbox fsaf = resnet_fsaf(num_classes=20, backbone='resnet101') model = fsaf_bbox(fsaf) model.load_weights(model_path, by_name=True) average_precisions = evaluate(generator, model, visualize=False) # compute per class average precision total_instances = [] precisions = [] for label, (average_precision, num_annotations) in average_precisions.items(): print('{:.0f} instances of class'.format(num_annotations), generator.label_to_name(label), 'with average precision: {:.4f}'.format(average_precision)) total_instances.append(num_annotations) precisions.append(average_precision) mean_ap = sum(precisions) / sum(x > 0 for x in total_instances) print('mAP: {:.4f}'.format(mean_ap))