def main(config_file: str):

    if config_file is None:
        config_file = os.path.join(dirs.CONFIG_DIR, 'train_brats_auxiliary_segm.yaml')

    context = ctx.TorchTrainContext('cuda')
    context.load_from_config(config_file)

    build_train = data.BuildData(
        build_dataset=data.BuildParametrizableDataset(),
        build_sampler=data.BuildSelectionSampler(),
    )
    build_valid = data.BuildData(
        build_dataset=data.BuildParametrizableDataset(),
    )

    train_steps = [SpecialTrainStep(), step.EvalStep()]
    train = trainloop.Train(train_steps, only_validate=False)

    subject_assembler = assembler.SubjectAssembler()
    validate = trainloop.ValidateSubject([SpecialSegmentationPredictStep()],
                                         [step.ExtractSubjectInfoStep(), EvalSubjectStep()],
                                         subject_assembler, entries=('probabilities',))

    hook = hooks.ComposeTrainLoopHook([hooks.TensorboardXHook(), hooks.ConsoleLogHook(), hooks.SaveBestModelHook(),
                                       hooks.SaveNLastModelHook(3)])
    train(context, build_train, build_valid, validate, hook=hook)
Esempio n. 2
0
def main(config_file):

    if config_file is None:
        config_file = os.path.join(dirs.CONFIG_DIR,
                                   'test_brats_auxiliary_segm.yaml')

    context = ctx.TorchTestContext('cuda')
    context.load_from_config(config_file)

    build_test = data.BuildData(
        build_dataset=data.BuildParametrizableDataset(), )

    test_steps = [SegmentationPredictStep()]
    subject_steps = [step.ExtractSubjectInfoStep(), EvalSubjectStep()]

    subject_assembler = assembler.SubjectAssembler()
    test = loop.Test(test_steps,
                     subject_steps,
                     subject_assembler,
                     entries=('probabilities', 'orig_prediction'))

    hook = hooks.ReducedComposeTestLoopHook([
        hooks.ConsoleTestLogHook(),
        hooks.WriteTestMetricsCsvHook('metrics.csv'),
        WriteHook()
    ])
    test(context, build_test, hook=hook)
def main(config_file):

    if config_file is None:
        config_file = os.path.join(dirs.CONFIG_DIR, 'test_brats_aleatoric.yaml')

    context = ctx.TorchTestContext('cuda')
    context.load_from_config(config_file)

    build_test = data.BuildData(
        build_dataset=data.BuildParametrizableDataset(),
    )

    if not hasattr(context.config.others, 'is_log_sigma'):
        raise ValueError('"is_log_sigma" entry missing in configuration file')
    is_log_sigma = context.config.others.is_log_sigma

    test_steps = [AleatoricPredictStep(is_log_sigma)]
    subject_steps = [step.ExtractSubjectInfoStep(), step.EvalSubjectStep()]

    subject_assembler = assembler.SubjectAssembler()
    test = loop.Test(test_steps, subject_steps, subject_assembler, entries=None)

    hook = hooks.ReducedComposeTestLoopHook([hooks.ConsoleTestLogHook(),
                                             hooks.WriteTestMetricsCsvHook('metrics.csv'),
                                             WriteHook()
                                             ])
    test(context, build_test, hook=hook)
Esempio n. 4
0
def main(hdf_file):

    # Use a pad extractor in order to compensate for the valid convolutions of the network. Actual image information is padded
    extractor = extr.PadDataExtractor(
        (2, 2, 2), extr.DataExtractor(categories=(defs.KEY_IMAGES, )))

    # Adapted permutation due to the additional dimension
    transform = tfm.Permute(permutation=(3, 0, 1, 2),
                            entries=(defs.KEY_IMAGES, ))

    # Creating patch indexing strategy with patch_shape that equal the network output shape
    indexing_strategy = extr.PatchWiseIndexing(patch_shape=(32, 32, 32))
    dataset = extr.PymiaDatasource(hdf_file, indexing_strategy, extractor,
                                   transform)

    direct_extractor = extr.ComposeExtractor([
        extr.ImagePropertiesExtractor(),
        extr.DataExtractor(categories=(defs.KEY_LABELS, defs.KEY_IMAGES))
    ])
    assembler = assm.SubjectAssembler(dataset)

    # torch specific handling
    pytorch_dataset = pymia_torch.PytorchDatasetAdapter(dataset)
    loader = torch_data.dataloader.DataLoader(pytorch_dataset,
                                              batch_size=2,
                                              shuffle=False)
    # dummy CNN with valid convolutions instead of same convolutions
    dummy_network = nn.Sequential(
        nn.Conv3d(in_channels=2, out_channels=8, kernel_size=3, padding=0),
        nn.Conv3d(in_channels=8, out_channels=1, kernel_size=3, padding=0),
        nn.Sigmoid())
    torch.set_grad_enabled(False)

    nb_batches = len(loader)

    # looping over the data in the dataset
    for i, batch in enumerate(loader):

        x, sample_indices = batch[defs.KEY_IMAGES], batch[
            defs.KEY_SAMPLE_INDEX]
        prediction = dummy_network(x)

        numpy_prediction = prediction.numpy().transpose((0, 2, 3, 4, 1))

        is_last = i == nb_batches - 1
        assembler.add_batch(numpy_prediction, sample_indices.numpy(), is_last)

        for subject_index in assembler.subjects_ready:
            subject_prediction = assembler.get_assembled_subject(subject_index)

            direct_sample = dataset.direct_extract(direct_extractor,
                                                   subject_index)
            target, image_properties = direct_sample[
                defs.KEY_LABELS], direct_sample[defs.KEY_PROPERTIES]
