Download code/src/preprocessing/augment_recipe.py from savastakan/hitit-cuneiform-ocr: direct link, hf CLI and curl.
- Browser
- Download file 4.38 kB
-
https://huggingface.co/savastakan/hitit-cuneiform-ocr/resolve/main/code/src/preprocessing/augment_recipe.py
- Command line
-
hf download hf://savastakan/hitit-cuneiform-ocr/code/src/preprocessing/augment_recipe.py
-
curl -L -o augment_recipe.py https://huggingface.co/savastakan/hitit-cuneiform-ocr/resolve/main/code/src/preprocessing/augment_recipe.py
4.38 kB
| #!/usr/bin/env python3 | |
| """Train-time augmentation pipeline (Albumentations-based). | |
| SOTA recipe: elastic + grid distortion + morph + CLAHE + color jitter. | |
| Reference: Albumentations OCR recipe, arXiv:2508.11499 historical HTR. | |
| """ | |
| from pathlib import Path | |
| import yaml | |
| ROOT = Path("/arf/scratch/stakan/hitit-proje") | |
| def build_train_transform(config=None): | |
| """Returns Albumentations.Compose — import edilir training'de.""" | |
| import albumentations as A | |
| from albumentations.pytorch import ToTensorV2 | |
| if config is None: | |
| config = yaml.safe_load(open(ROOT / "hitit_ocr" / "configs" / "preprocessing.yaml")) | |
| aug = config.get('augment_train', {}) | |
| norm = config.get('normalization', {}) | |
| # Pipeline adımları | |
| steps = [] | |
| # Geometric distortion (elastic + grid) | |
| geo_aug = [] | |
| if aug.get('elastic_transform', {}).get('enabled'): | |
| et = aug['elastic_transform'] | |
| geo_aug.append(A.ElasticTransform( | |
| alpha=et.get('alpha', 40.0), | |
| sigma=et.get('sigma', 6.0), | |
| alpha_affine=et.get('alpha_affine', 8.0), | |
| p=1.0, | |
| border_mode=0 | |
| )) | |
| if aug.get('grid_distortion', {}).get('enabled'): | |
| gd = aug['grid_distortion'] | |
| geo_aug.append(A.GridDistortion( | |
| num_steps=gd.get('num_steps', 5), | |
| distort_limit=gd.get('distort_limit', 0.15), | |
| p=1.0, | |
| border_mode=0 | |
| )) | |
| if geo_aug: | |
| steps.append(A.OneOf(geo_aug, p=0.5)) | |
| # Morphological (wedge thickness variation) | |
| if aug.get('morphological', {}).get('enabled'): | |
| m = aug['morphological'] | |
| # Custom implementation (Albumentations'da tam yok) | |
| # Kullanım: training script'te manuel apply | |
| pass | |
| # Color jitter | |
| if aug.get('color_jitter', {}).get('enabled'): | |
| cj = aug['color_jitter'] | |
| steps.append(A.ColorJitter( | |
| brightness=cj.get('brightness', 0.2), | |
| contrast=cj.get('contrast', 0.2), | |
| saturation=cj.get('saturation', 0.1), | |
| hue=0.0, | |
| p=cj.get('p', 0.5) | |
| )) | |
| # Random horizontal flip — cuneiform için DEĞİL (sign orientation önemli) | |
| # if aug.get('horizontal_flip', {}).get('enabled'): | |
| # steps.append(A.HorizontalFlip(p=0.5)) | |
| # Normalization | |
| if norm.get('strategy') == 'dataset_specific': | |
| # norm_stats'tan yükle | |
| import json | |
| stats_path = ROOT / "datasets" / "processed" / "normalization_stats.json" | |
| if stats_path.exists(): | |
| ns = json.load(open(stats_path)) | |
| mean = ns['global_rgb']['mean'] | |
| std = ns['global_rgb']['std'] | |
| else: | |
| mean = [0.485, 0.456, 0.406] | |
| std = [0.229, 0.224, 0.225] | |
| elif norm.get('strategy') == 'imagenet': | |
| mean = [0.485, 0.456, 0.406] | |
| std = [0.229, 0.224, 0.225] | |
| else: | |
| mean = [0.0, 0.0, 0.0] | |
| std = [1.0, 1.0, 1.0] | |
| steps.append(A.Normalize(mean=mean, std=std)) | |
| steps.append(ToTensorV2()) | |
| return A.Compose(steps) | |
| def build_val_transform(config=None): | |
| """Validation/test: sadece normalize.""" | |
| import albumentations as A | |
| from albumentations.pytorch import ToTensorV2 | |
| import json | |
| if config is None: | |
| config = yaml.safe_load(open(ROOT / "hitit_ocr" / "configs" / "preprocessing.yaml")) | |
| norm = config.get('normalization', {}) | |
| if norm.get('strategy') == 'dataset_specific': | |
| stats_path = ROOT / "datasets" / "processed" / "normalization_stats.json" | |
| if stats_path.exists(): | |
| ns = json.load(open(stats_path)) | |
| mean, std = ns['global_rgb']['mean'], ns['global_rgb']['std'] | |
| else: | |
| mean, std = [0.485, 0.456, 0.406], [0.229, 0.224, 0.225] | |
| else: | |
| mean, std = [0.485, 0.456, 0.406], [0.229, 0.224, 0.225] | |
| return A.Compose([ | |
| A.Normalize(mean=mean, std=std), | |
| ToTensorV2(), | |
| ]) | |
| if __name__ == '__main__': | |
| # Test/print pipeline | |
| try: | |
| import albumentations | |
| t = build_train_transform() | |
| print(f"Train pipeline: {len(t.transforms)} steps") | |
| for step in t.transforms: | |
| print(f" - {type(step).__name__}: p={getattr(step, 'p', 'n/a')}") | |
| except ImportError: | |
| print("albumentations kurulu değil. pip install albumentations") | |