Jacquin Antoine 745a64b342 Pipeline complet Radiacode 103 - identification automatique d'isotopes
- VegaModel CNN-FCNN 34.5M params, 82 isotopes, val acc 99.89%
- Generation 50k spectres synthetiques 1D (12-24h durees)
- Entrainement 100 epochs sur RTX 5060 Ti (CUDA 12.8, Blackwell)
- Detection continue avec soustraction du background
- Capture background 24h avec gestion deconnexion
- Docker Compose : conteneur train (GPU) + detect (CPU/USB)
- Modele entraite inclus (vega_best.pt, 395 Mo)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-19 12:29:56 +02:00

Radiacode 103 — Identification automatique d'isotopes

Pipeline Docker complet pour la capture, l'analyse et l'identification automatique d'isotopes radioactifs avec un spectrometre gamma Radiacode 103.

Architecture

Radiacode 103 (USB)
        │
        ▼
┌─────────────────────────────────────────────────────────┐
│  Conteneur detect (Python 3.11 + PyTorch CPU)          │
│                                                         │
│  capture_background.py  ──>  background_24h.npy (24h)   │
│  radiacode_monitor.py   ──>  rapport JSON quotidien      │
│         │                                               │
│         ├── Echantillonnage chaque 60s                  │
│         ├── Soustraction du background                  │
│         ├── Inference VegaModel (34.5M params, 82 iso)  │
│         └── Rapport quotidien a 00h00                   │
│                                                         │
│  Modele: vega_best.pt (entraite sur RTX 5060 Ti)       │
└─────────────────────────────────────────────────────────┘

Demarrage rapide

# 1. Builder les images
docker compose build

# 2. Lancer l'entrainement (GPU, ~45 min)
docker compose run --rm train

# 3. Capturer le bruit de fond (24h, sans source radioactive)
docker compose run --rm -d --name radiacode-bg detect python capture_background.py

# 4. Lancer la detection continue
docker compose up detect

Configuration

Variables d'environnement (dans docker-compose.yml) :

Variable Defaut Description
MODEL_PATH /models/vega_best.pt Chemin du modele PyTorch
ISOTOPE_INDEX_PATH /models/vega_isotope_index.txt Index des 82 isotopes
BACKGROUND_PATH /data/background_24h.npy Fichier background de reference
THRESHOLD 0.5 Seuil de probabilite pour la detection
SAMPLE_INTERVAL 60 Intervalle d'echantillonnage (secondes)
REPORT_HOUR 0 Heure du rapport quotidien
MIN_LIVE_TIME 3600 Live time minimum pour un rapport (secondes)
VEGA_DEVICE cpu Device PyTorch (cpu ou cuda)

Bruit Poissonnien et modele

Physique du bruit

La detection gamma est un processus de comptage intrinsequement stochastique. Chaque canal du spectre suit une loi de Poisson : si un canal accumule en moyenne N comptages, l'ecart-type est sqrt(N). Le rapport signal/bruit s'ameliore donc en sqrt(N) :

  • 6.5 CPS de background sur 1024 canaux -> ~0.006 CPS/canal
  • Apres 1h : ~22 comptages/canal, ecart-type ~4.7, SNR ~5
  • Apres 24h : ~560 comptages/canal, ecart-type ~24, SNR ~23
  • Apres 1 semaine : ~3900 comptages/canal, ecart-type ~62, SNR ~63

C'est pourquoi la capture de background dure 24h : en dessous, les pics du background (K-40 a 1460 keV, Bi-214 a 609 keV, Pb-214 a 352 keV) sont noyes dans le bruit Poissonnien.

Modele VegaModel