Esempio n. 5
0
def main(hdf_file, is_meta):

    if not is_meta:
        extractor = extr.DataExtractor(categories=(defs.KEY_IMAGES, ))
    else:
        extractor = extr.FilesystemDataExtractor(
            categories=(defs.KEY_IMAGES, ))

    transform = tfm.Permute(permutation=(2, 0, 1), entries=(defs.KEY_IMAGES, ))

    indexing_strategy = extr.SliceIndexing()
    dataset = extr.PymiaDatasource(hdf_file, indexing_strategy, extractor,
                                   transform)

    direct_extractor = extr.ComposeExtractor([
        extr.ImagePropertiesExtractor(),
        extr.DataExtractor(categories=(defs.KEY_LABELS, defs.KEY_IMAGES))
    ])
    assembler = assm.SubjectAssembler(dataset)

    # torch specific handling
    pytorch_dataset = pymia_torch.PytorchDatasetAdapter(dataset)
    loader = torch_data.dataloader.DataLoader(pytorch_dataset,
                                              batch_size=2,
                                              shuffle=False)
    dummy_network = nn.Sequential(
        nn.Conv2d(in_channels=2, out_channels=8, kernel_size=3, padding=1),
        nn.Conv2d(in_channels=8, out_channels=1, kernel_size=3, padding=1),
        nn.Sigmoid())
    torch.set_grad_enabled(False)

    nb_batches = len(loader)

    # looping over the data in the dataset
    for i, batch in enumerate(loader):

        x, sample_indices = batch[defs.KEY_IMAGES], batch[
            defs.KEY_SAMPLE_INDEX]
        prediction = dummy_network(x)

        numpy_prediction = prediction.numpy().transpose((0, 2, 3, 1))

        is_last = i == nb_batches - 1
        assembler.add_batch(numpy_prediction, sample_indices.numpy(), is_last)

        for subject_index in assembler.subjects_ready:
            subject_prediction = assembler.get_assembled_subject(subject_index)

            direct_sample = dataset.direct_extract(direct_extractor,
                                                   subject_index)
            target, image_properties = direct_sample[
                defs.KEY_LABELS], direct_sample[defs.KEY_PROPERTIES]
def main(config_file: str, config_id: str):

    if config_file is None:
        if config_id == 'baseline':
            config_file = os.path.join(dirs.CONFIG_DIR,
                                       'train_brats_baseline.yaml')
        elif config_id == 'center':
            config_file = os.path.join(dirs.CONFIG_DIR,
                                       'train_brats_center.yaml')
        elif config_id in ('cv0', 'cv1', 'cv2', 'cv3', 'cv4'):
            config_file = os.path.join(
                dirs.CONFIG_DIR, 'baseline_cv',
                'train_brats_baseline_cv{}.yaml'.format(config_id[-1]))
        elif config_id in ('ensemble0', 'ensemble1', 'ensemble2', 'ensemble3',
                           'ensemble4', 'ensemble5', 'ensemble6', 'ensemble7',
                           'ensemble8', 'ensemble9'):
            config_file = os.path.join(
                dirs.CONFIG_DIR, 'train_ensemble',
                'train_brats_ensemble_{}.yaml'.format(config_id[-1]))
        else:
            config_file = os.path.join(dirs.CONFIG_DIR,
                                       'train_brats_baseline.yaml')

    context = ctx.TorchTrainContext('cuda')
    context.load_from_config(config_file)

    build_train = data.BuildData(
        build_dataset=data.BuildParametrizableDataset(),
        build_sampler=data.BuildSelectionSampler(),
    )
    build_valid = data.BuildData(
        build_dataset=data.BuildParametrizableDataset(), )

    train_steps = [step.TrainStep(), step.EvalStep()]
    train = trainloop.Train(train_steps, only_validate=False)

    subject_assembler = assembler.SubjectAssembler()
    validate = trainloop.ValidateSubject(
        [step.SegmentationPredictStep(do_probs=True)],
        [step.ExtractSubjectInfoStep(),
         EvalSubjectStep()],
        subject_assembler,
        entries=('probabilities', ))

    hook = hooks.ComposeTrainLoopHook([
        hooks.TensorboardXHook(),
        hooks.ConsoleLogHook(),
        hooks.SaveBestModelHook(),
        hooks.SaveNLastModelHook(3)
    ])
    train(context, build_train, build_valid, validate, hook=hook)
Esempio n. 7
0
def main(hdf_file):

    extractor = extr.DataExtractor(categories=(defs.KEY_IMAGES, ))

    # no transformation needed because TensorFlow uses channel-last
    transform = None

    indexing_strategy = extr.SliceIndexing()
    dataset = extr.PymiaDatasource(hdf_file, indexing_strategy, extractor,
                                   transform)

    direct_extractor = extr.ComposeExtractor([
        extr.ImagePropertiesExtractor(),
        extr.DataExtractor(categories=(defs.KEY_LABELS, defs.KEY_IMAGES))
    ])
    assembler = assm.SubjectAssembler(dataset)

    # TensorFlow specific handling
    gen_fn = pymia_tf.get_tf_generator(dataset)
    tf_dataset = tf.data.Dataset.from_generator(generator=gen_fn,
                                                output_types={
                                                    defs.KEY_IMAGES:
                                                    tf.float32,
                                                    defs.KEY_SAMPLE_INDEX:
                                                    tf.int64
                                                })
    tf_dataset = tf_dataset.batch(2)

    dummy_network = keras.Sequential([
        layers.Conv2D(8, kernel_size=3, padding='same'),
        layers.Conv2D(2, kernel_size=3, padding='same', activation='sigmoid')
    ])
    nb_batches = len(dataset) // 2

    # looping over the data in the dataset
    for i, batch in enumerate(tf_dataset):
        x, sample_indices = batch[defs.KEY_IMAGES], batch[
            defs.KEY_SAMPLE_INDEX]

        prediction = dummy_network(x)

        numpy_prediction = prediction.numpy()

        is_last = i == nb_batches - 1
        assembler.add_batch(numpy_prediction, sample_indices.numpy(), is_last)

        for subject_index in assembler.subjects_ready:
            subject_prediction = assembler.get_assembled_subject(subject_index)

            direct_sample = dataset.direct_extract(direct_extractor,
                                                   subject_index)
