ktongue/DEM_MCM / markov_sweep.html
ktongue's picture
download
raw
10.3 kB
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Modélisation Markovienne - Sweep Multi-Configurations</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; max-width: 950px; margin: 0 auto; padding: 20px; line-height: 1.7; }
h1 { border-bottom: 3px solid #27ae60; padding-bottom: 10px; color: #2c3e50; }
h2 { color: #34495e; border-bottom: 1px solid #bdc3c7; padding-bottom: 5px; margin-top: 35px; }
h3 { color: #8e44ad; }
code { background: #ecf0f1; padding: 2px 6px; border-radius: 3px; font-family: 'Consolas', monospace; }
pre { background: #2c3e50; color: #ecf0f1; padding: 20px; border-radius: 8px; overflow-x: auto; }
pre code { background: none; padding: 0; color: inherit; }
.formula { background: linear-gradient(135deg, #27ae60 0%, #2ecc71 100%); color: white; padding: 18px; border-radius: 10px; margin: 20px 0; }
.note { background: #fff3cd; padding: 15px; border-radius: 8px; border-left: 5px solid #f39c12; margin: 20px 0; }
.success { background: #d4edda; padding: 15px; border-radius: 8px; border-left: 5px solid #28a745; margin: 20px 0; }
table { border-collapse: collapse; width: 100%; margin: 20px 0; box-shadow: 0 2px 15px rgba(0,0,0,0.1); }
th, td { border: 1px solid #ddd; padding: 12px 15px; text-align: left; }
th { background: #27ae60; color: white; }
tr:nth-child(even) { background: #f9f9f9; }
.param { background: #e8f6f3; padding: 3px 10px; border-radius: 4px; font-weight: bold; color: #27ae60; }
.folder { background: #2c3e50; color: #ecf0f1; padding: 10px 15px; border-radius: 5px; font-family: monospace; margin: 10px 0; }
.tree { background: #f8f9fa; padding: 15px; border-radius: 8px; border: 1px solid #ddd; }
.tree ul { list-style: none; padding-left: 20px; }
.tree li { margin: 5px 0; }
.tree .folder-icon::before { content: "📁 "; }
.tree .file-icon::before { content: "📄 "; }
hr { border: none; border-top: 2px solid #eee; margin: 30px 0; }
</style>
</head>
<body>
<h1>Modélisation Markovienne GPU - Sweep Multi-Configurations</h1>
<p>Cette version permet de tester automatiquement plusieurs configurations d'hyperparamètres et de sauvegarder les résultats de manière structurée.</p>
<hr>
<h2>1. Hyperparamètres Configurables</h2>
<table>
<tr><th>Paramètre</th><th>Description</th><th>Valeurs typiques</th></tr>
<tr><td class="param">nlt</td><td>Nombre de pas de temps pour l'apprentissage</td><td>10, 50, 100, 200, 500</td></tr>
<tr><td class="param">nx, ny, nz</td><td>Discrétisation spatiale (nombre de partitions par axe)</td><td>3x3x3, 5x5x5, 7x7x7, 10x10x10</td></tr>
<tr><td class="param">step_size</td><td>Pas de temps (1 = tous les fichiers, 2 = 1 sur 2)</td><td>1, 2, 5, 10</td></tr>
<tr><td class="param">start_index</td><td>Index de départ (après régime transitoire)</td><td>0, 1000, 2000, 3000</td></tr>
</table>
<hr>
<h2>2. Formule Utilisée</h2>
<div class="formula">
\[
P_{ij} = \frac{1}{N_{LT}} \sum_{n=1}^{N_{LT}} \frac{T_{ij}(n)}{\phi(i, t_{n-1})}
\]
</div>
<p>où:</p>
<ul>
<li>\(N_{LT}\) = <code>nlt</code></li>
<li>\(T_{ij}(n)\) = nombre de transitions \(i \to j\) au pas \(n\)</li>
<li>\(\phi(i, t_{n-1})\) = nombre de particules dans l'état \(i\) au temps \(t_{n-1}\)</li>
</ul>
<hr>
<h2>3. Structure des Résultats</h2>
<h3>3.1 Organisation des Dossiers</h3>
<div class="tree">
markov_sweep_results/
├── NLT_100_nx3_ny3_nz3_step1_start0/
│ ├── transition_matrix.npy
│ ├── params.json
│ └── stats.json
├── NLT_100_nx5_ny5_nz5_step1_start0/
│ ├── transition_matrix.npy
│ ├── params.json
│ └── stats.json
├── NLT_100_nx7_ny7_nz7_step1_start0/
│ └── ...
├── ...
└── summary.json
</div>
<p>Tous les résultats sont automatiquement sauvegardés dans le dossier <code>markov_sweep_results/</code>.</p>
<h3>3.2 Format des Fichiers</h3>
<h4>params.json</h4>
<pre><code>{
"nlt": 100,
"nx": 5,
"ny": 5,
"nz": 5,
"step_size": 1,
"start_index": 0
}</code></pre>
<h4>stats.json</h4>
<pre><code>{
"n_timesteps_used": 100,
"n_states": 125,
"row_sum_min": 0.9999,
"row_sum_max": 1.0001,
"diagonal_mean": 0.4567,
"diagonal_std": 0.1234
}</code></pre>
<h4>transition_matrix.npy</h4>
<p>Matrice numpy de forme <code>(n_states, n_states)</code> = <code>(125, 125)</code></p>
<hr>
<h2>4. Code</h2>
<h3>4.1 Configuration des Expériences</h3>
<pre><code># Grille d'hyperparamètres
CONFIGURATIONS = [
# Discrétisation variable
Params(nlt=100, nx=3, ny=3, nz=3, step_size=1, start_index=0),
Params(nlt=100, nx=5, ny=5, nz=5, step_size=1, start_index=0),
Params(nlt=100, nx=7, ny=7, nz=7, step_size=1, start_index=0),
Params(nlt=100, nx=10, ny=10, nz=10, step_size=1, start_index=0),
# N_LT variable
Params(nlt=10, nx=5, ny=5, nz=5, step_size=1, start_index=0),
Params(nlt=50, nx=5, ny=5, nz=5, step_size=1, start_index=0),
Params(nlt=200, nx=5, ny=5, nz=5, step_size=1, start_index=0),
Params(nlt=500, nx=5, ny=5, nz=5, step_size=1, start_index=0),
# Pas de temps variable
Params(nlt=100, nx=5, ny=5, nz=5, step_size=2, start_index=0),
Params(nlt=100, nx=5, ny=5, nz=5, step_size=5, start_index=0),
# Départ après régime transitoire
Params(nlt=100, nx=5, ny=5, nz=5, step_size=1, start_index=1000),
Params(nlt=100, nx=5, ny=5, nz=5, step_size=1, start_index=2000),
]</code></pre>
<h3>4.2 Classe Params</h3>
<pre><code>@dataclass
class Params:
"""Hyperparamètres pour une expérience."""
nlt: int = 100 # Nombre de pas de temps
nx: int = 5 # Discrétisation X
ny: int = 5 # Discrétisation Y
nz: int = 5 # Discrétisation Z
step_size: int = 1 # Pas de temps
start_index: int = 0 # Index de départ
def output_folder(self, base_dir="outputs"):
"""Génère le chemin du dossier de sortie."""
folder_name = f"NLT_{self.nlt}_nx{self.nx}_ny{self.ny}_nz{self.nz}_step{self.step_size}_start{self.start_index}"
return os.path.join(base_dir, folder_name)</code></pre>
<h3>4.3 Fonction Principale</h3>
<pre><code>def run_experiment(params, files, xmin, xmax, ...):
"""Exécute une expérience avec les paramètres dados."""
n_states = params.nx * params.ny * params.nz
# Sélection des fichiers selon step_size et start_index
all_indices = list(range(params.start_index, len(files) - 1, params.step_size))
selected_indices = all_indices[:params.nlt]
# Accumulateur GPU
P_accumulator = torch.zeros((n_states, n_states), dtype=torch.float64, device=device)
# Boucle principale
for idx in selected_indices:
# Lecture, calcul des états, P_n, accumulation
...
# Moyenne
P = P_accumulator / len(selected_indices)
return P, stats</code></pre>
<hr>
<h2>5. Impact des Paramètres</h2>
<h3>5.1 N_LT (Nombre de Timesteps)</h3>
<table>
<tr><th>N_LT</th><th>Effet</th></tr>
<tr><td>Petit (10-50)</td><td>Captures rapides, variance élevée, bruit</td></tr>
<tr><td>Moyen (100-200)</td><td>Bon équilibre entre biais et variance</td></tr>
<tr><td>Grand (500+)</td><td>Estimation robuste, lisse les fluctuations</td></tr>
</table>
<h3>5.2 Discrétisation (nx, ny, nz)</h3>
<table>
<tr><th>Grille</th><th>États</th><th>Comportement</th></tr>
<tr><td>3×3×3</td><td>27</td><td>Grossier, peu de données par état</td></tr>
<tr><td>5×5×5</td><td>125</td><td>Bon équilibre</td></tr>
<tr><td>7×7×7</td><td>343</td><td>Plus fin, plus de données nécessaires</td></tr>
<tr><td>10×10×10</td><td>1000</td><td>Très fin, peut nécessiter plus de N_LT</td></tr>
</table>
<h3>5.3 Step Size</h3>
<table>
<tr><th>Step</th><th>Transitions couvertes</th><th>Note</th></tr>
<tr><td>1</td><td>Toutes (fichiers adjacents)</td><td>Défaut, plus de données</td></tr>
<tr><td>2</td><td>1 sur 2</td><td>Transitions plus longues</td></tr>
<tr><td>5</td><td>1 sur 5</td><td>Transitions encore plus longues</td></tr>
</table>
<h3>5.4 Start Index</h3>
<div class="note">
<strong>start_index</strong> permet d'ignorer le régime transitoire initial.
Par exemple, start_index=1000 commence l'apprentissage après 1000 fichiers.
</div>
<hr>
<h2>6. Résumé des Formules</h2>
<table>
<tr><th>Concept</th><th>Formule</th><th>Code</th></tr>
<tr><td>Matrice finale</td><td>\(P_{ij} = \frac{1}{N_{LT}} \sum_n \frac{T_{ij}(n)}{\phi(i)}\)</td><td><code>P = P_accum / n_timesteps</code></td></tr>
<tr><td>Index d'état</td><td>\(state = i_x + i_y n_x + i_z n_x n_y\)</td><td><code>ix + iy*nx + iz*nx*ny</code></td></tr>
<tr><td>Comptage état</td><td>\(\phi[i] = \sum_p \mathbb{1}_{s_p=i}\)</td><td><code>torch.bincount(states)</code></td></tr>
<tr><td>Transitions</td><td>\(T_{ij} = \sum_p \mathbb{1}_{s_{t-1}=i} \cdot \mathbb{1}_{s_t=j}\)</td><td><code>scatter_add()</code></td></tr>
</table>
<hr>
<h2>7. Utilisation</h2>
<h3>7.1 Lancer le sweep</h3>
<pre><code>python transition_matrix_sweep.py</code></pre>
<h3>7.2 Modifier les configurations</h3>
<pre><code># Dans le fichier, modifier CONFIGURATIONS:
CONFIGURATIONS = [
Params(nlt=50, nx=5, ny=5, nz=5, step_size=1, start_index=0),
# Ajouter d'autres configurations...
]</code></pre>
<h3>7.3 Charger les résultats</h3>
<pre><code>import numpy as np
import json
# Charger une matrice
P = np.load("markov_sweep_results/NLT_100_nx5_ny5_nz5_step1_start0/transition_matrix.npy")
# Charger les statistiques
with open("markov_sweep_results/NLT_100_nx5_ny5_nz5_step1_start0/stats.json") as f:
stats = json.load(f)
# Charger le résumé
with open("markov_sweep_results/summary.json") as f:
summary = json.load(f)</code></pre>
<div class="success">
<strong>Output:</strong> Les résultats sont automatiquement organisés dans le dossier <code>markov_sweep_results/</code> avec des noms de dossiers explicites reflétant les hyperparamètres.
</div>
</body>
</html>

Xet Storage Details

Size:
10.3 kB
·
Xet hash:
9f1724b3275abd1aa7cd0d7a77bce59fb6282a52a40cc82a6e1c35d78a0462a9

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.