Download ml/scripts/run.sh from PRiyanshu0-1/TrackChain: direct link, hf CLI and curl.
- Browser
- Download file 12.1 kB
-
https://huggingface.co/PRiyanshu0-1/TrackChain/resolve/main/ml/scripts/run.sh
- Command line
-
hf download hf://PRiyanshu0-1/TrackChain/ml/scripts/run.sh
-
curl -L -o run.sh https://huggingface.co/PRiyanshu0-1/TrackChain/resolve/main/ml/scripts/run.sh
12.1 kB
| # ============================================================================= | |
| # TrackChain Master ML Training Orchestrator | |
| # Trains all 5 Phase 2 models in dependency order with SMART checkpointing. | |
| # | |
| # Usage: | |
| # chmod +x ml/scripts/run.sh | |
| # ./ml/scripts/run.sh # Runs ONLY missing/failed steps | |
| # ./ml/scripts/run.sh --force # Re-runs EVERYTHING (overwrites) | |
| # ./ml/scripts/run.sh --clean # Wipes all checkpoints | |
| # ./ml/scripts/run.sh --skip-yolo --skip-patchcore # Skips specific steps | |
| # | |
| # Output: | |
| # - Trained weights in artifacts/checkpoints/ | |
| # - ONNX/INT8 exports in artifacts/exports/ | |
| # - Training logs in artifacts/logs/ | |
| # ============================================================================= | |
| set -euo pipefail | |
| # --- Configuration ----------------------------------------------------------- | |
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |
| REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" | |
| LOG_DIR="$REPO_ROOT/artifacts/logs" | |
| CHECKPOINT_DIR="$REPO_ROOT/artifacts/checkpoints" | |
| EXPORT_DIR="$REPO_ROOT/artifacts/exports" | |
| DATA_ROOT="$REPO_ROOT/data" | |
| export PYTHONPATH="$REPO_ROOT:${PYTHONPATH:-}" | |
| EPOCHS_YOLO=${EPOCHS_YOLO:-50} | |
| EPOCHS_BILSTM=${EPOCHS_BILSTM:-20} | |
| EPOCHS_VAE=${EPOCHS_VAE:-30} | |
| BATCH_SIZE=${BATCH_SIZE:-16} | |
| # Flags | |
| FORCE=false | |
| CLEAN=false | |
| SKIP_YOLO=false | |
| SKIP_PATCHCORE=false | |
| SKIP_BILSTM=false | |
| SKIP_VAE=false | |
| # Auto-detect CUDA GPU | |
| if python -c "import torch; exit(0 if torch.cuda.is_available() else 1)" 2>/dev/null; then | |
| DEFAULT_DEVICE="0" | |
| DEVICE_INFO=$(python -c "import torch; print(f'CUDA GPU 0 ({torch.cuda.get_device_name(0)})')") | |
| else | |
| DEFAULT_DEVICE="cpu" | |
| DEVICE_INFO="CPU (No CUDA device found)" | |
| fi | |
| TRAIN_DEVICE=${TRAIN_DEVICE:-"$DEFAULT_DEVICE"} | |
| # --- Color output ------------------------------------------------------------ | |
| RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m'; CYAN='\033[0;36m'; NC='\033[0m' | |
| info() { echo -e "${CYAN}[INFO]${NC} $*"; } | |
| ok() { echo -e "${GREEN}[OK]${NC} $*"; } | |
| warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } | |
| err() { echo -e "${RED}[ERROR]${NC} $*"; } | |
| header(){ echo -e "\n${BLUE}═══════════════════════════════════════════════════${NC}"; | |
| echo -e "${BLUE} $*${NC}"; | |
| echo -e "${BLUE}═══════════════════════════════════════════════════${NC}"; } | |
| # --- Argument parsing -------------------------------------------------------- | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| --epochs-yolo) EPOCHS_YOLO="$2"; shift 2;; | |
| --epochs-bilstm) EPOCHS_BILSTM="$2"; shift 2;; | |
| --epochs-vae) EPOCHS_VAE="$2"; shift 2;; | |
| --batch) BATCH_SIZE="$2"; shift 2;; | |
| --force) FORCE=true; shift;; | |
| --clean) CLEAN=true; shift;; | |
| --skip-yolo) SKIP_YOLO=true; shift;; | |
| --skip-patchcore) SKIP_PATCHCORE=true; shift;; | |
| --skip-bilstm) SKIP_BILSTM=true; shift;; | |
| --skip-vae) SKIP_VAE=true; shift;; | |
| *) err "Unknown option: $1"; exit 1;; | |
| esac | |
| done | |
| # --- Setup & Clean Logic ----------------------------------------------------- | |
| cd "$REPO_ROOT" | |
| mkdir -p "$LOG_DIR" "$CHECKPOINT_DIR/vision" "$CHECKPOINT_DIR/geometry" "$EXPORT_DIR" | |
| if [[ "$CLEAN" == true ]]; then | |
| warn "Cleaning all checkpoints, exports, and logs..." | |
| find "$CHECKPOINT_DIR" -name "*.done" -type f -delete | |
| find "$EXPORT_DIR" -name "*.done" -type f -delete | |
| ok "Clean complete. Re-run without --clean to start training." | |
| exit 0 | |
| fi | |
| START_TIME=$(date +%s) | |
| header "TrackChain Phase 2 — Master ML Training Pipeline" | |
| info "Repo root: $REPO_ROOT" | |
| info "Compute Device: $DEVICE_INFO" | |
| info "YOLO epochs: $EPOCHS_YOLO" | |
| info "Bi-LSTM epochs: $EPOCHS_BILSTM" | |
| info "VAE epochs: $EPOCHS_VAE" | |
| info "Batch size: $BATCH_SIZE" | |
| info "Force retrain: $FORCE" | |
| # --- Helper: checkpoint-aware run -------------------------------------------- | |
| run_step() { | |
| local step_name="$1" | |
| local checkpoint="$2" | |
| shift 2 | |
| local cmd=("$@") | |
| # SMART CHECKPOINTING: Skip if .done file exists and --force is not used | |
| if [[ "$FORCE" == false && -f "$checkpoint" ]]; then | |
| info "[$step_name] Already completed (checkpoint found). Skipping." | |
| return 0 | |
| fi | |
| info "[$step_name] Starting..." | |
| # Temporarily disable exit-on-error to capture the exact exit code of the piped command | |
| set +e | |
| "${cmd[@]}" 2>&1 | tee "$LOG_DIR/${step_name}.log" | |
| local status=${PIPESTATUS[0]} | |
| set -e | |
| if [[ $status -eq 0 ]]; then | |
| touch "$checkpoint" | |
| ok "[$step_name] Completed successfully" | |
| else | |
| err "[$step_name] FAILED (exit code $status). See log: $LOG_DIR/${step_name}.log" | |
| exit 1 | |
| fi | |
| } | |
| # ============================================================================= | |
| # STEP 1: Data Verification & Generation | |
| # ============================================================================= | |
| header "STEP 1/7: Data Verification & Generation" | |
| if ! python -c "import os | |
| has_yolo = os.path.exists('$DATA_ROOT/external/rail_defects_expanded/train/images') or os.path.exists('$DATA_ROOT/external/rail_defects/train/images') | |
| has_patch = os.path.exists('$DATA_ROOT/external/rail_normal_expanded/train/good') or os.path.exists('$DATA_ROOT/external/rail_normal_only/train/good') | |
| assert has_yolo, 'YOLO dataset missing' | |
| assert has_patch, 'PatchCore dataset missing' | |
| print('[OK] Vision datasets verified')" 2>/dev/null; then | |
| err "Vision datasets not found. Ensure '$DATA_ROOT/external/rail_defects' and '$DATA_ROOT/external/rail_normal_only' exist." | |
| exit 1 | |
| fi | |
| run_step "generate_trc" \ | |
| "$CHECKPOINT_DIR/.trc_data.done" \ | |
| python ml/scripts/generate_trc_telemetry.py \ | |
| --mode telemetry \ | |
| --output "$DATA_ROOT/processed/synthetic_trc_run_001.csv" | |
| run_step "generate_geometry" \ | |
| "$CHECKPOINT_DIR/.geometry_data.done" \ | |
| python ml/scripts/generate_trc_telemetry.py \ | |
| --mode geometry_sequences --num_samples 5000 \ | |
| --output "$DATA_ROOT/processed/geometry_sequences/" | |
| run_step "generate_normal" \ | |
| "$CHECKPOINT_DIR/.normal_data.done" \ | |
| python ml/scripts/generate_trc_telemetry.py \ | |
| --mode normal_sequences --num_samples 3000 \ | |
| --output "$DATA_ROOT/processed/normal_sequences/" | |
| # ============================================================================= | |
| # STEP 2: YOLO Training (Phase 2.1) | |
| # ============================================================================= | |
| header "STEP 2/7: YOLOv8n Visual Defect Detector" | |
| YOLO_DATA="$DATA_ROOT/external/rail_defects/data.yaml" | |
| if [[ -f "$DATA_ROOT/external/rail_defects_expanded/data.yaml" ]]; then | |
| YOLO_DATA="$DATA_ROOT/external/rail_defects_expanded/data.yaml" | |
| fi | |
| if [[ "$SKIP_YOLO" == true ]]; then | |
| warn "Skipping YOLO (--skip-yolo)" | |
| else | |
| run_step "train_yolo" \ | |
| "$CHECKPOINT_DIR/vision/.yolo_train.done" \ | |
| python ml/scripts/train_detector.py \ | |
| --data "$YOLO_DATA" \ | |
| --epochs "$EPOCHS_YOLO" \ | |
| --batch "$BATCH_SIZE" \ | |
| --device "$TRAIN_DEVICE" | |
| run_step "export_yolo_onnx" \ | |
| "$EXPORT_DIR/.yolo_onnx.done" \ | |
| python ml/inference/exporters.py \ | |
| --model "$CHECKPOINT_DIR/vision/yolov8n_rail_best.pt" \ | |
| --outdir "$EXPORT_DIR" \ | |
| --format onnx | |
| run_step "export_yolo_int8" \ | |
| "$EXPORT_DIR/.yolo_int8.done" \ | |
| python ml/inference/exporters.py \ | |
| --model "$CHECKPOINT_DIR/vision/yolov8n_rail_best.pt" \ | |
| --outdir "$EXPORT_DIR" \ | |
| --format int8 | |
| fi | |
| # ============================================================================= | |
| # STEP 3: PatchCore Memory Bank (Phase 2.2) | |
| # ============================================================================= | |
| header "STEP 3/7: PatchCore Visual Anomaly Detector" | |
| PATCHCORE_DATA="$DATA_ROOT/external/rail_normal_only" | |
| if [[ -d "$DATA_ROOT/external/rail_normal_expanded/train/good" ]]; then | |
| PATCHCORE_DATA="$DATA_ROOT/external/rail_normal_expanded" | |
| info "Using expanded PatchCore dataset (800+ images)" | |
| fi | |
| if [[ "$SKIP_PATCHCORE" == true ]]; then | |
| warn "Skipping PatchCore (--skip-patchcore)" | |
| else | |
| run_step "train_patchcore" \ | |
| "$CHECKPOINT_DIR/vision/.patchcore_train.done" \ | |
| python ml/scripts/train_anomaly.py \ | |
| --data-path "$PATCHCORE_DATA" \ | |
| --coreset_ratio 0.10 \ | |
| --fpr_target 0.01 \ | |
| --device "$TRAIN_DEVICE" | |
| fi | |
| # ============================================================================= | |
| # STEP 4: Physics Verification (Phase 2.3) — no training | |
| # ============================================================================= | |
| header "STEP 4/7: EN 13848 Physics Verification" | |
| if [[ "$FORCE" == false && -f "$CHECKPOINT_DIR/geometry/.physics_verify.done" ]]; then | |
| info "[physics_verify] Already completed. Skipping." | |
| else | |
| python -c " | |
| import pandas as pd | |
| from ml.models.geometry.physics_detector import EN13848PhysicsThresholdDetector | |
| det = EN13848PhysicsThresholdDetector() | |
| df = pd.read_csv('$DATA_ROOT/processed/synthetic_trc_run_001.csv') | |
| signals = det.predict(df) | |
| fired = signals[0].fired | |
| score = signals[0].value | |
| print(f'Physics fired: {fired}, score: {score:.3f}') | |
| assert fired and abs(score - 0.625) < 0.05, 'Physics math failed!' | |
| " | |
| touch "$CHECKPOINT_DIR/geometry/.physics_verify.done" | |
| ok "[physics_verify] EN 13848 math verified" | |
| fi | |
| # ============================================================================= | |
| # STEP 5: Bi-LSTM Training (Phase 2.4) - ENHANCED | |
| # ============================================================================= | |
| header "STEP 5/7: Bi-LSTM Geometry Fault Classifier (Enhanced)" | |
| if [[ "$SKIP_BILSTM" == true ]]; then | |
| warn "Skipping Bi-LSTM (--skip-bilstm)" | |
| else | |
| run_step "train_bilstm" \ | |
| "$CHECKPOINT_DIR/geometry/.bilstm_train.done" \ | |
| python ml/scripts/train_fault_classifier_enhanced.py \ | |
| --epochs "$EPOCHS_BILSTM" \ | |
| --hidden-size 128 \ | |
| --num-layers 3 \ | |
| --batch_size 128 \ | |
| --lr 0.0005 \ | |
| --label-smoothing 0.1 \ | |
| --dropout 0.4 \ | |
| --data-path "$DATA_ROOT/processed/geometry_sequences/" \ | |
| --save-path "$CHECKPOINT_DIR/geometry/bilstm_fault_typing_enhanced.pt" | |
| fi | |
| # ============================================================================= | |
| # STEP 6: Seq-VAE Training (Phase 2.5) - FIXED AND ENHANCED | |
| # ============================================================================= | |
| header "STEP 6/7: Sequence VAE Novel Geometry Detector (Enhanced)" | |
| if [[ "$SKIP_VAE" == true ]]; then | |
| warn "Skipping Seq-VAE (--skip-vae)" | |
| else | |
| run_step "train_vae" \ | |
| "$CHECKPOINT_DIR/geometry/.vae_train.done" \ | |
| python ml/scripts/train_sequence_vae_enhanced.py \ | |
| --epochs "$EPOCHS_VAE" \ | |
| --beta 0.01 \ | |
| --latent-dim 16 \ | |
| --batch-size 64 \ | |
| --lr 0.001 \ | |
| --kl-annealing \ | |
| --annealing-epochs 10 \ | |
| --data-path "$DATA_ROOT/processed/normal_sequences/" \ | |
| --save-path "$CHECKPOINT_DIR/geometry/sequence_vae_enhanced.pt" | |
| fi | |
| # ============================================================================= | |
| # STEP 7: Final Test Suite | |
| # ============================================================================= | |
| header "STEP 7/7: Full Test Suite Verification" | |
| run_step "full_test_suite" \ | |
| "$CHECKPOINT_DIR/.tests.done" \ | |
| bash ml/scripts/test.sh | |
| ELAPSED=$(( $(date +%s) - START_TIME )) | |
| echo "" | |
| header "TrackChain Phase 2 — Training Pipeline Complete in ${ELAPSED}s" | |
| ok "Checkpoints: $CHECKPOINT_DIR/" | |
| ok "Exports: $EXPORT_DIR/" | |
| ok "Logs: $LOG_DIR/" | |
| echo "" | |
| ok "Next step: Run ./ml/scripts/calibrate.sh to fit calibration parameters." |