def main(config_file, config_id):

    if config_file is None:
        if config_id == 'baseline':
            config_file = os.path.join(dirs.CONFIG_DIR,
                                       'test_brats_baseline.yaml')
        elif config_id == 'baseline_mc':
            config_file = os.path.join(dirs.CONFIG_DIR,
                                       'test_brats_baseline_mc.yaml')
        elif config_id == 'center':
            config_file = os.path.join(dirs.CONFIG_DIR,
                                       'test_brats_center.yaml')
        elif config_id == 'center_mc':
            config_file = os.path.join(dirs.CONFIG_DIR,
                                       'test_brats_center_mc.yaml')
        elif config_id in ('cv0', 'cv1', 'cv2', 'cv3', 'cv4'):
            config_file = os.path.join(
                dirs.CONFIG_DIR, 'baseline_cv',
                'test_brats_baseline_cv{}.yaml'.format(config_id[-1]))
        else:
            config_file = os.path.join(dirs.CONFIG_DIR,
                                       'test_brats_baseline.yaml')

    context = ctx.TorchTestContext('cuda')
    context.load_from_config(config_file)

    build_test = data.BuildData(
        build_dataset=data.BuildParametrizableDataset(), )

    if hasattr(context.config.others, 'mc'):
        test_steps = [
            customstep.McPredictStep(context.config.others.mc),
            customstep.MultiPredictionSummary()
        ]
    else:
        test_steps = [step.SegmentationPredictStep(do_probs=True)]
    subject_steps = [step.ExtractSubjectInfoStep(), EvalSubjectStep()]

    subject_assembler = assembler.SubjectAssembler()
    test = loop.Test(test_steps,
                     subject_steps,
                     subject_assembler,
                     entries=('probabilities', ))

    hook = hooks.ReducedComposeTestLoopHook([
        hooks.ConsoleTestLogHook(),
        hooks.WriteTestMetricsCsvHook('metrics.csv'),
        WriteHook()
    ])
    test(context, build_test, hook=hook)
Esempio n. 9
0
def main(config_file: str):

    if config_file is None:
        config_file = os.path.join(dirs.CONFIG_DIR,
                                   'train_brats_auxiliary_feat.yaml')

    context = ctx.TorchTrainContext('cuda')
    context.load_from_config(config_file)

    if hasattr(context.config.others, 'model_dir') and hasattr(
            context.config.others, 'test_at'):
        mf = mgt.ModelFiles.from_model_dir(context.config.others.model_dir)
        checkpoint_path = mgt.model_service.find_checkpoint_file(
            mf.weight_checkpoint_dir, context.config.others.test_at)

        model = mgt.model_service.load_model_from_parameters(
            mf.model_path(), with_optimizer=False)
        model.provide_features = True
        mgt.model_service.load_checkpoint(checkpoint_path, model)
        test_model = model.to(context.device)

        test_model.eval()
        for params in test_model.parameters():
            params.requires_grad = False

    build_train = data.BuildData(
        build_dataset=data.BuildParametrizableDataset(),
        build_sampler=data.BuildSelectionSampler(),
    )
    build_valid = data.BuildData(
        build_dataset=data.BuildParametrizableDataset(), )

    train_steps = [SpecialTrainStep(test_model), step.EvalStep()]
    train = trainloop.Train(train_steps, only_validate=False)

    subject_assembler = assembler.SubjectAssembler()
    validate = trainloop.ValidateSubject(
        [SpecialSegmentationPredictStep(test_model)],
        [step.ExtractSubjectInfoStep(),
         EvalSubjectStep()],
        subject_assembler,
        entries=('probabilities', 'net_predictions'))

    hook = hooks.ComposeTrainLoopHook([
        hooks.TensorboardXHook(),
        hooks.ConsoleLogHook(),
        hooks.SaveBestModelHook(),
        hooks.SaveNLastModelHook(3),
    ])
    train(context, build_train, build_valid, validate, hook=hook)
