HookNet#

from hooknet.training.trainer import Trainer
from hooknet.model import create_hooknet
from wholeslidedata.iterators import create_batch_iterator
from wholeslidedata.visualization.plotting import plot_batch
from matplotlib import pyplot as plt
import gc
from wholeslidedata.samplers.utils import crop_data
from wholeslidedata.visualization.plotting import plot_mask

def plot_inference(patch, ground_truth, prediction):
    colors = ['black', 'red', 'pink', 'purple', 'blue', 'green', 'yellow', 'orange', 'grey']
    fig, axes = plt.subplots(1,3, figsize=(10,10))
    axes[0].imshow(patch)
    plot_mask(ground_truth, axes=axes[1], color_values=colors)
    plot_mask(prediction, axes=axes[2], color_values=colors)
    plt.show()

Data Loading#

ITERATOR_CONFIG = {
    "wholeslidedata": {
        "default": {
            "seed": 123,
            "yaml_source": "/home/user/pathology-whole-slide-data/docs/source/userguide/notebooks/examples/configs/tigersegmentationdata.yml",
            "image_backend": 'asap',
            'labels': {
                "roi": 0,
                "invasive tumor": 1,
                "tumor-associated stroma": 2,
                "in-situ tumor": 3 ,
                "healthy glands": 4,
                "necrosis not in-situ": 5,
                "inflamed stroma": 6,
                "rest": 7,
            },
            "annotation_parser": {
                "sample_label_names": ['roi'],
                "sorters": ["${$wholeslidedata.annotation.selector.sort_by_area_with_roi}"],
            },
            "batch_shape": {
                "batch_size": 5,
                "shape": [[284,284,3],[284,284,3]],
                "spacing": [0.5, 8.0],
                "y_shape": [2, 284, 284]
            },
            'point_sampler_name': "RandomPointSampler",
            'point_sampler': {
                "buffer": {'spacing': "${batch_shape.spacing}", 'value': -(284//2)},
            },

        }
    }
}

mode = 'training'
number_of_batches = 1
cpus=4

with create_batch_iterator(mode=mode, 
                           user_config=ITERATOR_CONFIG, 
                           number_of_batches=number_of_batches, cpus=4) as training_iterator:
    
    for x_batch, y_batch, info in training_iterator:
        plot_batch(x_batch[:,0,...], y_batch[:,0, ...], alpha=0.5)
        plot_batch(x_batch[:,1,...], y_batch[:,1, ...], alpha=0.5)
../../../_images/f49c0d61d6e9344e3978ace55d727644dd4db7efbd8e291a16f592a1b3f04c8a.png ../../../_images/a012b73d8a9855ac85d5cc836526ce891f3535646216d988a2c1485c76c9e698.png

Training#

ITERATOR_CONFIG = {
    "wholeslidedata": {
        "default": {
            "seed": 123,
            "yaml_source": "/home/user/pathology-whole-slide-data/docs/source/userguide/notebooks/examples/configs/tigersegmentationdata.yml",
            "image_backend": 'asap',
            "labels": {
                "roi": 0,
                "invasive tumor": 1,
                "tumor-associated stroma": 2,
                "in-situ tumor": 3,
                "healthy glands": 3,
                "necrosis not in-situ": 3,
                "inflamed stroma": 3,
                "rest": 3,
            },
            "annotation_parser": {
                "renamed_labels": {
                    'roi': 0,
                    'invasive tumor': 1,
                    'tumor-associated stroma': 2,
                    'rest': 3, 
                },
                "sample_label_names": ["roi"],
                "sorters": ["${$wholeslidedata.annotation.selector.sort_by_area_with_roi}"],
            },
            "batch_shape": {
                "batch_size": 32,
                "shape": [[284, 284, 3], [284, 284, 3]],
                "spacing": [0.5, 8.0],
                "y_shape": [2, 70, 70, 3],
            },
            "point_sampler_name": "RandomPointSampler",
            "point_sampler": {
                "buffer": {"spacing": "${batch_shape.spacing}", "value": -35},
            },
            "sample_callbacks": [
                {
                    "*object": "wholeslidedata.samplers.callbacks.CropSampleCallback",
                    "output_shape": [70, 70],
                },
                {
                    "*object": "wholeslidedata.samplers.callbacks.OneHotEncodingSampleCallback",
                    "labels": "${dataset.labels}",
                },
            ],
        }
    }
}

HOOKNET_CONFIG = {
    'hooknet': {
        'default': {
            'model': {
                'n_classes': 3,
                'n_filters': 64,
                'learning_rate': 0.0001,
            }
        }
    }
}
EPOCHS = 50
STEPS = 100 
CPUS = 4
PROJECT = "HookNet-TIGER" 
LOG_PATH = f"/home/user/{PROJECT}"
trainer = Trainer(iterator_config=ITERATOR_CONFIG, 
                  hooknet_config=HOOKNET_CONFIG, 
                  epochs=EPOCHS, 
                  steps=STEPS, 
                  cpus=CPUS, 
                  project=PROJECT, 
                  log_path=LOG_PATH)
trainer.train()
wandb: Currently logged in as: mart-vanrijthoven (use `wandb login --relogin` to force relogin)
wandb: wandb version 0.13.9 is available!  To upgrade, please run:
wandb:  $ pip install wandb --upgrade
Tracking run with wandb version 0.10.32
Syncing run beaming-peony-21 to Weights & Biases (Documentation).
Project page: https://wandb.ai/mart-vanrijthoven/HookNet-TIGER
Run page: https://wandb.ai/mart-vanrijthoven/HookNet-TIGER/runs/1ea6h9lj
Run data is saved locally in /home/user/HookNet-TIGER/wandb/run-20230201_234029-1ea6h9lj

wandb: WARNING Symlinked 0 file into the W&B run directory, call wandb.save again to sync new files.
training labels ['tumor-associated stroma', 'rest', 'invasive tumor', 'roi']
validation labels ['tumor-associated stroma', 'rest', 'invasive tumor', 'roi']
/home/user/pathology-whole-slide-data/wholeslidedata/image/wholeslideimage.py:72: UserWarning: spacing 8.0 outside margin (0.3%) for [0.6574764640761666, 1.3149529281523331, 2.6299058563046662, 5.2598117126093324, 10.519623425218665, 21.03924685043733, 42.07849370087466], returning closest spacing: 10.519623425218665
  warnings.warn(

Patch Inference#

ITERATOR_CONFIG = {
    "wholeslidedata": {
        "default": {
            "seed": 123,
            "yaml_source": "/home/user/pathology-whole-slide-data/docs/source/userguide/notebooks/examples/configs/tigersegmentationdata.yml",
            "image_backend": "asap",
            "labels": {
                "roi": 0,
                "invasive tumor": 1,
                "tumor-associated stroma": 2,
                "in-situ tumor": 3,
                "healthy glands": 3,
                "necrosis not in-situ": 3,
                "inflamed stroma": 3,
                "rest": 3,
            },
            "annotation_parser": {
                "renamed_labels": {
                    'roi': 0,
                    'invasive tumor': 1,
                    'tumor-associated stroma': 2,
                    'rest': 3, 
                },
                "sample_label_names": ["roi"],
                "sorters": ["${$wholeslidedata.annotation.selector.sort_by_area_with_roi}"],
            },
            "batch_shape": {
                "batch_size": 1,
                "shape": [[1244, 1244, 3], [1244, 1244, 3]],
                "spacing": [0.5, 8.0],
                "y_shape": [2, 1244, 1244],
            },
            "point_sampler_name": "RandomPointSampler",
            "point_sampler": {
                "buffer": {"spacing": "${batch_shape.spacing}", "value": -515},
            },
        }
    }
}

HOOKNET_CONFIG = {
    'hooknet': {
        'default': {
            'model': {
                'input_shape': [[1244,1244,3], [1244,1244,3]],
                'n_classes': 3,
                'n_filters': 32,
                'model_weights': '/home/user/HookNet-TIGER/hooknet_weights.h5'
            }
        }
    }
}

     
hooknet = create_hooknet(config=HOOKNET_CONFIG)


with create_batch_iterator(
    user_config=ITERATOR_CONFIG,
    mode='validation',
    cpus=4,
) as validation_batch_generator:
    for _ in range(10):
        x_batch, y_batch, info = next(validation_batch_generator)
        x_batch = list(x_batch.transpose(1, 0, 2, 3, 4))
        predictions = hooknet.predict_on_batch(x_batch)
        x_patch = crop_data(x_batch[0][0], hooknet._out_shape[:2])
        y_patch = crop_data(y_batch[0][0], hooknet._out_shape[:2])
        plot_inference(x_patch, y_patch, predictions[0])
loading weights... /home/user/HookNet-TIGER/hooknet_weights.h5
/home/user/pathology-whole-slide-data/wholeslidedata/image/wholeslideimage.py:72: UserWarning: spacing 0.5 outside margin (0.3%) for [0.6574764640761666, 1.3149529281523331, 2.6299058563046662, 5.2598117126093324, 10.519623425218665, 21.03924685043733, 42.07849370087466], returning closest spacing: 0.6574764640761666
  warnings.warn(
/home/user/pathology-whole-slide-data/wholeslidedata/image/wholeslideimage.py:72: UserWarning: spacing 8.0 outside margin (0.3%) for [0.6574764640761666, 1.3149529281523331, 2.6299058563046662, 5.2598117126093324, 10.519623425218665, 21.03924685043733, 42.07849370087466], returning closest spacing: 10.519623425218665
  warnings.warn(
../../../_images/79a6e963516164bc172394beee361515b173c2a90387efa2efb66e262983f551.png ../../../_images/a88ce23cfaf689a1e04852ca1bd87593d750e9d576d62a3c410f63e3de3da792.png ../../../_images/dfbefac6e9169dbeb90296e7cef07298d33298492f1d60a67212036469d5f5ab.png ../../../_images/62102fbbcc9c0922facb8bc6fe0772f8c8cbbfe953d6e4260b77e4e160b6f637.png ../../../_images/4aae876f3e2a114f649262ca29e0d0b57e0610fef67b38b565217144a5aed43b.png ../../../_images/acd96a771c608d0c382e4148a3032e03733a58426bea76590d19a875fa9892eb.png ../../../_images/f9a86e5cdba960358ecec729ec5b75f113fa38859b6f336abc6d477413e86d81.png ../../../_images/95c31cc572f002057581f00c88833c2ce95f46356fea062e940437656346bf75.png ../../../_images/50d79d5d4acd4827f1dcf44ed3b29dee12e83673dc1689d57d50b8ab13b79d8e.png ../../../_images/a6d4183ca0669dd3a13dd1810df883a8d2e9c71202ca8833bb1f6147666044c0.png