Files
boc/iom/ai_pipeline/full_training_pipeline.py
T
Bernt bae705aa97 ARCHITECTURE: NFC roadmap, edge AI, audit logging
- Add NFC ePassport roadmap (ICAO 9303, eIDAS)
- Add TensorFlow.js edge face detection (BlazeFace)
- Add structured audit logger (GDPR-compliant)
- Risk scoring support

Part of KYC Apple Native UX v1.1.0
2026-06-29 16:24:48 +00:00

190 lines
5.8 KiB
Python

"""
Full Training Pipeline
Combine synthetic + quiXzoom data for production AI models
"""
import sys
sys.path.insert(0, '/home/bernt/.openclaw/workspace/iom')
from ai_pipeline.data_collection import DataCollector, SyntheticDataGenerator
from ai_pipeline.quixzoom_data_ingestion import QuixzoomDataIngestion
from ai_pipeline.training_pipeline import TrainingPipeline, TrainingConfig
import os
import shutil
def combine_datasets():
"""Combine synthetic and quiXzoom datasets"""
print("=== Combining Datasets ===\n")
# Create combined dataset
combined_path = "/tmp/iom_combined_dataset"
os.makedirs(combined_path, exist_ok=True)
# 1. Generate synthetic data
print("1. Generating synthetic data...")
synthetic_collector = DataCollector(f"{combined_path}/synthetic")
generator = SyntheticDataGenerator()
scenes = ["street_view", "building_facade", "bridge", "road", "sidewalk", "park"]
for i in range(100):
scene = scenes[i % len(scenes)]
synthetic = generator.generate_synthetic_image(scene, num_defects=3)
synthetic_collector.add_annotation(
image_id=f"syn_{i:04d}",
filename=f"syn_{i:04d}.jpg",
width=synthetic["width"],
height=synthetic["height"],
objects=synthetic["objects"],
scene_type=scene,
split="train" if i < 80 else "val" if i < 90 else "test"
)
# 2. Ingest quiXzoom data
print("2. Ingesting quiXzoom data...")
quixzoom_ingestion = QuixzoomDataIngestion(f"{combined_path}/quixzoom")
quixzoom_results = quixzoom_ingestion.run_full_pipeline()
# 3. Merge datasets
print("3. Merging datasets...")
merged_path = f"{combined_path}/merged"
os.makedirs(f"{merged_path}/images/train", exist_ok=True)
os.makedirs(f"{merged_path}/images/val", exist_ok=True)
os.makedirs(f"{merged_path}/images/test", exist_ok=True)
os.makedirs(f"{merged_path}/labels/train", exist_ok=True)
os.makedirs(f"{merged_path}/labels/val", exist_ok=True)
os.makedirs(f"{merged_path}/labels/test", exist_ok=True)
# Copy synthetic data
for split in ["train", "val", "test"]:
src_img = f"{combined_path}/synthetic/images/{split}"
src_lbl = f"{combined_path}/synthetic/labels/{split}"
dst_img = f"{merged_path}/images/{split}"
dst_lbl = f"{merged_path}/labels/{split}"
if os.path.exists(src_img):
for f in os.listdir(src_img):
shutil.copy(f"{src_img}/{f}", dst_img)
if os.path.exists(src_lbl):
for f in os.listdir(src_lbl):
shutil.copy(f"{src_lbl}/{f}", dst_lbl)
# Copy quiXzoom data
for split in ["train", "val", "test"]:
src = f"{combined_path}/quixzoom/{split}"
dst = f"{merged_path}/labels/{split}"
if os.path.exists(src):
for f in os.listdir(src):
shutil.copy(f"{src}/{f}", dst)
# Count merged data
train_count = len(os.listdir(f"{merged_path}/labels/train"))
val_count = len(os.listdir(f"{merged_path}/labels/val"))
test_count = len(os.listdir(f"{merged_path}/labels/test"))
print(f"\nMerged dataset:")
print(f" Train: {train_count}")
print(f" Val: {val_count}")
print(f" Test: {test_count}")
print(f" Total: {train_count + val_count + test_count}")
return merged_path
def train_production_model(dataset_path: str):
"""Train production-ready model"""
print("\n=== Training Production Model ===\n")
from ultralytics import YOLO
# Create data.yaml
import json
data_yaml = {
"path": dataset_path,
"train": "images/train",
"val": "images/val",
"test": "images/test",
"nc": 10,
"names": [
"street_light", "traffic_sign", "bench", "trash_can",
"sidewalk", "road", "building", "bridge", "tree", "graffiti"
]
}
with open(f"{dataset_path}/data.yaml", "w") as f:
json.dump(data_yaml, f, indent=2)
# Load model
model = YOLO("yolov8n.pt")
# Train with better settings for production
print("Training production model...")
results = model.train(
data=f"{dataset_path}/data.yaml",
epochs=50, # More epochs for production
batch=16,
imgsz=640,
device="cpu", # Change to "0" for GPU
project="/tmp/iom_production_models",
name="yolo_infrastructure_v1",
exist_ok=True,
patience=10, # Early stopping
save=True,
pretrained=True
)
print(f"Training complete!")
return model
def export_production_model(model):
"""Export model to all production formats"""
print("\n=== Exporting Production Model ===\n")
formats = ["onnx", "torchscript", "openvino", "engine"]
for fmt in formats:
try:
print(f"Exporting to {fmt}...")
model.export(format=fmt)
print(f"{fmt} export successful")
except Exception as e:
print(f"{fmt} export failed: {e}")
print("\nExport complete!")
def main():
"""Main production training pipeline"""
print("=" * 60)
print("PRODUCTION AI TRAINING PIPELINE")
print("=" * 60)
# 1. Combine datasets
dataset_path = combine_datasets()
# 2. Train model
model = train_production_model(dataset_path)
# 3. Export
export_production_model(model)
print("\n" + "=" * 60)
print("PRODUCTION TRAINING COMPLETE")
print("=" * 60)
print("\nModels saved to: /tmp/iom_production_models/")
print("\nNext steps:")
print("1. Validate model on test set")
print("2. Deploy to production API")
print("3. Monitor performance")
print("4. Collect more data and retrain")
if __name__ == '__main__':
main()