Esempio n. 10
0
def main(config_file):

    if config_file is None:
        config_file = os.path.join(dirs.CONFIG_DIR, 'test_brats_ensemble.yaml')

    context = ctx.TorchTestContext('cuda')
    context.load_from_config(config_file)

    build_test = data.BuildData(
        build_dataset=data.BuildParametrizableDataset(),
    )

    if not hasattr(context.config.others, 'model_dir') or not hasattr(context.config.others, 'test_at'):
        raise ValueError('missing "model_dir" or "test_at" entry in the configuration (others)')

    model_dirs = context.config.others.model_dir
    if isinstance(model_dirs, str):
        model_dirs = [model_dirs]

    test_models = []
    for i, model_dir in enumerate(model_dirs):
        logging.info('load additional model [{}/{}] {}'.format(i+1, len(model_dirs), os.path.basename(model_dir)))
        mf = mgt.ModelFiles.from_model_dir(model_dir)
        checkpoint_path = mgt.model_service.find_checkpoint_file(mf.weight_checkpoint_dir, context.config.others.test_at)

        model = mgt.model_service.load_model_from_parameters(mf.model_path(), with_optimizer=False)
        mgt.model_service.load_checkpoint(checkpoint_path, model)
        test_model = model.to(context.device)

        test_model.eval()
        for params in test_model.parameters():
            params.requires_grad = False
        test_models.append(test_model)

    test_steps = [EnsemblePredictionStep(test_models), customstep.MultiPredictionSummary()]
    subject_steps = [step.ExtractSubjectInfoStep(), EvalSubjectStep()]

    subject_assembler = assembler.SubjectAssembler()
    test = loop.Test(test_steps, subject_steps, subject_assembler, entries=None)  # None means all output entries

    hook = hooks.ReducedComposeTestLoopHook([hooks.ConsoleTestLogHook(),
                                             hooks.WriteTestMetricsCsvHook('metrics.csv'),
                                             WriteHook()
                                             ])
    test(context, build_test, hook=hook)
def main(config_file):

    if config_file is None:
        config_file = os.path.join(dirs.CONFIG_DIR,
                                   'test_brats_auxiliary_feat.yaml')

    context = ctx.TorchTestContext('cuda')
    context.load_from_config(config_file)

    build_test = data.BuildData(
        build_dataset=data.BuildParametrizableDataset(), )

    if hasattr(context.config.others, 'model_dir') and hasattr(
            context.config.others, 'test_at'):
        mf = mgt.ModelFiles.from_model_dir(context.config.others.model_dir)
        checkpoint_path = mgt.model_service.find_checkpoint_file(
            mf.weight_checkpoint_dir, context.config.others.test_at)

        model = mgt.model_service.load_model_from_parameters(
            mf.model_path(), with_optimizer=False)
        model.provide_features = True
        mgt.model_service.load_checkpoint(checkpoint_path, model)
        test_model = model.to(context.device)

        test_model.eval()
        for params in test_model.parameters():
            params.requires_grad = False

    test_steps = [SegmentationPredictStep(test_model)]
    subject_steps = [step.ExtractSubjectInfoStep(), EvalSubjectStep()]

    subject_assembler = assembler.SubjectAssembler()
    test = loop.Test(test_steps,
                     subject_steps,
                     subject_assembler,
                     entries=('probabilities', 'segm_probabilities'))

    hook = hooks.ReducedComposeTestLoopHook([
        hooks.ConsoleTestLogHook(),
        hooks.WriteTestMetricsCsvHook('metrics.csv'),
        WriteHook()
    ])
    test(context, build_test, hook=hook)
Esempio n. 12
0
def main(config_file: str):

    if config_file is None:
        config_file = os.path.join(dirs.CONFIG_DIR,
                                   'train_brats_aleatoric.yaml')

    context = ctx.TorchTrainContext('cuda')
    context.load_from_config(config_file)

    build_train = data.BuildData(
        build_dataset=data.BuildParametrizableDataset(),
        build_sampler=data.BuildSelectionSampler(),
    )
    build_valid = data.BuildData(
        build_dataset=data.BuildParametrizableDataset(), )

    if not hasattr(context.config.others, 'is_log_sigma'):
        raise ValueError('"is_log_sigma" entry missing in configuration file')
    is_log_sigma = context.config.others.is_log_sigma

    train_steps = [TrainStepWithEval(loss.AleatoricLoss(is_log_sigma))]
    train = trainloop.Train(train_steps, only_validate=False)

    subject_assembler = assembler.SubjectAssembler()
    validate = trainloop.ValidateSubject(
        [AleatoricPredictStep(is_log_sigma=is_log_sigma)],
        [step.ExtractSubjectInfoStep(),
         step.EvalSubjectStep()],
        subject_assembler,
        entries=None)

    hook = hooks.ComposeTrainLoopHook([
        hooks.TensorboardXHook(),
        hooks.ConsoleLogHook(),
        hooks.SaveBestModelHook(),
        hooks.SaveNLastModelHook(3)
    ])
    train(context, build_train, build_valid, validate, hook=hook)