Le VegaModel est un CNN-FCNN multi-tache inspire de l'architecture Vega d'Open-RadiaCode-Android :

  • Entree : spectre 1D de 1023 canaux (20-3000 keV), normalise par max
  • Sortie : deux tetes
    • Classification : 82 neurones avec sigmoid (presence/absence de chaque isotope)
    • Regression : 82 neurones (activite estimee en Bq, normalisee a max_activity_bq=1000)
  • Architecture :
    • 3 blocs CNN (64, 128, 256 canaux) avec BatchNorm + ReLU + MaxPool
    • 2 couches FC (512, 256) avec Dropout(0.3)
    • 34 493 156 parametres au total
  • Fonction de perte : VegaLoss = classification_weight * BCE + regression_weight * MSE (ponderee pour ne penaliser l'activite que sur les isotopes presents)
  • Entrainement : 50 000 spectres synthetiques, 100 epochs, AMP (mixed precision), early stopping (patience=10)
  • Background dans les donnees synthetiques : K-40, radon (Pb-214, Bi-214), thorium (Ac-228, Pb-212, Tl-208) simules avec des activites aleatoires realistes

Spectres synthetiques

Les donnees d'entrainement simulent la physique complete :

  1. Pics photoelectriques : Gaussiennes avec FWHM dependant de l'energie (8.4% a 662 keV pour le CsI(Tl))
  2. Continuum Compton : distribution de Klein-Nishina simplifiee sous chaque pic
  3. Bruit Poissonnien : echantillonnage Poisson(N) pour chaque canal, simulant les fluctuations de comptage reelles
  4. Background environnemental : continuum exponentiel + pics de K-40, radon, thorium avec activites aleatoires
  5. Efficacite du detecteur : modele phenomenologique qui decroit avec l'energie (absorption basse energie + penetration haute energie)
  6. Durees de 12-24h : suffisamment longues pour que le rapport signal/bruit soit comparable aux mesures reelles

Soustraction du background a l'inference

Le modele est entraine avec du background synthetique inclus, mais a l'inference on soustrait le vrai background mesure :

rate = cumulated_counts / cumulated_live_time       # spectre brut en CPS
bg_rate = bg_counts / bg_live_time                  # background de reference en CPS
net_rate = np.clip(rate - bg_rate, 0, None)         # spectre net (background soustrait)
normalized = net_rate / net_rate.max()               # normalisation pour le modele

Cette approche hybride est optimale :

  • Le modele apprend a ignorer les pics du background (K-40, radon, thorium) pendant l'entrainement
  • La soustraction reelle elimine les variations locales du background (emplacement, altitude, materiaux)
  • Resultat : meilleure sensibilite et moins de faux positifs

Le conteneur train execute deux phases :

  1. Generation des spectres synthetiques : 50 000 spectres 1D (20k mono-isotope, 15k bi-isotope, 10k multi-isotope, 5k background seul) avec des durees de 12-24h
  2. Entrainement VegaModel : CNN-FCNN multi-tache, 82 isotopes, 34.5M parametres

Resultats de l'entrainement sur RTX 5060 Ti :

  • Val accuracy : 99.89%
  • AUC macro : 0.995
  • Best val loss : 0.0051
  • Duree : ~45 min (100 epochs, 25s/epoch)

Detection

Le moniteur radiacode_monitor.py :

  • Echantillonne le spectre toutes les 60 secondes
  • Cumule les comptages et le live time
  • Soustrait le background de reference (si disponible)
  • Execute l'inference VegaModel sur le spectre net
  • Genere un rapport JSON quotidien a REPORT_HOUR

Le rapport contient :

  • Live time et comptages totaux
  • CPS moyen
  • Isotopes detectes avec probabilite et activite estimee (Bq)

Capture du bruit de fond

Avant la detection, capturer le background pendant 24h sans source radioactive a proximite :

docker compose run --rm -d --name radiacode-bg \
  -e TARGET_DURATION=86400 -e SAMPLE_INTERVAL=60 \
  detect python capture_background.py

Suivre la progression :

docker logs -f radiacode-bg
cat data/background_snapshot.json

Structure du projet

radiacode_103/
├── docker-compose.yml          # Orchestration des conteneurs
├── TOTO.md                     # Suivi des taches
├── README.md
├── train/
│   ├── Dockerfile              # PyTorch 2.7.0 + CUDA 12.8 (Blackwell)
│   ├── requirements.txt
│   ├── entrypoint.sh           # Generation + entrainement
│   └── vega_ml/                # Code VegaModel (copie d'Open-RadiaCode-Android)
│       ├── synthetic_spectra/  # Generateur de spectres synthetiques
│       ├── training/vega/      # Modele, dataset, trainer
│       └── inference/
├── detect/
│   ├── Dockerfile              # Python 3.11-slim + radiacode + torch CPU
│   ├── requirements.txt
│   ├── radiacode_monitor.py   # Moniteur principal
│   └── capture_background.py  # Capture du bruit de fond 24h
├── data/
│   ├── synthetic/spectra/     # 50 000 spectres synthetiques (~4.2 Go)
│   └── background_snapshot.json
├── models/
│   ├── vega_best.pt           # Meilleur modele (395 Mo)
│   ├── vega_final.pt          # Modele final
│   ├── vega_history.json      # Metriques d'entrainement
│   └── vega_isotope_index.txt # 82 isotopes
└── logs/                       # Rapports quotidiens JSON

Materiel

Composant Modele
Spectrometre Radiacode 103 (CsI(Tl), 1024 canaux, FWHM 8.4% @662 keV)
GPU entrainement NVIDIA RTX 5060 Ti 16 Go (Blackwell, sm_120)
GPU secondaire NVIDIA RTX 4060 Ti 16 Go (Ada Lovelace)
Production (futur) Raspberry Pi 4 8 Go

82 isotopes detectables

Ac-227, Ac-228, Ag-110m, Am-241, Au-198, Ba-133, Ba-137m, Be-7, Bi-210, Bi-211, Bi-212, Bi-214, C-14, Cd-109, Ce-139, Ce-144, Co-57, Co-58, Co-60, Cr-51, Cs-134, Cs-137, Eu-152, Eu-154, F-18, Fe-59, Ga-67, Hf-181, Hg-203, I-123, I-129, I-131, In-111, Ir-192, K-40, Lu-177, Mn-54, Na-22, Pa-231, Pa-234m, Pb-210, Pb-211, Pb-212, Pb-214, Po-210, Po-212, Po-214, Po-216, Po-218, Pr-144, Ra-223, Ra-224, Ra-226, Ra-228, Rh-106, Rn-220, Rn-222, Ru-106, Sb-125, Sc-46, Se-75, Sm-153, Sn-113, Sr-85, Sr-90, Ta-182, Tc-99m, Th-228, Th-230, Th-231, Th-232, Th-234, Tl-201, Tl-207, Tl-208, U-234, U-235, U-238, Xe-133, Y-88, Y-90, Zn-65

Passage en production (Raspberry Pi 4)

  1. Copier models/vega_best.pt et models/vega_isotope_index.txt sur le Pi 4
  2. Capturer le background sur le Pi 4 (emplacement final)
  3. Le meme detect/Dockerfile fonctionne sur ARM64
  4. Adapter docker-compose.yml : retirer deploy.resources.reservations.devices
  5. VEGA_DEVICE=cpu (inference CPU sur Pi 4, ~1s par spectre)
Description
No description provided
Readme 440 MiB
Languages
Python 89.5%
JavaScript 7.4%
CSS 1%
HTML 1%
PowerShell 0.5%
Other 0.6%