### Install dhSegment Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/demo/dhSegment_paper.ipynb Installs the dhSegment library from its GitHub repository. This is typically the first step in setting up the environment. ```bash !pip install git+https://github.com/dhlab-epfl/dhSegment-torch.git@master ``` -------------------------------- ### Launch Tensorboard Instance Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/demo/dhSegment_paper.ipynb Starts a Tensorboard instance for visualizing training progress. Relaunch the cell if it fails and wait for the Tensorboard bar to appear. ```python %tensorboard --logdir ./ ``` -------------------------------- ### TensorboardLogger and WandbLogger Setup Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Configure loggers for Tensorboard and Weights & Biases to track training progress, metrics, and images. Requires ColorLabels for mapping. ```python from dh_segment_torch.training import TensorboardLogger, WandbLogger from dh_segment_torch.data import ColorLabels color_labels = ColorLabels.from_labels(["background", "text", "figure"]) tb_logger = TensorboardLogger( color_labels=color_labels, log_dir="tb_logs/", log_every=20, log_images_every=50, ) # Called inside the training loop # tb_logger.log(iteration, metrics, losses, batch, logits, lr_scheduler, optimizer, prefix="train") # Weights & Biases logger (requires wandb installed) # wb_logger = WandbLogger( # color_labels=color_labels, # exp_name="my_experiment", # config={"lr": 1e-3}, # ) ``` -------------------------------- ### Install dhSegment with Conda Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/README.md Recommended installation procedure using Conda to ensure dependency compatibility. This creates a dedicated environment for dhSegment. ```bash conda env create --name dhs --file environment.yml source activate dhs python setup.py install ``` -------------------------------- ### Train the Model Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/demo/dhSegment_paper.ipynb Initializes the Trainer from the defined parameters and starts the model training process. Training progress can be monitored in the Tensorboard window. Training can be interrupted early as checkpoints are saved automatically. ```python trainer = Trainer.from_params(params) trainer.train() ``` -------------------------------- ### Define Post-processing Parameters for DH-Segment Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/demo/dhSegment_paper.ipynb Configures the post-processing steps for inference, including operations for detecting horizontal and vertical lines, calculating mask size, and generating normalized annotations. This setup is crucial for transforming raw probability outputs into structured annotations. ```python post_process_params = { 'type': 'dag', 'operations' : { "h_lines": { "inputs": "h_probs", "ops": [ {"type": "filter_gaussian", "sigma": 1.2}, { "type": "threshold_hysteresis", "low_threshold": 0.1, "high_threshold": 0.4, }, {"type": "horizontal_lines_page", "angle_variance": 5, "vote_threshold": 100}, {"type": "lines_filter", "dist_thresh": 40}, "to_line", {'type': "assign_label", "label": "row"} ], }, "v_lines": { "inputs": "v_probs", "ops": [ {"type": "filter_gaussian", "sigma": 1.2}, { "type": "threshold_hysteresis", "low_threshold": 0.1, "high_threshold": 0.4, }, {"type": "vertical_lines_page", "angle_variance": 5, "vote_threshold": 100}, {"type": "lines_filter", "dist_thresh": 40}, "to_line", {'type': "assign_label", "label": "column"} ], }, "mask_size": { "inputs": "h_probs", "ops": "probas_to_image_size" }, 'labels_annotations': { 'inputs': ['h_lines', 'v_lines'], "ops": ["concat_lists", 'to_labels_annotations'] }, 'labels_annotations_normalized': { 'inputs': ['mask_size', 'labels_annotations'], 'ops': "normalize_labels_annotations" }, 'annotation': { 'inputs': ['path', 'labels_annotations_normalized'], 'ops': 'to_annotation' } } } ``` -------------------------------- ### Training via CLI Script Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Entry point for command-line training, supporting basic training and resuming from trainer or model checkpoints. ```bash # Basic training python scripts/train.py configs/train.jsonnet ``` ```bash # Resume from a trainer checkpoint (restores epoch, optimizer, scheduler state) python scripts/train.py configs/train.jsonnet \ --trainer-checkpoint model/train_checkpoint.pth ``` ```bash # Resume only model weights (e.g., fine-tuning from a previous run) python scripts/train.py configs/train.jsonnet \ --model-checkpoint model/best_model_miou=0.87.pth ``` -------------------------------- ### Train Demo Model Locally Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/README.md Script to train the demo model. Requires approximately 6 GB of GPU RAM and around 20 minutes for training. ```python python3 demo/train_demo.py ``` -------------------------------- ### Configuring Optimizers and LR Schedulers Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Sets up optimizers (Adam, SGD) and learning rate schedulers (Exponential, Cosine Annealing, ReduceLROnPlateau) for model training. Ensure model parameters are correctly passed to the optimizer. ```python from dh_segment_torch.training import ( AdamOptimizer, SGDOptimizer, ExponentialScheduler, CosineAnnealingScheduler, ReduceOnPlateauScheduler, ConcatScheduler, ) import torch.nn as nn model = nn.Linear(10, 3) params = list(model.named_parameters()) # Adam with weight decay optimizer = AdamOptimizer(model_params=params, lr=1e-3, weight_decay=1e-4) # Exponential LR decay scheduler = ExponentialScheduler(optimizer=optimizer, gamma=0.9995) scheduler.step() # Cosine annealing cosine = CosineAnnealingScheduler(optimizer=optimizer, T_max=100) # Reduce on plateau (requires val metric) plateau = ReduceOnPlateauScheduler(optimizer=optimizer, factor=0.5, patience=5) plateau.step(metric_value=0.82) ``` -------------------------------- ### Configure Model and Training Parameters Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/demo/dhSegment_paper.ipynb Defines configuration for model training, including dataset paths, model architecture, optimizer settings, and logging options. Adjust batch size based on GPU memory; 4 for >14GB, 2 otherwise. Defaults are suitable for most use cases. ```python params = { "color_labels": {"label_json_file": '/content/data/color_labels.json'}, "train_dataset": { "type": "image_csv", "csv_filename": "/content/data/train.csv", "base_dir": "/content/data", "repeat_dataset": 4, "compose": {"transforms": [{"type": "fixed_size_resize", "output_size": 1e6}]} }, "val_dataset": { "type": "image_csv", "csv_filename": "/content/data/val.csv", "base_dir": "/content/data", "compose": {"transforms": [{"type": "fixed_size_resize", "output_size": 1e6}]} }, "model": { "encoder": "resnet50", "decoder": { "decoder_channels": [512, 256, 128, 64, 32], "max_channels": 512 } }, "metrics": [['miou', 'iou'], ['iou', {"type": 'iou', "average": None}], 'precision'], "optimizer": {"lr": 1e-4}, "lr_scheduler": {"type": "exponential", "gamma": 0.9995}, "val_metric": "+miou", "early_stopping": {"patience": 4}, "model_out_dir": "./model_test", "num_epochs": 100, "evaluate_every_epoch": 5, "batch_size": 4, "num_data_workers": 0, "track_train_metrics": False, "loggers": [ {"type": 'tensorboard', "log_dir": "./model_cadaster_test/log", "log_every": 5, "log_images_every": 10} ] } ``` -------------------------------- ### Load and manage experiment configurations with Params Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Use Params to load Jsonnet or JSON configuration files. It provides dict-like access and supports imports and templating. Persist resolved configurations as plain JSON. ```python from dh_segment_torch.config import Params # Load a Jsonnet config file (supports imports, locals, arithmetic) params = Params.from_file("configs/train.jsonnet") # Dict-like access model_out = params.get("model_out_dir", "./model") # returns Params or scalar exp_name = params.pop("experiment_name", "my_exp") # pop with default # Persist the resolved config as plain JSON import os os.makedirs(model_out, exist_ok=True) params.to_file(os.path.join(model_out, "config.json")) # Build from a plain Python dict (no file needed) params2 = Params({ "model_out_dir": "./output", "num_epochs": 50, "batch_size": 4, "optimizer": {"lr": 1e-3}, }) print(params2["optimizer"]) # Params({'lr': 0.001}) ``` -------------------------------- ### Prepare and Split Data Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/demo/dhSegment_paper.ipynb This script processes the data based on the defined parameters, creates necessary directories, and splits the data into training, validation, and test sets. It handles image paths and label assignments. ```python num_processes = params.pop("num_processes", 4) data_path = params.pop("data_path") os.makedirs(data_path, exist_ok=True) relative_path = params.pop("relative_path", True) params.setdefault("labels_dir", os.path.join(data_path, "labels")) labels_dir = params.get("labels_dir") params.setdefault("images_dir", os.path.join(data_path, "images")) images_dir = params.get("images_dir") params.setdefault( "color_labels_file_path", os.path.join(data_path, "color_labels.json") ) params.setdefault("csv_path", os.path.join(data_path, "data.csv")) data_splitter_params = params.pop("data_splitter", None) train_csv_path = params.pop("train_csv", os.path.join(data_path, "train.csv")) val_csv_path = params.pop("val_csv", os.path.join(data_path, "val.csv")) test_csv_path = params.pop("test_csv", os.path.join(data_path, "test.csv")) params.setdefault("type", "image") image_writer = AnnotationWriter.from_params(params) data = image_writer.write(num_processes) if relative_path: data['image'] = data['image'].apply(lambda path: os.path.join("images", os.path.basename(path))) data['label'] = data['label'].apply(lambda path: os.path.join("labels", os.path.basename(path))) if data_splitter_params: data_splitter = DataSplitter.from_params(data_splitter_params) data_splitter.split_data(data, train_csv_path, val_csv_path, test_csv_path) ``` -------------------------------- ### Full Training Loop with Trainer Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Orchestrates the complete training lifecycle including epoch loop, gradient accumulation, validation, metric tracking, LR scheduling, regularization, early stopping, and checkpointing. Resume from checkpoint by loading state dict. ```python from dh_segment_torch.training import Trainer from dh_segment_torch.config import Params params = Params({ "color_labels": {"type": "json", "label_json_file": "data/color_labels.json"}, "train_dataset": { "type": "image_csv", "csv_filename": "data/train.csv", "base_dir": "data/", "repeat_dataset": 2, "compose": {"transforms": [ {"type": "fixed_size_resize", "output_size": 1e6}, {"type": "random_shadow", "p": 0.2}, {"type": "horizontal_flip", "p": 0.5}, ]}, }, "val_dataset": { "type": "image_csv", "csv_filename": "data/val.csv", "base_dir": "data/", "compose": {"transforms": [ {"type": "fixed_size_resize", "output_size": 1e6}, ]}, }, "model": { "encoder": "resnet50", "decoder": {"decoder_channels": [512, 256, 128, 64, 32], "max_channels": 512}, }, "initializer": {"initializers": [ {"regexes": "decoder.*.conv2d.weight$", "type": "xavier_uniform"}, {"regexes": "decoder.*.conv2d.bias$", "type": "zeros"}, ]}, "metrics": [["miou", "iou"], ["iou", {"type": "iou", "average": None}], "precision"], "optimizer": {"lr": 1e-3}, "lr_scheduler": {"type": "exponential", "gamma": 0.9995}, "val_metric": "+miou", "early_stopping": {"patience": 10}, "model_out_dir": "./model", "num_epochs": 100, "evaluate_every_epoch": 2, "batch_size": 4, "num_data_workers": 4, "track_train_metrics": False, "loggers": [{"type": "tensorboard", "log_dir": "./tb_logs", "log_every": 20, "log_images_every": 50}], }) trainer = Trainer.from_params(params) # Resume from checkpoint import torch state = torch.load("model/train_checkpoint.pth") trainer.load_state_dict(state) try: trainer.train() except KeyboardInterrupt: trainer.final_save() # saves a permanent checkpoint on interrupt ``` -------------------------------- ### Configure Inference Process Parameters Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/demo/dhSegment_paper.ipynb Combines dataset, model, and post-processing parameters along with other settings like batch size, number of workers, and output names to define the complete inference process configuration. ```python process_params = Params({ 'data': dataset_params, 'model': model_params, 'post_process': post_process_params, 'batch_size': 4, 'num_workers': 4, 'index_to_name': {1: 'h_probs', 2: 'v_probs'}, 'output_names': 'annotation', 'add_path': True }) ``` -------------------------------- ### Define Data Loading and Processing Parameters Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/demo/dhSegment_paper.ipynb Configure parameters for loading annotations, specifying attribute names, file paths, and image directories. This includes settings for color labels, image resizing, and data copying. ```python params = { 'data_path' : '/content/data', # Path to write the data 'data_splitter': {'train_ratio': 0.8, 'val_ratio': 0.2, 'test_ratio': 0.0}, # splitting ratio of the data 'annotation_reader': { 'type': 'via2_project', # File format of the data 'attrib_name': 'lines', # Name of the via attribute where the labels are defined 'file_path': '/content/drive/My Drive/sample_catastici/via_catastici_annotated.json', # Path to the annotation file 'images_dir': '/content/drive/My Drive/sample_catastici', # Path to the images directory (not necessary if using IIIF) 'line_thickness': 4, # Thickness of the lines to draw }, 'color_labels': { 'type': 'colors', # Definition of colors for each labels 'colors': ['#93be59', '#be5993'], # Colors 'labels': ['row', 'column'] # Corresponding labels }, 'copy_images': True, # Whether to copy the images 'overwrite': True, # Whether to overwrite the images 'progress': True, # Whether to show progress 'resizer': {'height': 1100} # Size to which the images should be resized while importing them (useful, since we resize them anyway in the processing pipeline) } ``` -------------------------------- ### Load TensorBoard extension Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/demo/dhSegment_paper.ipynb Loads the TensorBoard extension for use within the notebook environment, enabling visualization of training metrics. ```python # Load the TensorBoard notebook extension %load_ext tensorboard ``` -------------------------------- ### Perform Inference and Generate Annotations Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/demo/dhSegment_paper.ipynb Initializes the prediction process using the configured parameters and then executes the process to generate annotations from the input data. ```python predict_annots = PredictProcess.from_params(process_params) annots = predict_annots.process() ``` -------------------------------- ### Params - JSON/Jsonnet configuration loader Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt The Params class provides a convenient way to load and manage experiment configurations from JSON or Jsonnet files. It supports dict-like access, nested configurations, and persistence of resolved configurations. ```APIDOC ## Params - JSON/Jsonnet configuration loader `Params` is a `MutableMapping` wrapper around experiment configuration dictionaries. It loads `.jsonnet` or `.json` files, supports Jsonnet imports and templating, and exposes dict-like access with explicit error messages for missing required keys. ```python from dh_segment_torch.config import Params # Load a Jsonnet config file (supports imports, locals, arithmetic) params = Params.from_file("configs/train.jsonnet") # Dict-like access model_out = params.get("model_out_dir", "./model") # returns Params or scalar exp_name = params.pop("experiment_name", "my_exp") # pop with default # Persist the resolved config as plain JSON import os os.makedirs(model_out, exist_ok=True) params.to_file(os.path.join(model_out, "config.json")) # Build from a plain Python dict (no file needed) params2 = Params({ "model_out_dir": "./output", "num_epochs": 50, "batch_size": 4, "optimizer": {"lr": 1e-3}, }) print(params2["optimizer"]) # Params({'lr': 0.001}) ``` ``` -------------------------------- ### Initialize PredictProcess for end-to-end inference Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Combines dataset loading, model inference, and optional post-processing into a single pipeline. Can output processed results or raw probability maps. ```python from dh_segment_torch.inference import PredictProcess from dh_segment_torch.config import Params params = Params({ "data": { "type": "folder", "folder": "/path/to/images", "pre_processing": {"transforms": [{"type": "fixed_size_resize", "output_size": 1e6}]}, }, "model": { "type": "training_config", "model": {"encoder": "resnet50", "decoder": {"decoder_channels": [512,256,128,64,32], "max_channels": 512}}, "color_labels": {"type": "json", "label_json_file": "data/color_labels.json"}, "dataset": {"type": "image_csv", "csv_filename": "data/train.csv", "base_dir": "data/"}, "model_state_dict": "model/best_model_miou=0.87.pth", }, "batch_size": 2, # Optionally add a post_process pipeline here }) predictor = PredictProcess.from_params(params) # Option A: Get post-processed results as Python objects results = predictor.process() # results is a list of dicts; each dict contains pipeline output per image # Option B: Save raw probability maps as .npy files import os os.makedirs("output/probas", exist_ok=True) predictor.process_to_probas_files("output/probas") # Saves e.g. output/probas/image001.npy shape=(num_classes, H, W) ``` -------------------------------- ### Create InferenceDataset from various sources Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Provides a PyTorch Dataset for loading images during inference. Supports loading from explicit file paths, a directory, or a CSV file, with optional pre-processing. ```python from dh_segment_torch.inference import InferenceDataset # From explicit paths ds_paths = InferenceDataset( image_paths=["img/001.jpg", "img/002.jpg"], pre_processing=None, ) # From a directory (auto-detects image extensions) ds_folder = InferenceDataset.from_folder("path/to/images/") # From CSV (first column = image paths, header-less) ds_csv = InferenceDataset.from_csv( csv_path="data/test.csv", base_dir="data/", ) sample = ds_folder[0] print(sample.keys()) # dict_keys(['image', 'shape', 'path']) print(sample["image"].shape) # torch.Size([3, H, W]) ``` -------------------------------- ### Checkpointing Strategies for Model Saving Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Implements time-based, iteration-based, and best-score-based checkpointing to save model states during training. Ensure the checkpoint directory exists and metrics are tracked correctly for best-score saving. ```python from dh_segment_torch.training import ( TimeCheckpoint, IterationCheckpoint, BestCheckpoint, ) from dh_segment_torch.metrics import MetricTracker import os os.makedirs("model/", exist_ok=True) # Save every N iterations, keep last K iter_ckpt = IterationCheckpoint( checkpoint_dir="model/", prefix="train", save_every=200, checkpoints_to_keep=3, ) # Save best model by validation metric tracker = MetricTracker("+miou") # "+" = higher is better best_ckpt = BestCheckpoint(tracker=tracker, checkpoint_dir="model/") # Simulate updates state = {"model": {}, "optimizer": {}, "epoch": 1} tracker.update({"miou": 0.85}, {}) best_ckpt.maybe_save(state) # saves if 0.85 > previous best ``` -------------------------------- ### CLI: predict_probas.py for saving probability maps Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Command-line interface script to generate and save probability maps for input images. Requires a configuration file (e.g., JSONnet) specifying output directory and data paths. ```bash # predict_probas.jsonnet imports train.jsonnet and only needs output_directory + data path python scripts/predict_probas.py configs/predict_probas.jsonnet # Writes one .npy file per input image to the configured output_directory ``` -------------------------------- ### Check GPU availability Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/demo/dhSegment_paper.ipynb Verifies that a CUDA-enabled GPU is available and prints its total memory. A GPU is recommended for effective training. ```python assert torch.cuda.device_count() >= 1 print("The GPU has %.2f GB of memory."%(torch.cuda.get_device_properties(0).total_memory//1024**2/1000)) ``` -------------------------------- ### EarlyStopping for Training Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Implement early stopping to prevent overfitting during model training. Requires a MetricTracker to monitor performance. ```python from dh_segment_torch.training import EarlyStopping from dh_segment_torch.metrics import MetricTracker tracker = MetricTracker("+miou") stopper = EarlyStopping(tracker=tracker, patience=10) stopper.reset() for epoch in range(100): val_miou = 0.80 if epoch < 15 else 0.75 # stops improving after epoch 15 tracker.update({"miou": val_miou}, {}) if stopper.should_terminate(): print(f"Early stop at epoch {epoch}") break ``` -------------------------------- ### Define Model Parameters for DH-Segment Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/demo/dhSegment_paper.ipynb Sets up the model architecture, including the encoder and decoder configurations, number of classes, and the path to the pre-trained model state dictionary. Also specifies the device to be used for computation (e.g., CUDA). ```python model_params = { "model": { "encoder": "resnet50", "decoder": {"decoder_channels": [512, 256, 128, 64, 32], "max_channels": 512} }, "num_classes": 3, "model_state_dict": "./model_test/best_checkpoint", # To be completed "device": "cuda:0" } ``` -------------------------------- ### Load InferenceModel from parameters Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Loads a trained segmentation model for inference. Supports loading from a saved checkpoint and configuring patch-based inference for large images. ```python from dh_segment_torch.inference import InferenceModel from dh_segment_torch.config import Params # From a saved model checkpoint inference_model = InferenceModel.from_params(Params({ "model": { "encoder": "resnet50", "decoder": {"decoder_channels": [512, 256, 128, 64, 32], "max_channels": 512}, }, "num_classes": 3, "model_state_dict": "model/best_model_miou=0.87.pth", "device": "cuda:0", # patch-based inference for large images: # "patch_size": [512, 512], # "patches_overlap": 0.25, # "patches_batch_size": 8, })) import torch images = torch.rand(2, 3, 512, 512) shapes = torch.tensor([[512, 512], [512, 512]]) probas = inference_model.predict(images, shapes) print(probas.shape) # torch.Size([2, 3, 512, 512]) print(probas.sum(dim=1)) # sums to ~1 along class axis (softmax) ``` -------------------------------- ### Write Annotations to File Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/demo/dhSegment_paper.ipynb Configures an annotation writer with specified parameters, including the annotation format (VIA2), output file path, and the generated annotations. It then writes these annotations to the specified file using multiple workers for efficiency. ```python annotation_writer_params = Params({ 'type': 'via2', 'attrib_name': 'type', 'json_path': './annotations.json', 'annotation_iterator': annots }) writer = AnnotationWriter.from_params(annotation_writer_params) writer.write(num_workers=8) ``` -------------------------------- ### Import necessary libraries Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/demo/dhSegment_paper.ipynb Imports core components from the dhSegment library and standard Python libraries for data handling and deep learning. ```python from dh_segment_torch.config import Params from dh_segment_torch.data import DataSplitter from dh_segment_torch.data.annotation import AnnotationWriter from dh_segment_torch.training import Trainer from dh_segment_torch.inference import PredictProcess from dh_segment_torch.post_processing import PostProcessingPipeline import os import torch ``` -------------------------------- ### Apply Pipeline to Probability Map Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Applies a pre-defined pipeline to a single-class probability map to generate geometric results. Ensure the pipeline is correctly configured before applying. ```python probas = np.random.rand(3, 512, 512).astype(np.float32) text_channel = probas[1] # single-class probability map result = pipeline.apply(text_channel) print(type(result["res"][0])) # ``` -------------------------------- ### CLI: predict_annotations.py for saving structured annotations Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Command-line interface script to generate and save structured annotations (e.g., Via or Web Annotation format). The configuration must include a 'writer' key. ```bash python scripts/predict_annotations.py configs/predict_annotations.jsonnet # The config must contain a "writer" key (e.g. type "via" or "web_annotation") # and an optional "num_processes" for parallel writing ``` -------------------------------- ### Calculating Segmentation Metrics (IoU, Precision, F1) Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Computes segmentation metrics like IoU, Precision, and F1-Score over batches and provides final aggregated values. Metrics can be configured for different averaging strategies (e.g., 'macro'). ```python from dh_segment_torch.metrics import IoU, Precision, F1Score import torch num_classes = 3 iou = IoU(num_classes=num_classes, average="macro") f1 = F1Score(num_classes=num_classes) # Simulate two batches for _ in range(2): logits = torch.rand(4, num_classes, 128, 128) target = torch.randint(0, num_classes, (4, 128, 128)) iou(target, logits) f1(target, logits) print(iou.get_metric_value(reset=True)) # float: mean IoU print(f1.get_metric_value(reset=True)) # float: F1 score ``` -------------------------------- ### DagPipeline for Post-Processing Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Build and apply DAG-structured pipelines for post-processing segmentation results. Allows operations to share intermediate data. ```python from dh_segment_torch.post_processing import ( DagPipeline, OperationsInputs, Thresholding, FilterSmallObjects, PolygonDetection, ) import numpy as np pipeline = DagPipeline(operations={ "binary": OperationsInputs(inputs="probas", ops=[Thresholding(low_threshold=0.5)]), "cleaned": OperationsInputs(inputs="binary", ops=[FilterSmallObjects(min_size=200)]), "polygons": OperationsInputs(inputs="cleaned", ops=[PolygonDetection(min_area=100)]), }) probas = np.random.rand(256, 256).astype(np.float32) result = pipeline.apply(probas=probas) # result contains all intermediate keys: "binary", "cleaned", "polygons" print(len(result["polygons"])) # number of detected polygons ``` -------------------------------- ### Thresholding Operations for Binary Masks Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Converts continuous probability maps into binary masks using fixed, Otsu automatic, adaptive local, or hysteresis thresholding methods. Ensure probability maps are in the correct format (e.g., float32). ```python from dh_segment_torch.post_processing import ( Thresholding, AdaptiveThresholding, HysteresisThresholding, ) import numpy as np prob_map = np.random.rand(256, 256).astype(np.float32) # Fixed threshold (0.0–1.0 floats are auto-scaled to 0–255) binary = Thresholding(low_threshold=0.5).apply(prob_map) # Otsu automatic threshold (pass negative low_threshold) otsu_binary = Thresholding(low_threshold=-1).apply(prob_map) # Adaptive local threshold adaptive = AdaptiveThresholding( high_threshold=1.0, adaptive_method="gaussian", blockSize=11, C=2, ).apply(prob_map) # Hysteresis: keep connected components touching high threshold hysteresis = HysteresisThresholding( low_threshold=0.3, high_threshold=0.6, ).apply(prob_map) ``` -------------------------------- ### ResNet Encoders for ImageNet Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Provides pre-trained ResNet/ResNeXt/Wide-ResNet encoders available as string names. Used within config files or `from_params` calls. Demonstrates building an encoder and extracting features. ```python from dh_segment_torch.models.encoders import ResNetEncoder # All available variants (used as the "encoder" key in config) # "resnet18", "resnet34", "resnet50", "resnet101", "resnet152" # "resnext50_32x4d", "resnext101_32x8d" # "wide_resnet50_2", "wide_resnet101_2" encoder = ResNetEncoder.resnet101(pretrained=True, blocks=4) print(encoder.output_dims) # [3, 64, 256, 512, 1024, 2048] import torch features = encoder(torch.rand(1, 3, 512, 512)) print([f.shape for f in features]) ``` -------------------------------- ### Define Dataset Parameters for DH-Segment Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/demo/dhSegment_paper.ipynb Specifies the dataset configuration, including the type, folder path, and pre-processing transforms. This is used to load and prepare the data for model training or inference. ```python dataset_params = { "type": "folder", "folder": "/content/drive/My Drive/sample_catastici", "pre_processing": {"transforms": [{"type": "fixed_size_resize", "output_size": 1e6}]} } ``` -------------------------------- ### Define color-to-class mappings with ColorLabels Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt ColorLabels maps pixel colors to class indices for segmentation tasks. It determines `num_classes`, enables automatic loss selection, and supports both multiclass and multilabel scenarios. Colors can be specified directly or auto-generated. ```python from dh_segment_torch.data import ColorLabels import json # --- From a list of dicts (Jsonnet "labels_list" type) --- color_labels = ColorLabels.from_list_of_color_labels([ {"color": "#000000", "label": "background"}, {"color": "#FF0000", "label": "text"}, {"color": "#0000FF", "label": "illustration"}, ]) print(color_labels) # ColorLabels(num_classes=3, multilabel=False, labels=['background', 'text', 'illustration']) # --- From a saved JSON file --- color_labels.to_json("color_labels.json") loaded = ColorLabels.from_labels_json_file("color_labels.json") # --- Multilabel: each pixel can belong to multiple classes --- ml_labels = ColorLabels.from_colors_multilabel( colors=["#FF0000", "#00FF00", "#0000FF"], labels=["text", "table", "figure"], ) print(ml_labels.multilabel) # True print(ml_labels.num_classes) # 3 (one-hot size) # --- Minimal: auto-generate colors from class names --- auto = ColorLabels.from_labels(["background", "page", "margin"]) ``` -------------------------------- ### Split datasets into train/validation/test CSVs with DataSplitter Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt DataSplitter partitions a pandas DataFrame of image and label paths into separate CSV files for training, validation, and testing. It handles ratio normalization if they do not sum to 1.0. ```python import pandas as pd from dh_segment_torch.data import DataSplitter # Build a dataframe of image/label pairs data = pd.DataFrame({ "image": ["images/001.jpg", "images/002.jpg", "images/003.jpg", "images/004.jpg"], "label": ["labels/001.png", "labels/002.png", "labels/003.png", "labels/004.png"], }) splitter = DataSplitter(train_ratio=0.7, val_ratio=0.2, test_ratio=0.1) splitter.split_data( data, train_csv_path="data/train.csv", val_csv_path="data/val.csv", test_csv_path="data/test.csv", ) # Produces headerless CSVs with two columns: image_path, label_path ``` -------------------------------- ### Polygon and Bounding Box Detection Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Detects polygons and axis-aligned bounding boxes from binary masks, with options to filter by area and limit the number of detected objects. Results are returned as Shapely Polygon objects. ```python from dh_segment_torch.post_processing import PolygonDetection, BoxDetection import numpy as np binary = (np.random.rand(256, 256) > 0.7).astype(np.uint8) * 255 # Detect polygons, filter by minimum area, keep top-5 polygons = PolygonDetection(min_area=100, max_polygons=5).apply(binary) print(polygons[0].geom_type) # 'Polygon' print(polygons[0].area) # Detect axis-aligned bounding boxes boxes = BoxDetection(min_area=50).apply(binary) print(boxes[0].geom_type) # 'Polygon' (rectangle) ``` -------------------------------- ### Morphological Operations for Binary Image Refinement Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Applies morphological operations such as filtering small objects/holes, opening/closing, and skeletonization to refine binary masks. Ensure binary images are in uint8 format with values 0 or 255. ```python from dh_segment_torch.post_processing import ( FilterSmallObjects, FilterSmallHoles, OpenClose, Skeletonize, DiskStructuringElement, ) import numpy as np binary = (np.random.rand(256, 256) > 0.5).astype(np.uint8) * 255 # Remove objects smaller than 300 pixels cleaned = FilterSmallObjects(min_size=300).apply(binary) # Fill holes smaller than 200 pixels filled = FilterSmallHoles(max_size=200).apply(cleaned) # Morphological open then close with a disk of radius 3 se = DiskStructuringElement(radius=3) smoothed = OpenClose(structuring_element=se).apply(filled) # Skeletonize (medial axis) skeleton = Skeletonize().apply(smoothed) ``` -------------------------------- ### SegmentationModel with Encoder-Decoder Architecture Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Composes pre-trained encoders with decoders for segmentation tasks. The forward method returns logits and optionally loss. Can be built manually or from a Params dict. ```python from dh_segment_torch.models import SegmentationModel from dh_segment_torch.models.encoders import ResNetEncoder from dh_segment_torch.models.decoders import UnetDecoder from dh_segment_torch.nn.loss import CrossEntropyLoss import torch # Build manually encoder = ResNetEncoder.resnet50(pretrained=True) decoder = UnetDecoder( encoder_channels=encoder.output_dims, num_classes=3, decoder_channels=[512, 256, 128, 64, 32], max_channels=512, ) model = SegmentationModel(encoder, decoder, loss=CrossEntropyLoss()) # Forward pass batch_images = torch.rand(2, 3, 512, 512) batch_targets = torch.randint(0, 3, (2, 512, 512)) output = model(input=batch_images, target=batch_targets, track_metrics=True) print(output.keys()) # dict_keys(['logits', 'loss']) print(output["logits"].shape) # torch.Size([2, 3, 512, 512]) # Build from a Params dict (registered as "segmentation_model") from dh_segment_torch.config import Params model2 = SegmentationModel.from_params(Params({ "encoder": "resnet101", "decoder": {"decoder_channels": [512, 256, 128, 64, 32], "max_channels": 512}, "num_classes": 3, })) ``` -------------------------------- ### ColorLabels - color-to-class mapping Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt The ColorLabels class handles the mapping between RGB pixel colors and class indices or binary vectors. It is crucial for defining the segmentation classes and is used throughout the data pipeline and model training. ```APIDOC ## ColorLabels — color-to-class mapping `ColorLabels` maps RGB pixel colors in label images to class indices (multiclass) or binary one-hot vectors (multilabel). It is the central contract between the data pipeline and the model — it determines `num_classes`, enables automatic loss selection, and drives label assignment transforms. ```python from dh_segment_torch.data import ColorLabels import json # --- From a list of dicts (Jsonnet "labels_list" type) --- color_labels = ColorLabels.from_list_of_color_labels([ {"color": "#000000", "label": "background"}, {"color": "#FF0000", "label": "text"}, {"color": "#0000FF", "label": "illustration"}, ]) print(color_labels) # ColorLabels(num_classes=3, multilabel=False, labels=['background', 'text', 'illustration']) # --- From a saved JSON file --- color_labels.to_json("color_labels.json") loaded = ColorLabels.from_labels_json_file("color_labels.json") # --- Multilabel: each pixel can belong to multiple classes --- ml_labels = ColorLabels.from_colors_multilabel( colors=["#FF0000", "#00FF00", "#0000FF"], labels=["text", "table", "figure"], ) print(ml_labels.multilabel) # True print(ml_labels.num_classes) # 3 (one-hot size) # --- Minimal: auto-generate colors from class names --- auto = ColorLabels.from_labels(["background", "page", "margin"]) ``` ``` -------------------------------- ### Define a PostProcessingPipeline Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt Applies a sequence of operations to probability maps, such as filtering, thresholding, and polygon detection. Use `DagPipeline` for more complex DAG-structured pipelines. ```python from dh_segment_torch.post_processing import ( PostProcessingPipeline, GaussianFilter, Thresholding, FilterSmallObjects, PolygonDetection, ) import numpy as np pipeline = PostProcessingPipeline(operations=[ GaussianFilter(sigma=1.0), Thresholding(low_threshold=0.5), # binary mask at 50% FilterSmallObjects(min_size=500), # remove noise PolygonDetection(min_area=200), # extract polygons ]) ``` -------------------------------- ### DataSplitter - train/val/test CSV generation Source: https://context7.com/dhlab-epfl/dhsegment-torch/llms.txt The DataSplitter class is used to partition a dataset of image and label paths into training, validation, and testing sets, generating corresponding CSV files for easy data loading. ```APIDOC ## DataSplitter — train/val/test CSV generation `DataSplitter` partitions a pandas DataFrame of `(image_path, label_path)` pairs into train, validation, and test CSV files. Ratios are automatically normalized if they do not sum to 1.0. ```python import pandas as pd from dh_segment_torch.data import DataSplitter # Build a dataframe of image/label pairs data = pd.DataFrame({ "image": ["images/001.jpg", "images/002.jpg", "images/003.jpg", "images/004.jpg"], "label": ["labels/001.png", "labels/002.png", "labels/003.png", "labels/004.png"], }) splitter = DataSplitter(train_ratio=0.7, val_ratio=0.2, test_ratio=0.1) splitter.split_data( data, train_csv_path="data/train.csv", val_csv_path="data/val.csv", test_csv_path="data/test.csv", ) # Produces headerless CSVs with two columns: image_path, label_path ``` ``` -------------------------------- ### dhSegment Citation Source: https://github.com/dhlab-epfl/dhsegment-torch/blob/master/README.md BibTeX entry for citing the dhSegment paper in research. This should be used when referencing the tool in academic work. ```bibtex @inproceedings{oliveiraseguinkaplan2018dhsegment, title={dhSegment: A generic deep-learning approach for document segmentation}, author={Ares Oliveira, Sofia and Seguin, Benoit and Kaplan, Frederic}, booktitle={Frontiers in Handwriting Recognition (ICFHR), 2018 16th International Conference on}, pages={7--12}, year={2018}, organization={IEEE} } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.