169 lines
4.5 KiB
Python
169 lines
4.5 KiB
Python
![]() |
#!/usr/bin/env python3
|
||
|
"""
|
||
|
Configuration file for YOLOv8 French ID Card Detection
|
||
|
"""
|
||
|
import os
|
||
|
from pathlib import Path
|
||
|
|
||
|
# Base directories
|
||
|
BASE_DIR = Path(__file__).parent
|
||
|
DATA_DIR = BASE_DIR / "data"
|
||
|
LOGS_DIR = BASE_DIR / "logs"
|
||
|
|
||
|
# Data configuration
|
||
|
DATA_YAML_PATH = DATA_DIR / "data.yaml"
|
||
|
|
||
|
# Logging configuration
|
||
|
TRAINING_LOG_PATH = LOGS_DIR / "training.log"
|
||
|
INFERENCE_LOG_PATH = LOGS_DIR / "inference.log"
|
||
|
EVAL_LOG_PATH = LOGS_DIR / "eval.log"
|
||
|
|
||
|
# Results directories (sử dụng runs từ YOLO)
|
||
|
INFERENCE_RESULTS_DIR = Path("runs/detect")
|
||
|
EVALUATION_RESULTS_DIR = Path("runs/val")
|
||
|
VISUALIZATION_RESULTS_DIR = Path("runs/detect")
|
||
|
|
||
|
# Default configurations
|
||
|
DEFAULT_TRAINING_CONFIG = {
|
||
|
'epochs': 100,
|
||
|
'batch': 16, # Sửa từ batch_size thành batch
|
||
|
'imgsz': 640,
|
||
|
'patience': 50,
|
||
|
'save_period': 10,
|
||
|
'device': 'auto',
|
||
|
'project': 'runs/train',
|
||
|
'exist_ok': True,
|
||
|
'pretrained': True,
|
||
|
'optimizer': 'auto',
|
||
|
'verbose': False, # Giảm verbose
|
||
|
'seed': 42,
|
||
|
'deterministic': True,
|
||
|
'single_cls': True,
|
||
|
'rect': False,
|
||
|
'cos_lr': True,
|
||
|
'close_mosaic': 10,
|
||
|
'resume': False,
|
||
|
'amp': True,
|
||
|
'fraction': 1.0,
|
||
|
'cache': False,
|
||
|
'lr0': 0.01,
|
||
|
'lrf': 0.01,
|
||
|
'momentum': 0.937,
|
||
|
'weight_decay': 0.0005,
|
||
|
'warmup_epochs': 3.0,
|
||
|
'warmup_momentum': 0.8,
|
||
|
'warmup_bias_lr': 0.1,
|
||
|
'box': 7.5,
|
||
|
'cls': 0.5,
|
||
|
'dfl': 1.5,
|
||
|
'pose': 12.0,
|
||
|
'kobj': 2.0,
|
||
|
'label_smoothing': 0.0,
|
||
|
'nbs': 64,
|
||
|
'overlap_mask': False, # Tắt mask để tránh tải YOLOv11
|
||
|
'mask_ratio': 4,
|
||
|
'dropout': 0.0,
|
||
|
'val': True,
|
||
|
'plots': True,
|
||
|
'save': True,
|
||
|
'save_json': False,
|
||
|
'save_hybrid': False,
|
||
|
'conf': 0.001,
|
||
|
'iou': 0.6,
|
||
|
'max_det': 300,
|
||
|
'half': True,
|
||
|
'dnn': False,
|
||
|
'plots': True,
|
||
|
'source': None,
|
||
|
'show': False,
|
||
|
'save_txt': False,
|
||
|
'save_conf': False,
|
||
|
'save_crop': False,
|
||
|
'show_labels': True,
|
||
|
'show_conf': True,
|
||
|
'vid_stride': 1,
|
||
|
'line_thickness': 3,
|
||
|
'visualize': False,
|
||
|
'augment': True, # Bật augmentation giống Roboflow
|
||
|
'hsv_s': 0.61, # Saturation augmentation ~61% (Roboflow: Between -61% and +61%)
|
||
|
'hsv_h': 0.015, # Hue augmentation
|
||
|
'hsv_v': 0.4, # Value augmentation
|
||
|
'degrees': 0.0, # Không xoay ảnh
|
||
|
'translate': 0.1, # Dịch chuyển nhẹ
|
||
|
'scale': 0.5, # Scale augmentation
|
||
|
'shear': 0.0, # Không shear
|
||
|
'perspective': 0.0, # Không perspective
|
||
|
'flipud': 0.0, # Không flip vertical
|
||
|
'fliplr': 0.5, # Flip horizontal 50%
|
||
|
'mosaic': 1.0, # Bật mosaic augmentation
|
||
|
'mixup': 0.0, # Không dùng mixup
|
||
|
'copy_paste': 0.0, # Không copy paste
|
||
|
'erasing': 0.08,
|
||
|
'agnostic_nms': False,
|
||
|
'classes': None,
|
||
|
'retina_masks': False,
|
||
|
'boxes': True,
|
||
|
'format': 'torchscript',
|
||
|
'keras': False,
|
||
|
'optimize': False,
|
||
|
'int8': False,
|
||
|
'dynamic': False,
|
||
|
'simplify': False,
|
||
|
'opset': 17,
|
||
|
'workspace': 4,
|
||
|
'nms': False,
|
||
|
}
|
||
|
|
||
|
DEFAULT_INFERENCE_CONFIG = {
|
||
|
'conf_threshold': 0.25,
|
||
|
'iou_threshold': 0.45,
|
||
|
'max_det': 300,
|
||
|
'line_thickness': 3,
|
||
|
'show_labels': True,
|
||
|
'show_conf': True,
|
||
|
}
|
||
|
|
||
|
def create_directories():
|
||
|
"""Create all necessary directories"""
|
||
|
directories = [
|
||
|
LOGS_DIR,
|
||
|
]
|
||
|
|
||
|
for directory in directories:
|
||
|
directory.mkdir(parents=True, exist_ok=True)
|
||
|
|
||
|
print("Directories created successfully")
|
||
|
|
||
|
def get_best_model_path(model_size: str = 'n') -> str:
|
||
|
"""Get path to best trained model from runs/train"""
|
||
|
runs_dir = Path('runs/train')
|
||
|
if not runs_dir.exists():
|
||
|
return None
|
||
|
|
||
|
training_runs = list(runs_dir.glob(f'yolov8_{model_size}_french_id_card'))
|
||
|
if not training_runs:
|
||
|
return None
|
||
|
|
||
|
latest_run = max(training_runs, key=lambda x: x.stat().st_mtime)
|
||
|
best_model_path = latest_run / 'weights' / 'best.pt'
|
||
|
|
||
|
return str(best_model_path) if best_model_path.exists() else None
|
||
|
|
||
|
def get_exported_model_path(model_size: str = 'n', format: str = 'onnx') -> str:
|
||
|
"""Get path to exported model"""
|
||
|
return str(Path("runs/export") / f"yolov8_{model_size}_french_id_card.{format}")
|
||
|
|
||
|
def get_latest_training_run():
|
||
|
"""Get path to latest training run"""
|
||
|
runs_dir = Path('runs/train')
|
||
|
if not runs_dir.exists():
|
||
|
return None
|
||
|
|
||
|
training_runs = list(runs_dir.glob('yolov8_*_french_id_card'))
|
||
|
if not training_runs:
|
||
|
return None
|
||
|
|
||
|
return max(training_runs, key=lambda x: x.stat().st_mtime)
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
create_directories()
|