Esempio n. 13
0
def main(hdf_file, log_dir):
    # initialize the evaluator with the metrics and the labels to evaluate
    metrics = [metric.DiceCoefficient()]
    labels = {1: 'WHITEMATTER',
              2: 'GREYMATTER',
              3: 'HIPPOCAMPUS',
              4: 'AMYGDALA',
              5: 'THALAMUS'}
    evaluator = eval_.SegmentationEvaluator(metrics, labels)

    # we want to log the mean and standard deviation of the metrics among all subjects of the dataset
    functions = {'MEAN': np.mean, 'STD': np.std}
    statistics_aggregator = writer.StatisticsAggregator(functions=functions)
    console_writer = writer.ConsoleStatisticsWriter(functions=functions)

    # initialize TensorBoard writer
    tb = tensorboard.SummaryWriter(os.path.join(log_dir, 'logging-example-torch'))

    # setup the training datasource
    train_subjects, valid_subjects = ['Subject_1', 'Subject_2', 'Subject_3'], ['Subject_4']
    extractor = extr.DataExtractor(categories=(defs.KEY_IMAGES, defs.KEY_LABELS))
    indexing_strategy = extr.SliceIndexing()

    augmentation_transforms = [augm.RandomElasticDeformation(), augm.RandomMirror()]
    transforms = [tfm.Permute(permutation=(2, 0, 1)), tfm.Squeeze(entries=(defs.KEY_LABELS,))]
    train_transforms = tfm.ComposeTransform(augmentation_transforms + transforms)
    train_dataset = extr.PymiaDatasource(hdf_file, indexing_strategy, extractor, train_transforms,
                                         subject_subset=train_subjects)

    # setup the validation datasource
    valid_transforms = tfm.ComposeTransform([tfm.Permute(permutation=(2, 0, 1))])
    valid_dataset = extr.PymiaDatasource(hdf_file, indexing_strategy, extractor, valid_transforms,
                                         subject_subset=valid_subjects)
    direct_extractor = extr.ComposeExtractor(
        [extr.SubjectExtractor(),
         extr.ImagePropertiesExtractor(),
         extr.DataExtractor(categories=(defs.KEY_LABELS,))]
    )
    assembler = assm.SubjectAssembler(valid_dataset)

    # torch specific handling
    pytorch_train_dataset = pymia_torch.PytorchDatasetAdapter(train_dataset)
    train_loader = torch_data.dataloader.DataLoader(pytorch_train_dataset, batch_size=16, shuffle=True)

    pytorch_valid_dataset = pymia_torch.PytorchDatasetAdapter(valid_dataset)
    valid_loader = torch_data.dataloader.DataLoader(pytorch_valid_dataset, batch_size=16, shuffle=False)

    u_net = unet.UNetModel(ch_in=2, ch_out=6, n_channels=16, n_pooling=3).to(device)

    print(u_net)

    optimizer = optim.Adam(u_net.parameters(), lr=1e-3)
    train_batches = len(train_loader)

    # looping over the data in the dataset
    epochs = 100
    for epoch in range(epochs):
        u_net.train()
        print(f'Epoch {epoch + 1}/{epochs}')

        # training
        print('training')
        for i, batch in enumerate(train_loader):
            x, y = batch[defs.KEY_IMAGES].to(device), batch[defs.KEY_LABELS].to(device).long()
            logits = u_net(x)

            optimizer.zero_grad()
            loss = F.cross_entropy(logits, y)
            loss.backward()
            optimizer.step()

            tb.add_scalar('train/loss', loss.item(), epoch*train_batches + i)
            print(f'[{i + 1}/{train_batches}]\tloss: {loss.item()}')

        # validation
        print('validation')
        with torch.no_grad():
            u_net.eval()
            valid_batches = len(valid_loader)
            for i, batch in enumerate(valid_loader):
                x, sample_indices = batch[defs.KEY_IMAGES].to(device), batch[defs.KEY_SAMPLE_INDEX]

                logits = u_net(x)
                prediction = logits.argmax(dim=1, keepdim=True)

                numpy_prediction = prediction.cpu().numpy().transpose((0, 2, 3, 1))

                is_last = i == valid_batches - 1
                assembler.add_batch(numpy_prediction, sample_indices.numpy(), is_last)

                for subject_index in assembler.subjects_ready:
                    subject_prediction = assembler.get_assembled_subject(subject_index)

                    direct_sample = train_dataset.direct_extract(direct_extractor, subject_index)
                    target, image_properties = direct_sample[defs.KEY_LABELS],  direct_sample[defs.KEY_PROPERTIES]

                    # evaluate the prediction against the reference
                    evaluator.evaluate(subject_prediction[..., 0], target[..., 0], direct_sample[defs.KEY_SUBJECT])

            # calculate mean and standard deviation of each metric
            results = statistics_aggregator.calculate(evaluator.results)
            # log to TensorBoard into category train
            for result in results:
                tb.add_scalar(f'valid/{result.metric}-{result.id_}', result.value, epoch)

            console_writer.write(evaluator.results)

            # clear results such that the evaluator is ready for the next evaluation
            evaluator.clear()
