def setUp(self): self.label_names = ('a', 'b', 'c') imgs = np.random.uniform(size=(1, 3, 2, 3)) # There are labels for 'a' and 'b', but none for 'c'. pred_labels = np.array([[[1, 1, 1], [0, 0, 1]]]) gt_labels = np.array([[[1, 0, 0], [0, -1, 1]]]) self.iou_a = 1 / 3 self.iou_b = 2 / 4 self.pixel_accuracy = 3 / 5 self.class_accuracy_a = 1 / 3 self.class_accuracy_b = 2 / 2 self.miou = np.mean((self.iou_a, self.iou_b)) self.mean_class_accuracy = np.mean( (self.class_accuracy_a, self.class_accuracy_b)) self.dataset = TupleDataset(imgs, gt_labels) self.link = _SemanticSegmentationStubLink(pred_labels) self.iterator = SerialIterator(self.dataset, 5, repeat=False, shuffle=False) self.evaluator = SemanticSegmentationEvaluator(self.iterator, self.link, self.label_names)
def setUp(self): self.label_names = ('a', 'b', 'c') imgs = np.random.uniform(size=(1, 3, 2, 3)) # There are labels for 'a' and 'b', but none for 'c'. pred_labels = np.array([[[1, 1, 1], [0, 0, 1]]]) gt_labels = np.array([[[1, 0, 0], [0, -1, 1]]]) self.iou_a = 1 / 3 self.iou_b = 2 / 4 self.pixel_accuracy = 3 / 5 self.class_accuracy_a = 1 / 3 self.class_accuracy_b = 2 / 2 self.miou = np.mean((self.iou_a, self.iou_b)) self.mean_class_accuracy = np.mean( (self.class_accuracy_a, self.class_accuracy_b)) self.dataset = TupleDataset(imgs, gt_labels) self.link = _SemanticSegmentationStubLink(pred_labels) self.iterator = SerialIterator( self.dataset, 5, repeat=False, shuffle=False) self.evaluator = SemanticSegmentationEvaluator( self.iterator, self.link, self.label_names)
def test_consistency(self): reporter = chainer.Reporter() if self.comm.rank == 0: multi_iterator = SerialIterator(self.dataset, self.batchsize, repeat=False, shuffle=False) else: multi_iterator = None multi_link = _SemanticSegmentationStubLink(self.labels, self.initial_count) multi_evaluator = SemanticSegmentationEvaluator(multi_iterator, multi_link, label_names=('cls0', 'cls1', 'cls2'), comm=self.comm) reporter.add_observer('target', multi_link) with reporter: multi_mean = multi_evaluator.evaluate() if self.comm.rank != 0: self.assertEqual(multi_mean, {}) return single_iterator = SerialIterator(self.dataset, self.batchsize, repeat=False, shuffle=False) single_link = _SemanticSegmentationStubLink(self.labels) single_evaluator = SemanticSegmentationEvaluator(single_iterator, single_link, label_names=('cls0', 'cls1', 'cls2')) reporter.add_observer('target', single_link) with reporter: single_mean = single_evaluator.evaluate() self.assertEqual(set(multi_mean.keys()), set(single_mean.keys())) for key in multi_mean.keys(): np.testing.assert_equal(single_mean[key], multi_mean[key])
class TestSemanticSegmentationEvaluator(unittest.TestCase): def setUp(self): self.label_names = ('a', 'b', 'c') imgs = np.random.uniform(size=(1, 3, 2, 3)) # There are labels for 'a' and 'b', but none for 'c'. pred_labels = np.array([[[1, 1, 1], [0, 0, 1]]]) gt_labels = np.array([[[1, 0, 0], [0, -1, 1]]]) self.iou_a = 1 / 3 self.iou_b = 2 / 4 self.pixel_accuracy = 3 / 5 self.class_accuracy_a = 1 / 3 self.class_accuracy_b = 2 / 2 self.miou = np.mean((self.iou_a, self.iou_b)) self.mean_class_accuracy = np.mean( (self.class_accuracy_a, self.class_accuracy_b)) self.dataset = TupleDataset(imgs, gt_labels) self.link = _SemanticSegmentationStubLink(pred_labels) self.iterator = SerialIterator(self.dataset, 5, repeat=False, shuffle=False) self.evaluator = SemanticSegmentationEvaluator(self.iterator, self.link, self.label_names) def test_evaluate(self): reporter = chainer.Reporter() reporter.add_observer('main', self.link) with reporter: eval_ = self.evaluator.evaluate() # No observation is reported to the current reporter. Instead the # evaluator collect results in order to calculate their mean. np.testing.assert_equal(len(reporter.observation), 0) np.testing.assert_equal(eval_['main/miou'], self.miou) np.testing.assert_equal(eval_['main/pixel_accuracy'], self.pixel_accuracy) np.testing.assert_equal(eval_['main/mean_class_accuracy'], self.mean_class_accuracy) np.testing.assert_equal(eval_['main/iou/a'], self.iou_a) np.testing.assert_equal(eval_['main/iou/b'], self.iou_b) np.testing.assert_equal(eval_['main/iou/c'], np.nan) np.testing.assert_equal(eval_['main/class_accuracy/a'], self.class_accuracy_a) np.testing.assert_equal(eval_['main/class_accuracy/b'], self.class_accuracy_b) np.testing.assert_equal(eval_['main/class_accuracy/c'], np.nan) def test_call(self): eval_ = self.evaluator() # main is used as default np.testing.assert_equal(eval_['main/miou'], self.miou) np.testing.assert_equal(eval_['main/pixel_accuracy'], self.pixel_accuracy) np.testing.assert_equal(eval_['main/mean_class_accuracy'], self.mean_class_accuracy) np.testing.assert_equal(eval_['main/iou/a'], self.iou_a) np.testing.assert_equal(eval_['main/iou/b'], self.iou_b) np.testing.assert_equal(eval_['main/iou/c'], np.nan) np.testing.assert_equal(eval_['main/class_accuracy/a'], self.class_accuracy_a) np.testing.assert_equal(eval_['main/class_accuracy/b'], self.class_accuracy_b) np.testing.assert_equal(eval_['main/class_accuracy/c'], np.nan) def test_evaluator_name(self): self.evaluator.name = 'eval' eval_ = self.evaluator() # name is used as a prefix np.testing.assert_equal(eval_['eval/main/miou'], self.miou) np.testing.assert_equal(eval_['eval/main/pixel_accuracy'], self.pixel_accuracy) np.testing.assert_equal(eval_['eval/main/mean_class_accuracy'], self.mean_class_accuracy) np.testing.assert_equal(eval_['eval/main/iou/a'], self.iou_a) np.testing.assert_equal(eval_['eval/main/iou/b'], self.iou_b) np.testing.assert_equal(eval_['eval/main/iou/c'], np.nan) np.testing.assert_equal(eval_['eval/main/class_accuracy/a'], self.class_accuracy_a) np.testing.assert_equal(eval_['eval/main/class_accuracy/b'], self.class_accuracy_b) np.testing.assert_equal(eval_['eval/main/class_accuracy/c'], np.nan) def test_current_report(self): reporter = chainer.Reporter() with reporter: eval_ = self.evaluator() # The result is reported to the current reporter. np.testing.assert_equal(reporter.observation, eval_)
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) choices_dataset = ['real', 'synthetic'] parser.add_argument('dataset', choices=choices_dataset, help='dataset') parser.add_argument('-g', '--gpu', type=int, default=0, help='gpu id') choices_model = ['fcn8s', 'fcn32s'] parser.add_argument('-m', '--model', choices=choices_model, default=choices_model[0], help='model file') parser.add_argument('--freeze', choices=['conv5', 'fc6', 'fc7'], help='end layer to freeze feature extractor') args = parser.parse_args() args.max_iteration = int(100e3) args.interval_eval = int(1e3) args.interval_print = 10 args.git_hash = instance_occlsegm_lib.utils.git_hash(__file__) args.hostname = socket.gethostname() now = datetime.datetime.now() args.timestamp = now.isoformat() args.out = osp.join(here, 'logs/train_fcn', now.strftime('%Y%m%d_%H%M%S')) try: os.makedirs(args.out) except OSError: pass if args.gpu >= 0: chainer.cuda.get_device_from_id(args.gpu).use() if args.dataset == 'real': data_train = contrib.datasets.ARC2017RealDataset(split='train') class_names = data_train.class_names data_train = chainer.datasets.TransformDataset( data_train, Transform(train=True)) elif args.dataset == 'synthetic': data_train = contrib.datasets.ARC2017SyntheticCachedDataset() class_names = data_train.class_names data_train = chainer.datasets.TransformDataset( data_train, Transform(train=True)) else: raise ValueError iter_train = chainer.iterators.MultiprocessIterator( data_train, batch_size=1, shared_mem=10 ** 7) data_test = contrib.datasets.ARC2017RealDataset(split='test') data_test = chainer.datasets.TransformDataset( data_test, Transform(train=False)) iter_test = chainer.iterators.SerialIterator( data_test, batch_size=1, repeat=False, shuffle=False) if args.model == 'fcn8s': model = contrib.models.FCN8sAtOnce(n_class=len(class_names)) elif args.model == 'fcn32s': model = contrib.models.FCN32s(n_class=len(class_names)) else: raise ValueError vgg16 = fcn.models.VGG16() chainer.serializers.load_npz(vgg16.pretrained_model, vgg16) model.init_from_vgg16(vgg16) model = chainercv.links.PixelwiseSoftmaxClassifier(predictor=model) if args.gpu >= 0: model.to_gpu() optimizer = chainer.optimizers.Adam(alpha=1e-5) optimizer.setup(model) optimizer.add_hook(chainer.optimizer.WeightDecay(rate=0.0005)) if args.model == 'FCN8sAtOnce': model.predictor.upscore2.disable_update() model.predictor.upscore_pool4.disable_update() model.predictor.upscore8.disable_update() elif args.model == 'FCN32s': model.predictor.upscore.disable_update() if args.freeze in ['conv5', 'fc6', 'fc7']: model.predictor.conv1_1.disable_update() model.predictor.conv1_2.disable_update() model.predictor.conv2_1.disable_update() model.predictor.conv2_2.disable_update() model.predictor.conv3_1.disable_update() model.predictor.conv3_2.disable_update() model.predictor.conv3_3.disable_update() model.predictor.conv4_1.disable_update() model.predictor.conv4_2.disable_update() model.predictor.conv4_3.disable_update() model.predictor.conv5_1.disable_update() model.predictor.conv5_2.disable_update() model.predictor.conv5_3.disable_update() elif args.freeze in ['fc6', 'fc7']: model.predictor.fc6.disable_update() elif args.freeze in ['fc7']: model.predictor.fc7.disable_update() else: assert args.freeze is None updater = training.StandardUpdater(iter_train, optimizer, device=args.gpu) trainer = training.Trainer( updater, stop_trigger=(args.max_iteration, 'iteration'), out=args.out) trainer.extend( SemanticSegmentationEvaluator( iter_test, model.predictor, label_names=class_names), trigger=(args.interval_eval, 'iteration')) # logging trainer.extend(contrib.extensions.ParamsReport(args.__dict__)) trainer.extend(extensions.LogReport( trigger=(args.interval_print, 'iteration'))) trainer.extend(extensions.PrintReport( ['epoch', 'iteration', 'elapsed_time', 'main/loss', 'validation/main/miou'])) trainer.extend(extensions.ProgressBar(update_interval=5)) # plotting assert extensions.PlotReport.available() trainer.extend(extensions.PlotReport( y_keys=['main/loss'], x_key='iteration', file_name='loss.png', trigger=(args.interval_print, 'iteration'))) trainer.extend(extensions.PlotReport( y_keys=['validation/main/miou'], x_key='iteration', file_name='miou.png', trigger=(args.interval_print, 'iteration'))) # snapshotting trainer.extend(extensions.snapshot_object( target=model.predictor, filename='model_best.npz'), trigger=training.triggers.MaxValueTrigger( key='validation/main/miou', trigger=(args.interval_eval, 'iteration'))) # visualizing data_test_raw = contrib.datasets.ARC2017RealDataset(split='test') iter_test_raw = chainer.iterators.SerialIterator( data_test_raw, batch_size=1, repeat=False, shuffle=False) trainer.extend( contrib.extensions.SemanticSegmentationVisReport( iter_test_raw, transform=Transform(train=False), class_names=class_names, device=args.gpu, shape=(6, 2)), trigger=(args.interval_eval, 'iteration')) trainer.run()
def main(): parser = argparse.ArgumentParser() parser.add_argument('--gpu', type=int, default=-1) parser.add_argument('--batchsize', type=int, default=12) parser.add_argument('--class_weight', type=str, default='class_weight.npy') parser.add_argument('--out', type=str, default='result') args = parser.parse_args() # Triggers log_trigger = (50, 'iteration') validation_trigger = (2000, 'iteration') end_trigger = (16000, 'iteration') # Dataset train = CamVidDataset(split='train') train = TransformDataset(train, transform) val = CamVidDataset(split='val') # Iterator train_iter = iterators.MultiprocessIterator(train, args.batchsize) val_iter = iterators.MultiprocessIterator(val, args.batchsize, shuffle=False, repeat=False) # Model class_weight = np.load(args.class_weight) model = SegNetBasic(n_class=len(camvid_label_names)) model = PixelwiseSoftmaxClassifier(model, class_weight=class_weight) if args.gpu >= 0: # Make a specified GPU current chainer.cuda.get_device_from_id(args.gpu).use() model.to_gpu() # Copy the model to the GPU # Optimizer optimizer = optimizers.MomentumSGD(lr=0.1, momentum=0.9) optimizer.setup(model) optimizer.add_hook(chainer.optimizer_hooks.WeightDecay(rate=0.0005)) # Updater updater = training.updaters.StandardUpdater(train_iter, optimizer, device=args.gpu) # Trainer trainer = training.Trainer(updater, end_trigger, out=args.out) trainer.extend(extensions.LogReport(trigger=log_trigger)) trainer.extend(extensions.observe_lr(), trigger=log_trigger) trainer.extend(extensions.dump_graph('main/loss')) if extensions.PlotReport.available(): trainer.extend( extensions.PlotReport(['main/loss'], x_key='iteration', file_name='loss.png')) trainer.extend( extensions.PlotReport(['validation/main/miou'], x_key='iteration', file_name='miou.png')) trainer.extend(extensions.snapshot_object( model.predictor, filename='model_iteration-{.updater.iteration}'), trigger=end_trigger) trainer.extend(extensions.PrintReport([ 'epoch', 'iteration', 'elapsed_time', 'lr', 'main/loss', 'validation/main/miou', 'validation/main/mean_class_accuracy', 'validation/main/pixel_accuracy' ]), trigger=log_trigger) trainer.extend(extensions.ProgressBar(update_interval=10)) trainer.extend(SemanticSegmentationEvaluator(val_iter, model.predictor, camvid_label_names), trigger=validation_trigger) trainer.run()
def main(): parser = argparse.ArgumentParser() parser.add_argument("--gpu", type=int, default=-1) parser.add_argument("--batchsize", type=int, default=12) parser.add_argument("--class_weight", type=str, default="class_weight.npy") parser.add_argument("--out", type=str, default="result") args = parser.parse_args() # Triggers log_trigger = (50, "iteration") validation_trigger = (2000, "iteration") end_trigger = (16000, "iteration") # Dataset train = CamVidDataset(split="train") train = TransformDataset(dataset=train, transform=transform) val = CamVidDataset(split="val") # Iterator train_iter = iterators.MultiprocessIterator(train, args.batchsize) val_iter = iterators.MultiprocessIterator(val, args.batchsize, repeat=False, shuffle=False) # Model class_weight = np.load(args.class_weight) model = SegNetBasic(n_class=11) model = PixelwiseSoftmaxClassifier( model, class_weight=class_weight ) if args.gpu >= 0: # Make a specified GPU current chainer.cuda.get_device_from_id(args.gpu).use() # Copy the model to the GPU model.to_gpu() # Optimizer optimizer = optimizers.MomentumSGD(lr=0.1, momentum=0.9) optimizer.setup(model) optimizer.add_hook(chainer.optimizer.WeightDecay(rate=0.0005)) # Updater updater = training.StandardUpdater(train_iter, optimizer, device=args.gpu) # Trainer trainer = training.Trainer(updater=updater, stop_trigger=end_trigger, out=args.out) trainer.extend(extensions.LogReport(trigger=log_trigger)) trainer.extend(extensions.observe_lr(), trigger=log_trigger) trainer.extend(extensions.dump_graph("main/loss")) if extensions.PlotReport.available(): trainer.extend(extensions.PlotReport( ["main/loss"], x_key="iteration", file_name="loss.png" )) trainer.extend(extensions.PlotReport( ["validation/loss"], x_key="iteration", file_name="miou.png" )) trainer.extend(extensions.snapshot_object( model.predictor, filename="model_iteration-{.updater.iteration}"), trigger=end_trigger) trainer.extend(extensions.PrintReport( ["epoch", "iteration", "elapsed_time", "lr", "main/loss", "validation/main/miou", "validation/main/mean_class_accuracy", "validation/main/pixel_accuracy" ] ), trigger=log_trigger) trainer.extend(extensions.ProgressBar(update_interval=10)) trainer.extend(SemanticSegmentationEvaluator( val_iter, model.predictor, camvid_label_names), trigger=validation_trigger) trainer.run()
def train_one_epoch(model, train_data, lr, gpu, batchsize, out): train_model = PixelwiseSoftmaxClassifier(model) if gpu >= 0: # Make a specified GPU current chainer.cuda.get_device_from_id(gpu).use() train_model.to_gpu() # Copy the model to the GPU log_trigger = (0.1, 'epoch') validation_trigger = (1, 'epoch') end_trigger = (1, 'epoch') train_data = TransformDataset(train_data, ('img', 'label_map'), SimpleDoesItTransform(model.mean)) val = VOCSemanticSegmentationWithBboxDataset( split='val').slice[:, ['img', 'label_map']] # Iterator train_iter = iterators.MultiprocessIterator(train_data, batchsize) val_iter = iterators.MultiprocessIterator(val, 1, shuffle=False, repeat=False, shared_mem=100000000) # Optimizer optimizer = optimizers.MomentumSGD(lr=lr, momentum=0.9) optimizer.setup(train_model) optimizer.add_hook(chainer.optimizer_hooks.WeightDecay(rate=0.0001)) # Updater updater = training.updaters.StandardUpdater(train_iter, optimizer, device=gpu) # Trainer trainer = training.Trainer(updater, end_trigger, out=out) trainer.extend(extensions.LogReport(trigger=log_trigger)) trainer.extend(extensions.observe_lr(), trigger=log_trigger) trainer.extend(extensions.dump_graph('main/loss')) if extensions.PlotReport.available(): trainer.extend( extensions.PlotReport(['main/loss'], x_key='iteration', file_name='loss.png')) trainer.extend( extensions.PlotReport(['validation/main/miou'], x_key='iteration', file_name='miou.png')) trainer.extend(extensions.snapshot_object(model, filename='snapshot.npy'), trigger=end_trigger) trainer.extend(extensions.PrintReport([ 'epoch', 'iteration', 'elapsed_time', 'lr', 'main/loss', 'validation/main/miou', 'validation/main/mean_class_accuracy', 'validation/main/pixel_accuracy' ]), trigger=log_trigger) trainer.extend(extensions.ProgressBar(update_interval=10)) trainer.extend(SemanticSegmentationEvaluator( val_iter, model, voc_semantic_segmentation_label_names), trigger=validation_trigger) trainer.run()
def handler(context): # Triggers log_trigger = (50, 'iteration') validation_trigger = (2000, 'iteration') end_trigger = (nb_iterations, 'iteration') # Dataset dataset_alias = context.datasets train_dataset_id = dataset_alias['train'] val_dataset_id = dataset_alias['val'] train = SegmentationDatasetFromAPI(train_dataset_id) val = SegmentationDatasetFromAPI(val_dataset_id) class_weight = calc_weight(train) print(class_weight) train = TransformDataset(train, transform) # Iterator train_iter = iterators.SerialIterator(train, BATCHSIZE) val_iter = iterators.SerialIterator(val, BATCHSIZE, shuffle=False, repeat=False) # Model model = SegNetBasic(n_class=len(camvid_label_names)) model = PixelwiseSoftmaxClassifier(model, class_weight=class_weight) if USE_GPU >= 0: # Make a specified GPU current chainer.cuda.get_device_from_id(USE_GPU).use() model.to_gpu() # Copy the model to the GPU # Optimizer optimizer = optimizers.MomentumSGD(lr=0.1, momentum=0.9) optimizer.setup(model) optimizer.add_hook(chainer.optimizer_hooks.WeightDecay(rate=0.0005)) # Updater updater = training.updaters.StandardUpdater(train_iter, optimizer, device=USE_GPU) # Trainer trainer = training.Trainer(updater, end_trigger, out=ABEJA_TRAINING_RESULT_DIR) trainer.extend(extensions.LogReport(trigger=log_trigger)) trainer.extend(extensions.observe_lr(), trigger=log_trigger) trainer.extend(extensions.dump_graph('main/loss')) trainer.extend(extensions.snapshot_object( model.predictor, filename='model_iteration-{.updater.iteration}'), trigger=end_trigger) print_entries = [ 'iteration', 'main/loss', 'validation/main/miou', 'validation/main/mean_class_accuracy', 'validation/main/pixel_accuracy' ] report_entries = [ 'epoch', 'iteration', 'lr', 'main/loss', 'validation/main/miou', 'validation/main/mean_class_accuracy', 'validation/main/pixel_accuracy' ] trainer.extend(Statistics(report_entries, nb_iterations, obs_key='iteration'), trigger=log_trigger) trainer.extend(Tensorboard(report_entries, out_dir=log_path)) trainer.extend(extensions.PrintReport(print_entries), trigger=log_trigger) trainer.extend(SemanticSegmentationEvaluator(val_iter, model.predictor, camvid_label_names), trigger=validation_trigger) trainer.run()
def main(): parser = argparse.ArgumentParser() parser.add_argument('--data-dir', default='auto') parser.add_argument('--dataset', choices=('ade20k', 'cityscapes')) parser.add_argument('--model', choices=('pspnet_resnet101', 'pspnet_resnet50')) parser.add_argument('--lr', default=1e-2) parser.add_argument('--batchsize', default=2, type=int) parser.add_argument('--out', default='result') parser.add_argument('--iteration', default=None, type=int) parser.add_argument('--communicator', default='hierarchical') args = parser.parse_args() dataset_cfgs = { 'ade20k': { 'input_size': (473, 473), 'label_names': ade20k_semantic_segmentation_label_names, 'iteration': 150000 }, 'cityscapes': { 'input_size': (713, 713), 'label_names': cityscapes_semantic_segmentation_label_names, 'iteration': 90000 } } dataset_cfg = dataset_cfgs[args.dataset] # https://docs.chainer.org/en/stable/chainermn/tutorial/tips_faqs.html#using-multiprocessiterator if hasattr(multiprocessing, 'set_start_method'): multiprocessing.set_start_method('forkserver') p = multiprocessing.Process() p.start() p.join() comm = chainermn.create_communicator(args.communicator) device = comm.intra_rank n_class = len(dataset_cfg['label_names']) if args.model == 'pspnet_resnet101': model = PSPNetResNet101(n_class, pretrained_model='imagenet', input_size=dataset_cfg['input_size']) elif args.model == 'pspnet_resnet50': model = PSPNetResNet50(n_class, pretrained_model='imagenet', input_size=dataset_cfg['input_size']) train_chain = create_mnbn_model(TrainChain(model), comm) model = train_chain.model if device >= 0: chainer.cuda.get_device_from_id(device).use() train_chain.to_gpu() if args.iteration is None: n_iter = dataset_cfg['iteration'] else: n_iter = args.iteration if args.dataset == 'ade20k': train = ADE20KSemanticSegmentationDataset(data_dir=args.data_dir, split='train') if comm.rank == 0: val = ADE20KSemanticSegmentationDataset(data_dir=args.data_dir, split='val') label_names = ade20k_semantic_segmentation_label_names elif args.dataset == 'cityscapes': train = CityscapesSemanticSegmentationDataset(args.data_dir, label_resolution='fine', split='train') if comm.rank == 0: val = CityscapesSemanticSegmentationDataset( args.data_dir, label_resolution='fine', split='val') label_names = cityscapes_semantic_segmentation_label_names train = TransformDataset(train, ('img', 'label'), Transform(model.mean, dataset_cfg['input_size'])) if comm.rank == 0: indices = np.arange(len(train)) else: indices = None indices = chainermn.scatter_dataset(indices, comm, shuffle=True) train = train.slice[indices] train_iter = chainer.iterators.MultiprocessIterator( train, batch_size=args.batchsize, n_processes=2) optimizer = chainermn.create_multi_node_optimizer( chainer.optimizers.MomentumSGD(args.lr, 0.9), comm) optimizer.setup(train_chain) for param in train_chain.params(): if param.name not in ('beta', 'gamma'): param.update_rule.add_hook(chainer.optimizer.WeightDecay(1e-4)) for l in [ model.ppm, model.head_conv1, model.head_conv2, train_chain.aux_conv1, train_chain.aux_conv2 ]: for param in l.params(): param.update_rule.add_hook(GradientScaling(10)) updater = training.updaters.StandardUpdater(train_iter, optimizer, device=device) trainer = training.Trainer(updater, (n_iter, 'iteration'), args.out) trainer.extend(PolynomialShift('lr', 0.9, n_iter, optimizer=optimizer), trigger=(1, 'iteration')) log_interval = 10, 'iteration' if comm.rank == 0: trainer.extend(extensions.LogReport(trigger=log_interval)) trainer.extend(extensions.observe_lr(), trigger=log_interval) trainer.extend(extensions.PrintReport([ 'epoch', 'iteration', 'elapsed_time', 'lr', 'main/loss', 'validation/main/miou', 'validation/main/mean_class_accuracy', 'validation/main/pixel_accuracy' ]), trigger=log_interval) trainer.extend(extensions.ProgressBar(update_interval=10)) trainer.extend(extensions.snapshot_object( train_chain.model, 'snapshot_model_{.updater.iteration}.npz'), trigger=(n_iter, 'iteration')) val_iter = chainer.iterators.SerialIterator(val, batch_size=1, repeat=False, shuffle=False) trainer.extend(SemanticSegmentationEvaluator(val_iter, model, label_names), trigger=(n_iter, 'iteration')) trainer.run()
def main(): parser = argparse.ArgumentParser() parser.add_argument('--gpu', type=int, default=-1) parser.add_argument('--batchsize', type=int, default=12) parser.add_argument('--class-weight', type=str, default='class_weight.npy') parser.add_argument('--val-iter', type=int, default=2000) parser.add_argument('--out', type=str, default='result') parser.add_argument('--iter', type=int, default=16000) parser.add_argument('--dtype', type=str, default='float32') parser.add_argument('--init-scale', type=float, default=1.0) parser.add_argument('--n-uf', type=float, default=1e-5) parser.add_argument('--dynamic-interval', type=int, default=None) parser.add_argument('--loss-scale-method', type=str, default='approx_range') parser.add_argument('--verbose', action='store_true', default=False) args = parser.parse_args() # Data type print('==> Using data type: {}'.format(args.dtype)) chainer.global_config.dtype = dtypes[args.dtype] # Triggers log_trigger = (50, 'iteration') validation_trigger = (args.val_iter, 'iteration') end_trigger = (args.iter, 'iteration') # Dataset train = CamVidDataset(split='train') train = TransformDataset(train, transform) val = CamVidDataset(split='val') # Iterator train_iter = iterators.MultiprocessIterator(train, args.batchsize) val_iter = iterators.MultiprocessIterator(val, args.batchsize, shuffle=False, repeat=False) # Model class_weight = np.load(args.class_weight) model = SegNetBasic(n_class=len(camvid_label_names), dtype=dtypes[args.dtype]) # adaptive loss scaling if args.dtype != 'float32': recorder = AdaLossRecorder(sample_per_n_iter=100) model = AdaLossScaled(model, init_scale=args.init_scale, transforms=[ AdaLossTransformLinear(), AdaLossTransformConvolution2D(), AdaLossTransformBatchNormalization(), ], cfg={ 'loss_scale_method': args.loss_scale_method, 'scale_upper_bound': 65504, 'accum_upper_bound': 65504, 'update_per_n_iteration': 100, 'recorder': recorder, 'n_uf_threshold': args.n_uf, }, verbose=args.verbose) model = PixelwiseSoftmaxClassifier(model, class_weight=class_weight) if args.gpu >= 0: # Make a specified GPU current chainer.cuda.get_device_from_id(args.gpu).use() model.to_gpu() # Copy the model to the GPU # Optimizer optimizer = optimizers.MomentumSGD(lr=0.1, momentum=0.9) optimizer.setup(model) optimizer.add_hook(chainer.optimizer_hooks.WeightDecay(rate=0.0005)) if args.dtype == 'mixed16': optimizer.use_fp32_update() # Updater updater = training.updaters.StandardUpdater(train_iter, optimizer, device=args.gpu) if args.dtype == 'mixed16': if args.dynamic_interval is not None: print('==> Using dynamic loss scaling (interval={}) ...'.format( args.dynamic_interval)) optimizer.loss_scaling(interval=args.dynamic_interval, scale=None) optimizer._loss_scale_max = 32770.0 else: if args.loss_scale_method == 'approx_range': print('==> Using adaptive loss scaling ...') else: print('==> Using default fixed loss scaling (scale={}) ...'. format(args.init_scale)) optimizer.loss_scaling(interval=float('inf'), scale=None) optimizer._loss_scale_max = 1.0 # to prevent actual loss scaling # Trainer trainer = training.Trainer(updater, end_trigger, out=args.out) # warmup_attr_ratio = 0.1 if args.dtype != 'float32' else None # # NOTE: this is confusing but it means n_iter # warmup_n_epoch = 1000 if args.dtype != 'float32' else None # lr_shift = chainerlp.extensions.ExponentialShift( # 'lr', # 0.1, # init=0.1 * warmup_attr_ratio, # warmup_attr_ratio=warmup_attr_ratio, # warmup_n_epoch=warmup_n_epoch) # trainer.extend(lr_shift, trigger=(1, 'iteration')) trainer.extend(extensions.LogReport(trigger=log_trigger)) trainer.extend(extensions.observe_lr(), trigger=log_trigger) if args.dtype != 'float32': trainer.extend(extensions.observe_value( 'loss_scale', lambda trainer: trainer.updater.get_optimizer('main')._loss_scale), trigger=log_trigger) trainer.extend(extensions.dump_graph('main/loss')) # snapshot the trainer after each trainer.extend(extensions.snapshot(), trigger=validation_trigger) # snapshot the model itself trainer.extend(extensions.snapshot_object( get_snapshot_model(model), 'model_iter_{.updater.iteration}'), trigger=validation_trigger) if extensions.PlotReport.available(): trainer.extend( extensions.PlotReport(['main/loss'], x_key='iteration', file_name='loss.png')) trainer.extend( extensions.PlotReport(['validation/main/miou'], x_key='iteration', file_name='miou.png')) metrics = [ 'epoch', 'iteration', 'elapsed_time', 'lr', 'main/loss', 'validation/main/miou', 'validation/main/mean_class_accuracy', 'validation/main/pixel_accuracy' ] if args.dtype != 'float32': metrics.append('loss_scale') trainer.extend(extensions.PrintReport(metrics), trigger=log_trigger) trainer.extend(extensions.ProgressBar(update_interval=10)) trainer.extend(SemanticSegmentationEvaluator(val_iter, model.predictor, camvid_label_names), trigger=validation_trigger) # snapshot the best validation result trainer.extend(extensions.snapshot_object(get_snapshot_model(model), 'model_best'), trigger=chainer.training.triggers.MaxValueTrigger( 'validation/main/miou', trigger=validation_trigger)) hooks = [] if args.dtype != 'float32': hook = AdaLossMonitor(sample_per_n_iter=100, verbose=args.verbose, includes=['Grad', 'Deconvolution']) recorder.trainer = trainer hook.trainer = trainer hooks.append(hook) with ExitStack() as stack: for hook in hooks: stack.enter_context(hook) trainer.run() chainer.serializers.save_npz( os.path.join(args.out, 'snapshot_model.npz'), recalculate_bn_statistics(model.predictor, args.batchsize, dtype=args.dtype)) if args.dtype != 'float32': recorder.export().to_csv(os.path.join(args.out, 'loss_scale.csv'))
class TestSemanticSegmentationEvaluator(unittest.TestCase): def setUp(self): self.label_names = ('a', 'b', 'c') imgs = np.random.uniform(size=(1, 3, 2, 3)) # There are labels for 'a' and 'b', but none for 'c'. pred_labels = np.array([[[1, 1, 1], [0, 0, 1]]]) gt_labels = np.array([[[1, 0, 0], [0, -1, 1]]]) self.iou_a = 1 / 3 self.iou_b = 2 / 4 self.pixel_accuracy = 3 / 5 self.class_accuracy_a = 1 / 3 self.class_accuracy_b = 2 / 2 self.miou = np.mean((self.iou_a, self.iou_b)) self.mean_class_accuracy = np.mean( (self.class_accuracy_a, self.class_accuracy_b)) self.dataset = TupleDataset(imgs, gt_labels) self.link = _SemanticSegmentationStubLink(pred_labels) self.iterator = SerialIterator( self.dataset, 5, repeat=False, shuffle=False) self.evaluator = SemanticSegmentationEvaluator( self.iterator, self.link, self.label_names) def test_evaluate(self): reporter = chainer.Reporter() reporter.add_observer('main', self.link) with reporter: eval_ = self.evaluator.evaluate() # No observation is reported to the current reporter. Instead the # evaluator collect results in order to calculate their mean. np.testing.assert_equal(len(reporter.observation), 0) np.testing.assert_equal(eval_['main/miou'], self.miou) np.testing.assert_equal(eval_['main/pixel_accuracy'], self.pixel_accuracy) np.testing.assert_equal(eval_['main/mean_class_accuracy'], self.mean_class_accuracy) np.testing.assert_equal(eval_['main/iou/a'], self.iou_a) np.testing.assert_equal(eval_['main/iou/b'], self.iou_b) np.testing.assert_equal(eval_['main/iou/c'], np.nan) np.testing.assert_equal(eval_['main/class_accuracy/a'], self.class_accuracy_a) np.testing.assert_equal(eval_['main/class_accuracy/b'], self.class_accuracy_b) np.testing.assert_equal(eval_['main/class_accuracy/c'], np.nan) def test_call(self): eval_ = self.evaluator() # main is used as default np.testing.assert_equal(eval_['main/miou'], self.miou) np.testing.assert_equal(eval_['main/pixel_accuracy'], self.pixel_accuracy) np.testing.assert_equal(eval_['main/mean_class_accuracy'], self.mean_class_accuracy) np.testing.assert_equal(eval_['main/iou/a'], self.iou_a) np.testing.assert_equal(eval_['main/iou/b'], self.iou_b) np.testing.assert_equal(eval_['main/iou/c'], np.nan) np.testing.assert_equal(eval_['main/class_accuracy/a'], self.class_accuracy_a) np.testing.assert_equal(eval_['main/class_accuracy/b'], self.class_accuracy_b) np.testing.assert_equal(eval_['main/class_accuracy/c'], np.nan) def test_evaluator_name(self): self.evaluator.name = 'eval' eval_ = self.evaluator() # name is used as a prefix np.testing.assert_equal(eval_['eval/main/miou'], self.miou) np.testing.assert_equal(eval_['eval/main/pixel_accuracy'], self.pixel_accuracy) np.testing.assert_equal(eval_['eval/main/mean_class_accuracy'], self.mean_class_accuracy) np.testing.assert_equal(eval_['eval/main/iou/a'], self.iou_a) np.testing.assert_equal(eval_['eval/main/iou/b'], self.iou_b) np.testing.assert_equal(eval_['eval/main/iou/c'], np.nan) np.testing.assert_equal(eval_['eval/main/class_accuracy/a'], self.class_accuracy_a) np.testing.assert_equal(eval_['eval/main/class_accuracy/b'], self.class_accuracy_b) np.testing.assert_equal(eval_['eval/main/class_accuracy/c'], np.nan) def test_current_report(self): reporter = chainer.Reporter() with reporter: eval_ = self.evaluator() # The result is reported to the current reporter. np.testing.assert_equal(reporter.observation, eval_)
label_resolution='fine', split='val') label_names = cityscapes_semantic_segmentation_label_names else: raise ValueError('Invalid model_name') n_class = len(label_names) train_iter, valid_iter = create_iterator(train, valid, args.crop_size, args.rotate, args.horizontal_flip, args.scale_range, args.batchsize) in_ch = 3 # model = create_model(args, in_ch, n_class, args.crop_size) model = PSPNetResNet50(n_class, input_size=args.crop_size, pretrained_model='imagenet') net = PSPTrainChain(model) evaluator = SemanticSegmentationEvaluator(valid_iter, model, label_names) trainer = create_trainer(train_iter, net, args.gpu_id, args.initial_lr, args.weight_decay, args.freeze_layer, args.small_lr_layers, args.small_initial_lr, args.num_epochs_or_iter, args.epoch_or_iter, args.save_dir) # TODO: https://github.com/chainer/chainercv/blob/fd630326cb148c8a4966a65ccbdaea90900cd8de/examples/pspnet/train_multi.py#L256 trainer_extend(trainer, net, evaluator, args.small_lr_layers, args.lr_decay_rate, args.lr_decay_epoch, args.epoch_or_iter, args.save_trainer_interval) trainer.run()