parser.print_help(sys.stderr) sys.exit(1) train_transform = TrainAugmentation(config.image_size, config.image_mean, config.image_std) target_transform = MatchPrior(config.priors, config.center_variance, config.size_variance, 0.5) test_transform = TestTransform(config.image_size, config.image_mean, config.image_std) logging.info("Prepare training datasets.") datasets = [] for dataset_path in args.datasets: if args.dataset_type == 'voc': dataset = VOCDataset(dataset_path, transform=train_transform, target_transform=target_transform) label_file = os.path.join(args.checkpoint_folder, "voc-model-labels.txt") store_labels(label_file, dataset.class_names) num_classes = len(dataset.class_names) elif args.dataset_type == 'open_images': dataset = OpenImagesDataset(dataset_path, transform=train_transform, target_transform=target_transform, dataset_type="train", balance_data=args.balance_data) label_file = os.path.join(args.checkpoint_folder, "open-images-model-labels.txt") store_labels(label_file, dataset.class_names) logging.info(dataset)
recall = true_positive / num_true_cases if use_2007_metric: return measurements.compute_voc2007_average_precision( precision, recall) else: return measurements.compute_average_precision(precision, recall) if __name__ == '__main__': eval_path = pathlib.Path(args.eval_dir) eval_path.mkdir(exist_ok=True) timer = Timer() class_names = [name.strip() for name in open(args.label_file).readlines()] if args.dataset_type == "voc": dataset = VOCDataset(args.dataset, is_test=True) elif args.dataset_type == 'open_images': dataset = OpenImagesDataset(args.dataset, dataset_type="test") true_case_stat, all_gb_boxes, all_difficult_cases = group_annotation_by_class( dataset) if args.net == 'vgg16-ssd': net = create_vgg_ssd(len(class_names), is_test=True) elif args.net == 'mb1-ssd': net = create_mobilenetv1_ssd(len(class_names), is_test=True) elif args.net == 'mb1-ssd-lite': net = create_mobilenetv1_ssd_lite(len(class_names), is_test=True) elif args.net == 'sq-ssd-lite': net = create_squeezenet_ssd_lite(len(class_names), is_test=True) elif args.net == 'mb2-ssd-lite': net = create_mobilenetv2_ssd_lite(len(class_names),
return measurements.compute_voc2007_average_precision( precision, recall) else: return measurements.compute_average_precision(precision, recall) COLORS = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0)] FONT = cv2.FONT_HERSHEY_SIMPLEX if __name__ == '__main__': eval_path = pathlib.Path(args.eval_dir) eval_path.mkdir(exist_ok=True) timer = Timer() class_names = [name.strip() for name in open(args.label_file).readlines()] if args.dataset_type == "voc": dataset = VOCDataset(args.dataset, is_test=True) elif args.dataset_type == 'open_images': dataset = OpenImagesDataset(args.dataset, dataset_type="test") true_case_stat, all_gb_boxes, all_difficult_cases = group_annotation_by_class( dataset) if args.net == 'vgg16-ssd': net = create_vgg_ssd(len(class_names), is_test=True) elif args.net == 'mb1-ssd': net = create_mobilenetv1_ssd(len(class_names), is_test=True) elif args.net == 'mb1-ssd-lite': net = create_mobilenetv1_ssd_lite(len(class_names), is_test=True) elif args.net == 'sq-ssd-lite': net = create_squeezenet_ssd_lite(len(class_names), is_test=True) elif args.net == 'mb2-ssd-lite': net = create_mobilenetv2_ssd_lite(len(class_names),
# create data transforms for train/test/val train_transform = TrainAugmentation(config.image_size, config.image_mean, config.image_std) target_transform = MatchPrior(config.priors, config.center_variance, config.size_variance, 0.5) test_transform = TestTransform(config.image_size, config.image_mean, config.image_std) # load datasets (could be multiple) logging.info("Prepare training datasets.") datasets = [] for dataset_path in args.datasets: if args.dataset_type == 'voc': dataset = VOCDataset(dataset_path, transform=train_transform, target_transform=target_transform, bg_transform=test_transform) label_file = os.path.join(args.checkpoint_folder, "labels.txt") store_labels(label_file, dataset.class_names) num_classes = len(dataset.class_names) elif args.dataset_type == 'open_images': dataset = OpenImagesDataset(dataset_path, transform=train_transform, target_transform=target_transform, dataset_type="train", balance_data=args.balance_data) label_file = os.path.join(args.checkpoint_folder, "labels.txt") store_labels(label_file, dataset.class_names) logging.info(dataset) num_classes = len(dataset.class_names)
def train_network(dataset_path, model_path, net_type): args.datasets = dataset_path args.validation_dataset = dataset_path args.checkpoint_folder = model_path args.log_dir = os.path.join(args.checkpoint_folder, 'log') args.net = net_type timer = Timer() logging.info(args) if args.net == 'slim': create_net = create_mb_tiny_fd config = fd_config elif args.net == 'RFB': create_net = create_Mb_Tiny_RFB_fd config = fd_config else: logging.fatal("The net type is wrong.") parser.print_help(sys.stderr) sys.exit(1) train_transform = TrainAugmentation(config.image_size, config.image_mean, config.image_std) target_transform = MatchPrior(config.priors, config.center_variance, config.size_variance, args.overlap_threshold) test_transform = TestTransform(config.image_size, config.image_mean_test, config.image_std) if not os.path.exists(args.checkpoint_folder): os.makedirs(args.checkpoint_folder) logging.info("Prepare training datasets.") datasets = [] # voc datasets dataset = VOCDataset(dataset_path, transform=train_transform, target_transform=target_transform) label_file = os.path.join(args.checkpoint_folder, "voc-model-labels.txt") store_labels(label_file, dataset.class_names) num_classes = len(dataset.class_names) print('num_classes: ', num_classes) logging.info(f"Stored labels into file {label_file}.") # train_dataset = ConcatDataset(datasets) train_dataset = dataset logging.info("Train dataset size: {}".format(len(train_dataset))) train_loader = DataLoader(train_dataset, args.batch_size, num_workers=args.num_workers, shuffle=True) logging.info("Prepare Validation datasets.") val_dataset = VOCDataset(args.validation_dataset, transform=test_transform, target_transform=target_transform, is_test=True) logging.info("validation dataset size: {}".format(len(val_dataset))) val_loader = DataLoader(val_dataset, args.batch_size, num_workers=args.num_workers, shuffle=False) logging.info("Build network.") net = create_net(num_classes) timer.start("Load Model") if args.resume: logging.info(f"Resume from the model {args.resume}") net.load(args.resume) logging.info( f'Took {timer.end("Load Model"):.2f} seconds to load the model.') # add multigpu_train if torch.cuda.device_count() >= 1: cuda_index_list = [int(v.strip()) for v in args.cuda_index.split(",")] net = nn.DataParallel(net, device_ids=cuda_index_list) logging.info("use gpu :{}".format(cuda_index_list)) min_loss = -10000.0 last_epoch = -1 base_net_lr = args.base_net_lr if args.base_net_lr is not None else args.lr extra_layers_lr = args.extra_layers_lr if args.extra_layers_lr is not None else args.lr params = [{ 'params': net.module.base_net.parameters(), 'lr': base_net_lr }, { 'params': itertools.chain(net.module.source_layer_add_ons.parameters(), net.module.extras.parameters()), 'lr': extra_layers_lr }, { 'params': itertools.chain(net.module.regression_headers.parameters(), net.module.classification_headers.parameters()) }] net.to(DEVICE) criterion = MultiboxLoss(config.priors, iou_threshold=args.iou_threshold, neg_pos_ratio=5, center_variance=0.1, size_variance=0.2, device=DEVICE, num_classes=num_classes, loss_type=args.loss_type) if args.optimizer_type == "SGD": optimizer = torch.optim.SGD(params, lr=args.lr, momentum=args.momentum, weight_decay=args.weight_decay) elif args.optimizer_type == "Adam": optimizer = torch.optim.Adam(params, lr=args.lr) logging.info("use Adam optimizer") else: logging.fatal(f"Unsupported optimizer: {args.scheduler}.") parser.print_help(sys.stderr) sys.exit(1) logging.info( f"Learning rate: {args.lr}, Base net learning rate: {base_net_lr}, " + f"Extra Layers learning rate: {extra_layers_lr}.") if args.optimizer_type != "Adam": if args.scheduler == 'multi-step': logging.info("Uses MultiStepLR scheduler.") milestones = [int(v.strip()) for v in args.milestones.split(",")] scheduler = MultiStepLR(optimizer, milestones=milestones, gamma=0.1, last_epoch=last_epoch) elif args.scheduler == 'poly': logging.info("Uses PolyLR scheduler.") else: logging.fatal(f"Unsupported Scheduler: {args.scheduler}.") parser.print_help(sys.stderr) sys.exit(1) logging.info(f"Start training from epoch {last_epoch + 1}.") for epoch in range(last_epoch + 1, args.num_epochs): if args.optimizer_type != "Adam": if args.scheduler != "poly": if epoch != 0: scheduler.step() train(train_loader, net, criterion, optimizer, device=DEVICE, debug_steps=args.debug_steps, epoch=epoch) if args.scheduler == "poly": adjust_learning_rate(optimizer, epoch) logging.info("epoch: {} lr rate :{}".format( epoch, optimizer.param_groups[0]['lr'])) if epoch % args.validation_epochs == 0 or epoch == args.num_epochs - 1: logging.info("validation epoch: {} lr rate :{}".format( epoch, optimizer.param_groups[0]['lr'])) val_loss, val_regression_loss, val_classification_loss = test( val_loader, net, criterion, DEVICE) logging.info( f"Epoch: {epoch}, " + f"Validation Loss: {val_loss:.4f}, " + f"Validation Regression Loss {val_regression_loss:.4f}, " + f"Validation Classification Loss: {val_classification_loss:.4f}" ) model_path = os.path.join( args.checkpoint_folder, f"{args.net}-Epoch-{epoch}-Loss-{val_loss:.4f}.pth") net.module.save(model_path) logging.info(f"Saved model {model_path}")