Esempio n. 14
0
def main(hdf_file: str, log_dir: str):
    # initialize the evaluator with the metrics and the labels to evaluate
    metrics = [metric.DiceCoefficient()]
    labels = {1: 'WHITEMATTER', 2: 'GREYMATTER', 5: 'THALAMUS'}
    evaluator = eval_.SegmentationEvaluator(metrics, labels)

    # we want to log the mean and standard deviation of the metrics among all subjects of the dataset
    functions = {'MEAN': np.mean, 'STD': np.std}
    statistics_aggregator = writer.StatisticsAggregator(functions=functions)

    # initialize TensorBoard writer
    # tb = tensorboard.SummaryWriter(os.path.join(log_dir, 'logging-example-torch'))
    tb = tf.summary.create_file_writer(
        os.path.join(log_dir, 'logging-example-tensorflow'))

    # initialize the data handling
    dataset = extr.PymiaDatasource(
        hdf_file, extr.SliceIndexing(),
        extr.DataExtractor(categories=(defs.KEY_IMAGES, )))
    gen_fn = pymia_tf.get_tf_generator(dataset)
    tf_dataset = tf.data.Dataset.from_generator(generator=gen_fn,
                                                output_types={
                                                    defs.KEY_IMAGES:
                                                    tf.float32,
                                                    defs.KEY_SAMPLE_INDEX:
                                                    tf.int64
                                                })
    loader = tf_dataset.batch(100)

    assembler = assm.SubjectAssembler(dataset)
    direct_extractor = extr.ComposeExtractor([
        extr.SubjectExtractor(),  # extraction of the subject name
        extr.ImagePropertiesExtractor(
        ),  # Extraction of image properties (origin, spacing, etc.) for storage
        extr.DataExtractor(
            categories=(defs.KEY_LABELS,
                        ))  # Extraction of "labels" entries for evaluation
    ])

    # initialize a dummy network, which returns a random prediction
    class DummyNetwork(tf.keras.Model):
        def call(self, inputs):
            return tf.random.uniform((*inputs.shape[:-1], 1),
                                     0,
                                     6,
                                     dtype=tf.int32)

    dummy_network = DummyNetwork()
    tf.random.set_seed(0)  # set seed for reproducibility

    nb_batches = len(dataset) // 2

    epochs = 10
    for epoch in range(epochs):
        print(f'Epoch {epoch + 1}/{epochs}')
        for i, batch in enumerate(loader):
            # get the data from batch and predict
            x, sample_indices = batch[defs.KEY_IMAGES], batch[
                defs.KEY_SAMPLE_INDEX]
            prediction = dummy_network(x)

            # translate the prediction to numpy
            numpy_prediction = prediction.numpy()

            # add the batch prediction to the assembler
            is_last = i == nb_batches - 1
            assembler.add_batch(numpy_prediction, sample_indices.numpy(),
                                is_last)

            # process the subjects/images that are fully assembled
            for subject_index in assembler.subjects_ready:
                subject_prediction = assembler.get_assembled_subject(
                    subject_index)

                # extract the target and image properties via direct extract
                direct_sample = dataset.direct_extract(direct_extractor,
                                                       subject_index)
                reference, image_properties = direct_sample[
                    defs.KEY_LABELS], direct_sample[defs.KEY_PROPERTIES]

                # evaluate the prediction against the reference
                evaluator.evaluate(subject_prediction[..., 0], reference[...,
                                                                         0],
                                   direct_sample[defs.KEY_SUBJECT])

        # calculate mean and standard deviation of each metric
        results = statistics_aggregator.calculate(evaluator.results)
        # log to TensorBoard into category train
        for result in results:
            with tb.as_default():
                tf.summary.scalar(f'train/{result.metric}-{result.id_}',
                                  result.value, epoch)

        # clear results such that the evaluator is ready for the next evaluation
        evaluator.clear()
Esempio n. 15
0
def main(hdf_file, log_dir):
    # initialize the evaluator with the metrics and the labels to evaluate
    metrics = [metric.DiceCoefficient()]
    labels = {
        1: 'WHITEMATTER',
        2: 'GREYMATTER',
        3: 'HIPPOCAMPUS',
        4: 'AMYGDALA',
        5: 'THALAMUS'
    }
    evaluator = eval_.SegmentationEvaluator(metrics, labels)

    # we want to log the mean and standard deviation of the metrics among all subjects of the dataset
    functions = {'MEAN': np.mean, 'STD': np.std}
    statistics_aggregator = writer.StatisticsAggregator(functions=functions)
    console_writer = writer.ConsoleStatisticsWriter(functions=functions)

    # initialize TensorBoard writer
    summary_writer = tf.summary.create_file_writer(
        os.path.join(log_dir, 'logging-example-tensorflow'))

    # setup the training datasource
    train_subjects, valid_subjects = ['Subject_1', 'Subject_2',
                                      'Subject_3'], ['Subject_4']
    extractor = extr.DataExtractor(categories=(defs.KEY_IMAGES,
                                               defs.KEY_LABELS))
    indexing_strategy = extr.SliceIndexing()

    augmentation_transforms = [
        augm.RandomElasticDeformation(),
        augm.RandomMirror()
    ]
    transforms = [tfm.Squeeze(entries=(defs.KEY_LABELS, ))]
    train_transforms = tfm.ComposeTransform(augmentation_transforms +
                                            transforms)
    train_dataset = extr.PymiaDatasource(hdf_file,
                                         indexing_strategy,
                                         extractor,
                                         train_transforms,
                                         subject_subset=train_subjects)

    # setup the validation datasource
    batch_size = 16
    valid_transforms = tfm.ComposeTransform([])
    valid_dataset = extr.PymiaDatasource(hdf_file,
                                         indexing_strategy,
                                         extractor,
                                         valid_transforms,
                                         subject_subset=valid_subjects)
    direct_extractor = extr.ComposeExtractor([
        extr.SubjectExtractor(),
        extr.ImagePropertiesExtractor(),
        extr.DataExtractor(categories=(defs.KEY_LABELS, ))
    ])
    assembler = assm.SubjectAssembler(valid_dataset)

    # tensorflow specific handling
    train_gen_fn = pymia_tf.get_tf_generator(train_dataset)
    tf_train_dataset = tf.data.Dataset.from_generator(
        generator=train_gen_fn,
        output_types={
            defs.KEY_IMAGES: tf.float32,
            defs.KEY_LABELS: tf.int64,
            defs.KEY_SAMPLE_INDEX: tf.int64
        })
    tf_train_dataset = tf_train_dataset.batch(batch_size).shuffle(
        len(train_dataset))

    valid_gen_fn = pymia_tf.get_tf_generator(valid_dataset)
    tf_valid_dataset = tf.data.Dataset.from_generator(
        generator=valid_gen_fn,
        output_types={
            defs.KEY_IMAGES: tf.float32,
            defs.KEY_LABELS: tf.int64,
            defs.KEY_SAMPLE_INDEX: tf.int64
        })
    tf_valid_dataset = tf_valid_dataset.batch(batch_size)

    u_net = unet.build_model(channels=2,
                             num_classes=6,
                             layer_depth=3,
                             filters_root=16)

    optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3)
    train_loss = tf.keras.metrics.Mean('train_loss', dtype=tf.float32)

    train_batches = len(train_dataset) // batch_size

    # looping over the data in the dataset
    epochs = 100
    for epoch in range(epochs):
        print(f'Epoch {epoch + 1}/{epochs}')

        # training
        print('training')
        for i, batch in enumerate(tf_train_dataset):
            x, y = batch[defs.KEY_IMAGES], batch[defs.KEY_LABELS]

            with tf.GradientTape() as tape:
                logits = u_net(x, training=True)
                loss = tf.keras.losses.sparse_categorical_crossentropy(
                    y, logits, from_logits=True)

            grads = tape.gradient(loss, u_net.trainable_variables)
            optimizer.apply_gradients(zip(grads, u_net.trainable_variables))

            train_loss(loss)

            with summary_writer.as_default():
                tf.summary.scalar('train/loss',
                                  train_loss.result(),
                                  step=epoch * train_batches + i)
            print(
                f'[{i + 1}/{train_batches}]\tloss: {train_loss.result().numpy()}'
            )

        # validation
        print('validation')
        valid_batches = len(valid_dataset) // batch_size
        for i, batch in enumerate(tf_valid_dataset):
            x, sample_indices = batch[defs.KEY_IMAGES], batch[
                defs.KEY_SAMPLE_INDEX]

            logits = u_net(x)
            prediction = tf.expand_dims(tf.math.argmax(logits, -1), -1)

            numpy_prediction = prediction.numpy()

            is_last = i == valid_batches - 1
            assembler.add_batch(numpy_prediction, sample_indices.numpy(),
                                is_last)

            for subject_index in assembler.subjects_ready:
                subject_prediction = assembler.get_assembled_subject(
                    subject_index)

                direct_sample = train_dataset.direct_extract(
                    direct_extractor, subject_index)
                target, image_properties = direct_sample[
                    defs.KEY_LABELS], direct_sample[defs.KEY_PROPERTIES]

                # evaluate the prediction against the reference
                evaluator.evaluate(subject_prediction[..., 0], target[..., 0],
                                   direct_sample[defs.KEY_SUBJECT])

        # calculate mean and standard deviation of each metric
        results = statistics_aggregator.calculate(evaluator.results)
        # log to TensorBoard into category train
        with summary_writer.as_default():
            for result in results:
                tf.summary.scalar(f'valid/{result.metric}-{result.id_}',
                                  result.value, epoch)

        console_writer.write(evaluator.results)

        # clear results such that the evaluator is ready for the next evaluation
        evaluator.clear()
