Skip to content

Commit 1c6abcd

Browse files
committed
CHG: minor corrections, updates to the story
1 parent e7bbfd2 commit 1c6abcd

1 file changed

Lines changed: 19 additions & 10 deletions

File tree

tutorial9.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ def _(mo):
2121
2222
Today, the German federal health authority RKI announced that the recently observed sharp increase in ICU case numbers following acute respiratory infections is caused by a new lineage of the influenza virus. It was first sequenced at the University Hospital of Cologne and has consequently been named *Influenza B/Colognia/314/2026*. Following its detection, laboratories across Germany rushed to test stored samples from recent patients, giving us a reasonably complete picture of ICU admissions and deaths to date.
2323
24-
The oldest sample identified came from an 80-year-old man from Cologne who died on 2026-02-29. His family reported that he first felt ill shortly after excessively celebrating Carnival on Rose Monday, which fell on 2026-02-16 this year.
24+
The oldest sample identified came from an 50-year-old man from Cologne who died on 2026-03-02. His family reported that he first felt ill shortly after excessively celebrating Carnival on Rose Monday, which fell on 2026-02-16 this year.
2525
2626
The RKI has today published all available data and called on modellers worldwide to estimate disease parameters and forecast the further course of the outbreak.
27+
28+
At the same time, political discussions started on whether and which non-pharmaceutical interventions should be implemented. First forecasts suggested that they are absolutely necessary to reduce the expected number of cases to not overwhelm the healthcare system. However, data shows that the German population has already started to reduce contacts and more people wear masks, which has not been taken into account by the first predictions. Some people argue that it is thus unnecessary to implement further measures, while others argue that measures are not necessary in their states, but in other states. To validate this claim, we need to identify the effects and starting days of such preventative contact reductions for each german region.
2729
""")
2830
return
2931

@@ -37,7 +39,7 @@ def _(mo):
3739
3840
This is the third in a series of three notebooks introducing Approximate Bayesian Computation with MEmilio. In the first two notebooks we calibrated simple single-region compartmental models. Here we extend the approach to a **metapopulation model** that resolves spatial heterogeneity across Germany.
3941
40-
We use [BayesFlow](https://bayesflow.org/main/index.html), a Python library for simulation-based inference with deep learning, as our inference method. This notebook is not a general tutorial on Neural Parameter Estimation with BayesFlow — for that we refer to the BayesFlow documentation and the primary literature. Our focus is on showing how MEmilio and BayesFlow work together.
42+
We use [BayesFlow](https://bayesflow.org/main/index.html), a Python library for simulation-based inference with deep learning, as our inference method. This notebook is not a general tutorial on Neural Parameter Estimation with BayesFlow — for that we refer to the [BayesFlow documentation](https://bayesflow.org/main/user_guide/introduction.html) and the primary literature. Our focus is on showing how MEmilio and BayesFlow work together.
4143
""")
4244
return
4345

@@ -303,7 +305,7 @@ def _(mo):
303305
mo.md(r"""
304306
### The simulator
305307
306-
The function below is the **core forward model** that BayesFlow will call repeatedly during training. Given a set of intervention parameters it assembles the full metapopulation model, runs the ODE solver, and returns the simulated observables.
308+
The function below is the **core forward model** that BayesFlow will call repeatedly during training. Given a set of intervention parameters it assembles the full metapopulation model, runs the ODE solver, and returns the simulated observables. Other than in the last notebooks, here we round the output data before giving it to our inference process. This is helpful here as it already reduces a main difference between the simulated data and the real data, improving the inference process.
307309
308310
The outputs are the **Critical (ICU)** and **Dead** compartment counts for each of the six age groups, extracted at daily resolution for all five regions. This gives, per region, an array of shape `(31, 12)` — 31 time points (days 0–30) and 12 compartment-age combinations (6 age groups × 2 outcomes).
309311
""")
@@ -399,16 +401,13 @@ def _(mo):
399401

400402

401403
@app.cell
402-
def _(mio):
404+
def _():
403405
import os
404406
# Must be set before importing BayesFlow/Keras
405407
os.environ["KERAS_BACKEND"] = "tensorflow"
406408

407409
import bayesflow as bf
408410

409-
# Suppress verbose MEmilio logs
410-
mio.set_log_level(mio.LogLevel.Error)
411-
412411
print("All imports successful!")
413412
print(f"BayesFlow version: {bf.__version__}")
414413
return bf, os
@@ -514,7 +513,7 @@ def _(mo):
514513
515514
The **inference network** (`CouplingFlow`) is a normalising flow that learns the mapping from the summary embedding to samples from the approximate posterior $q(\theta \mid s(y))$. It consists of alternating affine coupling layers and can represent complex, multi-modal distributions.
516515
517-
For more details we refer to the BayesFlow documentation.
516+
For more details we refer to the [BayesFlow documentation](https://bayesflow.org/main/user_guide/index.html).
518517
""")
519518
return
520519

@@ -578,8 +577,8 @@ def _(mo):
578577

579578

580579
@app.cell
581-
def _(mo, workflow):
582-
mo.md("Running training... (this may take a few minutes)")
580+
def _(workflow):
581+
print("Running training... (this may take a few minutes)")
583582

584583
history = workflow.fit_online(
585584
epochs=15,
@@ -903,5 +902,15 @@ def _(mo, np, posterior_samples):
903902
return
904903

905904

905+
@app.cell(hide_code=True)
906+
def _(mo):
907+
mo.md(r"""
908+
Overall, the fitting seems to work and the aggregated plots look reasonable. However, the plots per region show some difficulties of the inference process for the regions without ICU cases and deaths. This is likely caused by the different scales of case numbers in the different regions and age groups. The 90% CIs especially for the damping start values are very high, indicating much uncertainty in the inferred parameters. Our results indicate that there is not enough data currently to perform inference on all regions and thus, that our research question here is not answerable.
909+
910+
Let's hope that somebody else volunteers to communicate this in a talk show...
911+
""")
912+
return
913+
914+
906915
if __name__ == "__main__":
907916
app.run()

0 commit comments

Comments
 (0)