Esempio n. 16
0
def main(config_file: str):
    config = cfg.load(config_file, cfg.Configuration)
    print(config)

    indexing_strategy = pymia_extr.SliceIndexing()  # slice-wise extraction
    extraction_transform = None  # we do not want to apply any transformation on the slices after extraction
    # define an extractor for training, i.e. what information we would like to extract per sample
    train_extractor = pymia_extr.ComposeExtractor([pymia_extr.NamesExtractor(),
                                                   pymia_extr.DataExtractor(),
                                                   pymia_extr.SelectiveDataExtractor()])

    # define an extractor for testing, i.e. what information we would like to extract per sample
    # not that usually we don't use labels for testing, i.e. the SelectiveDataExtractor is only used for this example
    test_extractor = pymia_extr.ComposeExtractor([pymia_extr.NamesExtractor(),
                                                  pymia_extr.IndexingExtractor(),
                                                  pymia_extr.DataExtractor(),
                                                  pymia_extr.SelectiveDataExtractor(),
                                                  pymia_extr.ImageShapeExtractor()])

    # define an extractor for evaluation, i.e. what information we would like to extract per sample
    eval_extractor = pymia_extr.ComposeExtractor([pymia_extr.NamesExtractor(),
                                                  pymia_extr.SubjectExtractor(),
                                                  pymia_extr.SelectiveDataExtractor(),
                                                  pymia_extr.ImagePropertiesExtractor()])

    # define the data set
    dataset = pymia_extr.ParameterizableDataset(config.database_file,
                                                indexing_strategy,
                                                pymia_extr.SubjectExtractor(),  # for select_indices() below
                                                extraction_transform)

    # generate train / test split for data set
    # we use Subject_0, Subject_1 and Subject_2 for training and Subject_3 for testing
    sampler_ids_train = pymia_extr.select_indices(dataset,
                                                  pymia_extr.SubjectSelection(('Subject_0', 'Subject_1', 'Subject_2')))
    sampler_ids_test = pymia_extr.select_indices(dataset,
                                                 pymia_extr.SubjectSelection(('Subject_3')))

    # set up training data loader
    training_sampler = pymia_extr.SubsetRandomSampler(sampler_ids_train)
    training_loader = pymia_extr.DataLoader(dataset, config.batch_size_training, sampler=training_sampler,
                                            collate_fn=collate_batch, num_workers=1)

    # set up testing data loader
    testing_sampler = pymia_extr.SubsetSequentialSampler(sampler_ids_test)
    testing_loader = pymia_extr.DataLoader(dataset, config.batch_size_testing, sampler=testing_sampler,
                                           collate_fn=collate_batch, num_workers=1)

    sample = dataset.direct_extract(train_extractor, 0)  # extract a subject

    evaluator = init_evaluator()  # initialize evaluator

    for epoch in range(config.epochs):  # epochs loop
        dataset.set_extractor(train_extractor)
        for batch in training_loader:  # batches for training
            # feed_dict = batch_to_feed_dict(x, y, batch, True)  # e.g. for TensorFlow
            # train model, e.g.:
            # sess.run([train_op, loss], feed_dict=feed_dict)
            pass

        # subject assembler for testing
        subject_assembler = pymia_asmbl.SubjectAssembler()

        dataset.set_extractor(test_extractor)
        for batch in testing_loader:  # batches for testing
            # feed_dict = batch_to_feed_dict(x, y, batch, False)  # e.g. for TensorFlow
            # test model, e.g.:
            # prediction = sess.run(y_model, feed_dict=feed_dict)
            prediction = np.stack(batch['labels'], axis=0)  # we use the labels as predictions such that we can validate the assembler
            subject_assembler.add_batch(prediction, batch)

        # evaluate all test images
        for subject_idx in list(subject_assembler.predictions.keys()):
            # convert prediction and labels back to SimpleITK images
            sample = dataset.direct_extract(eval_extractor, subject_idx)
            label_image = pymia_conv.NumpySimpleITKImageBridge.convert(sample['labels'],
                                                                       sample['properties'])

            assembled = subject_assembler.get_assembled_subject(sample['subject_index'])
            prediction_image = pymia_conv.NumpySimpleITKImageBridge.convert(assembled, sample['properties'])
            evaluator.evaluate(prediction_image, label_image, sample['subject'])  # evaluate prediction
Esempio n. 17
0
def init_subject_assembler():
    return asmbl.SubjectAssembler(zero_fn=init_shape,
                                  on_sample_fn=on_sample_fn)
Esempio n. 18
0
def main(hdf_file: str, log_dir: str):
    # initialize the evaluator with the metrics and the labels to evaluate
    metrics = [metric.DiceCoefficient()]
    labels = {1: 'WHITEMATTER', 2: 'GREYMATTER', 5: 'THALAMUS'}
    evaluator = eval_.SegmentationEvaluator(metrics, labels)

    # we want to log the mean and standard deviation of the metrics among all subjects of the dataset
    functions = {'MEAN': np.mean, 'STD': np.std}
    statistics_aggregator = writer.StatisticsAggregator(functions=functions)

    # initialize TensorBoard writer
    tb = tensorboard.SummaryWriter(
        os.path.join(log_dir, 'logging-example-torch'))

    # initialize the data handling
    transform = tfm.Permute(permutation=(2, 0, 1), entries=(defs.KEY_IMAGES, ))
    dataset = extr.PymiaDatasource(
        hdf_file, extr.SliceIndexing(),
        extr.DataExtractor(categories=(defs.KEY_IMAGES, )), transform)
    pytorch_dataset = pymia_torch.PytorchDatasetAdapter(dataset)
    loader = torch_data.dataloader.DataLoader(pytorch_dataset,
                                              batch_size=100,
                                              shuffle=False)

    assembler = assm.SubjectAssembler(dataset)
    direct_extractor = extr.ComposeExtractor([
        extr.SubjectExtractor(),  # extraction of the subject name
        extr.ImagePropertiesExtractor(
        ),  # Extraction of image properties (origin, spacing, etc.) for storage
        extr.DataExtractor(
            categories=(defs.KEY_LABELS,
                        ))  # Extraction of "labels" entries for evaluation
    ])

    # initialize a dummy network, which returns a random prediction
    class DummyNetwork(nn.Module):
        def forward(self, x):
            return torch.randint(0, 6, (x.size(0), 1, *x.size()[2:]))

    dummy_network = DummyNetwork()
    torch.manual_seed(0)  # set seed for reproducibility

    nb_batches = len(loader)

    epochs = 10
    for epoch in range(epochs):
        print(f'Epoch {epoch + 1}/{epochs}')
        for i, batch in enumerate(loader):
            # get the data from batch and predict
            x, sample_indices = batch[defs.KEY_IMAGES], batch[
                defs.KEY_SAMPLE_INDEX]
            prediction = dummy_network(x)

            # translate the prediction to numpy and back to (B)HWC (channel last)
            numpy_prediction = prediction.numpy().transpose((0, 2, 3, 1))

            # add the batch prediction to the assembler
            is_last = i == nb_batches - 1
            assembler.add_batch(numpy_prediction, sample_indices.numpy(),
                                is_last)

            # process the subjects/images that are fully assembled
            for subject_index in assembler.subjects_ready:
                subject_prediction = assembler.get_assembled_subject(
                    subject_index)

                # extract the target and image properties via direct extract
                direct_sample = dataset.direct_extract(direct_extractor,
                                                       subject_index)
                reference, image_properties = direct_sample[
                    defs.KEY_LABELS], direct_sample[defs.KEY_PROPERTIES]

                # evaluate the prediction against the reference
                evaluator.evaluate(subject_prediction[..., 0], reference[...,
                                                                         0],
                                   direct_sample[defs.KEY_SUBJECT])

        # calculate mean and standard deviation of each metric
        results = statistics_aggregator.calculate(evaluator.results)
        # log to TensorBoard into category train
        for result in results:
            tb.add_scalar(f'train/{result.metric}-{result.id_}', result.value,
                          epoch)

        # clear results such that the evaluator is ready for the next evaluation
        evaluator.clear()
Esempio n. 19
0
def init_subject_assembler():
    return asmbl.SubjectAssembler(zero_fn=lambda shape, id_, batch, idx: np.zeros(shape, np.float32),
                                  on_sample_fn=on_sample_ensure_index_expression_validity)
Esempio n. 20
0
def init_subject_assembler():
    return asmbl.SubjectAssembler(zero_fn=init_shape,
                                  on_sample_fn=size_correction)