DeepJSCC vs. Capacity-Matched JPEG over AWGN#
Train an image encoder and decoder jointly over an additive white Gaussian noise (AWGN) channel, then compare the learned system with a capacity-matched JPEG reference at a fixed bandwidth ratio.
Use this page for a compact implementation and training check. For a research-facing comparison with no-CSI slow fading and a bandwidth sweep, use DeepJSCC over slow Rayleigh fading.
Warning
Experimental tutorial evidence. The completed result on this page uses one trained model, four Kodak crops, and three channel-noise seeds. It is not a paper-grade population claim or a publication-ready result. Authoritative Kodak redistribution terms have not been archived, so this site does not publish the source crop or reconstruction gallery.
What this demo measures#
The two paths are:
Capacity-matched JPEG: image → highest JPEG quality fitting the capacity budget
→ ideal error-free delivery → JPEG decode
DeepJSCC: image → 0.5 learned complex symbols/pixel → AWGN
→ learned reconstruction
The bandwidth ratio is
κ = 0.5 complex channel uses per source pixel. For an SNR coordinate in decibels,
γ = 10^(SNR_dB/10) and the ideal complex-AWGN budget is
capacity bpp = κ × log2(1 + γ).
At each SNR, the JPEG reference searches qualities 1–95 and chooses the highest native bitstream
that fits this budget. If quality 1 does not fit, it records an outage and returns the benchmark’s
declared gray reconstruction. This is an optimistic channel-coding assumption for one fixed JPEG
implementation, not an upper bound over digital separation or all source codecs. The comparison is
modeled on the protocol in the
DeepJSCC paper.
PSNR, measured in decibels, and MS-SSIM, reported on an approximately 0–1 scale here, both increase
with reconstruction quality. Training minimizes image mean squared error (MSE); the benchmark
reports all three measures. This experiment varies SNR at one fixed κ, so it is not a
rate-distortion sweep.
Before you start#
You need:
a Git clone of Noema, a supported Python version (
3.11–3.13), anduv;network access for dependencies and the 24 hash-verified Kodak PNGs;
port
8766available if you choose the Workbench route;enough time for an 80-epoch starter-model training run and a 32-run benchmark.
The starter selects CUDA when available and otherwise uses CPU. Seeds and file hashes reproduce the protocol, but training is not guaranteed to be bit-identical across hardware and library builds. Your result ID and exact metrics may therefore differ from the reference result below.
Fetch the dataset once before choosing a workflow:
cd "$(git rev-parse --show-toplevel)"
uv sync --extra onnx --extra wireless
uv run --extra onnx noema data fetch kodak \
--directory .noema/datasets/kodak
Caution
The fetcher records the mirror URL and file hashes, but the repository currently records the Kodak usage statement as an unverified third-party statement. Confirm the applicable terms before using the data, and do not redistribute the images or their reconstructions from this tutorial.
How the Noema pieces fit#
recipe
→ exported training bundle and interface contract
→ hash-verified data contract and train/validation split
→ paired encoder/decoder artifact
→ frozen benchmark pack
→ result bundle with metrics and provenance
The recipe defines the communication problem and replaceable interfaces. The exported bundle contains the trainer-neutral contract plus a PyTorch starter. Training returns the encoder and decoder together, and the benchmark evaluates that frozen pair without changing the declared resource budget.
Choose one workflow#
The CLI quick start and the guided Workbench route are alternatives. Do not run both into the same bundle directory. The exporter rejects a non-empty output directory unless overwrite is explicitly enabled, so choose a fresh bundle path for each attempt.
Option A — CLI training summary#
Run this block from any directory inside the Git clone after fetching Kodak. It exports the bundle, attaches the starter, validates the contract, trains and evaluates the pair, and runs the benchmark.
(
set -euo pipefail
ROOT="$(git rev-parse --show-toplevel)"
BUNDLE="$ROOT/.noema/training_exports/deepjscc_image"
cd "$ROOT"
uv run --project "$ROOT" --extra onnx --extra wireless noema differentiable export \
"$ROOT/recipes/deepjscc_kodak_awgn_train.yaml" \
--training-plan \
"$ROOT/demo_trainings/deepjscc_image_reconstruction/training_plan.yaml" \
--out "$BUNDLE"
uv run --project "$ROOT" --extra onnx --extra wireless python \
"$ROOT/demo_trainings/prepare_example.py" deepjscc-image "$BUNDLE" \
--project-root "$ROOT"
cd "$BUNDLE"
uv run --project "$ROOT" --extra onnx --extra wireless python validate_contract.py
uv run --project "$ROOT" --extra onnx --extra wireless python train_demo.py
uv run --project "$ROOT" --extra onnx --extra wireless python evaluate_demo.py
cd "$BUNDLE/reference_training"
uv run --project "$ROOT" --extra onnx --extra wireless python build_benchmark.py
cd "$ROOT"
uv run --project "$ROOT" --extra onnx --extra wireless noema benchmark validate \
"$BUNDLE/reference_training/benchmark_pack.yaml"
uv run --project "$ROOT" --extra onnx --extra wireless noema benchmark run \
"$BUNDLE/reference_training/benchmark_pack.yaml"
)
This example reads a file-backed dataset directly, so it does not need a tensor-capture stage.
The final command prints the result ID and paths to result.json, metrics.csv, recipes.csv, and
summary.md.
Option B — guided Workbench workflow#
1. Open the template#
Start Noema in Terminal 1 and leave the process running:
cd "$(git rev-parse --show-toplevel)"
uv run --extra onnx --extra wireless noema ui serve --port 8766
Open http://127.0.0.1:8766, select Browse template recipes, then open Semantic communication > Image reconstruction > Image reconstruction — DeepJSCC over AWGN.
The recipe declares:
Kodak images
01–20for the deterministic train/validation partition;Kodak images
21–24for the benchmark only;a training SNR grid of
[-4, 0, 4, 8, 12, 16]dB;unit average transmitted complex-symbol power;
paired trainable Sender and Receiver interfaces.
2. Export from Workbench#
Configure Workbench:
Under Operation Training Capabilities, select Train/replace for Sender and Receiver.
Set Bundle directory to
.noema/training_exports/deepjscc_image_workbench.Select PyTorch under Support framework.
Leave Overwrite generated files disabled for a new bundle. Enable it only when you intentionally want to regenerate Noema-owned contract files in an existing bundle.
Select Export training bundle.
In Terminal 2, attach the included starter:
cd "$(git rev-parse --show-toplevel)"
uv run --extra onnx --extra wireless python demo_trainings/prepare_example.py \
deepjscc-image .noema/training_exports/deepjscc_image_workbench
Inspect data_contract.yaml to confirm the selected files, hashes, split, and crop policy.
3. Train and return the endpoint pair#
cd "$(git rev-parse --show-toplevel)/.noema/training_exports/deepjscc_image_workbench"
uv run --project ../../.. --extra onnx --extra wireless python validate_contract.py
uv run --project ../../.. --extra onnx --extra wireless python train_demo.py
uv run --project ../../.. --extra onnx --extra wireless python evaluate_demo.py
The residual convolutional model downsamples each spatial dimension by eight and emits 32 complex
feature maps, giving 32 / (8 × 8) = 0.5 complex channel uses per source pixel. Crops, flips, and
rotations augment the 16 training images while the recorded source files and hashes remain fixed.
The paired artifact contains:
artifacts/encoder.onnxandartifacts/decoder.onnx;trained_artifact.yaml, which binds the pair to its interfaces;reference_training/training_history.json;reference_training/evaluation_metrics.json.
Workbench discovers the pair automatically. Select Validate returned model and continue only after the interface validation succeeds.
4. Build and run the benchmark#
cd "$(git rev-parse --show-toplevel)"
cd .noema/training_exports/deepjscc_image_workbench/reference_training
uv run --project ../../../.. --extra onnx --extra wireless python build_benchmark.py
cd ../../../..
uv run --extra onnx --extra wireless noema benchmark validate \
.noema/training_exports/deepjscc_image_workbench/reference_training/benchmark_pack.yaml
uv run --extra onnx --extra wireless noema benchmark run \
.noema/training_exports/deepjscc_image_workbench/reference_training/benchmark_pack.yaml
Progress and recovery#
Stage |
Successful checkpoint |
Safe recovery |
|---|---|---|
Dataset fetch |
24 Kodak files pass the recorded hashes |
Rerun the fetch command |
Export |
|
Choose a fresh bundle, or deliberately enable overwrite |
Contract validation |
|
Fix the reported file, hash, or interface error before training |
Training/evaluation |
Both ONNX files and |
Rerun from the bundle; training does not resume an interrupted epoch sequence |
Benchmark |
The CLI prints |
Rebuild the pack only if its inputs changed; otherwise rerun the benchmark |
Method and benchmark protocol#
The benchmark grid is [-6, -4, -2, 0, 4, 8, 12, 16] dB. The model trains on
[-4, 0, 4, 8, 12, 16] dB, so −2 dB is an unseen interpolation point and −6 dB tests
extrapolation below the training range.
The same channel-noise seeds—71001, 72001, and 73001—are reused at every SNR. This
common-random-number design pairs the SNR comparisons; the seeds are not fresh independent draws at
each coordinate. The capacity-matched JPEG reference is deterministic and runs once per SNR.
Both methods receive a maximum budget of 0.5 complex channel uses per source pixel. DeepJSCC emits
that number directly. The JPEG model reserves the same full block even when its native bitstream
uses less of the ideal capacity or the run is in outage.
The current JPEG recipe fixes the encoder configuration, including 4:2:0 subsampling, non-progressive
output, and qualities 1–95. The
current recipe template may evolve; the
snapshot manifest records hashes for the exact per-run recipes used by the completed result.
Checks before interpretation#
Before interpreting a new result, verify that:
every learned run uses the same paired-artifact identity;
images
21–24do not appear in the training contract;both methods are admitted under the
0.5-use resource limit;every selected JPEG bitstream is at or below its ideal capacity budget;
quality
0in the operating-point table is interpreted as the declared outage sentinel.
Completed reference result#
Warning
This stored result is descriptive tutorial evidence. Its 95% intervals cover three channel-noise seeds for one frozen model and the same four crops. They do not cover training initialization, model-selection, or image-population uncertainty.
Reference result identity
20260727T235925Z_semantic_comm.digital_vs_deepjscc_post_training_v3 contains 32 runs: one
deterministic capacity-matched JPEG run and three learned noise realizations at each of eight SNR
coordinates.
PSNR chart unavailable. The accessible quality table below contains the plotted means; the downloadable chart data contains interval bounds.
MS-SSIM chart unavailable. The accessible quality table below contains the plotted means; the downloadable chart data contains interval bounds.
SNR (dB) |
JPEG PSNR (dB) |
DeepJSCC PSNR (dB) |
JPEG MS-SSIM |
DeepJSCC MS-SSIM |
|---|---|---|---|---|
-6 |
13.72 |
21.99 |
0.270 |
0.745 |
-4 |
17.64 |
23.14 |
0.509 |
0.805 |
-2 |
25.34 |
24.01 |
0.871 |
0.849 |
0 |
27.94 |
24.65 |
0.928 |
0.880 |
4 |
31.35 |
25.44 |
0.972 |
0.916 |
8 |
33.86 |
25.81 |
0.985 |
0.931 |
12 |
35.87 |
25.96 |
0.990 |
0.938 |
16 |
37.50 |
26.02 |
0.993 |
0.940 |
SNR (dB) |
JPEG quality mean |
JPEG quality range |
JPEG native bpp |
Ideal capacity bpp |
|---|---|---|---|---|
-6 |
0.00 |
0–0 |
0.000 |
0.162 |
-4 |
1.25 |
0–3 |
0.118 |
0.242 |
-2 |
7.75 |
6–10 |
0.344 |
0.353 |
0 |
16.00 |
12–24 |
0.494 |
0.500 |
4 |
44.00 |
33–65 |
0.900 |
0.906 |
8 |
72.50 |
65–84 |
1.421 |
1.435 |
12 |
84.75 |
81–91 |
2.006 |
2.037 |
16 |
90.50 |
88–94 |
2.601 |
2.675 |
Method |
Budgeted channel uses/source pixel |
Maximum per-image channel uses/source pixel |
Budget limit |
Admitted |
|---|---|---|---|---|
Capacity-matched JPEG |
0.5 |
0.5 |
0.5 |
yes |
Learned DeepJSCC |
0.5 |
0.5 |
0.5 |
yes |
In this completed run, DeepJSCC reaches 21.99 dB PSNR at −6 dB versus 13.72 dB for the JPEG
reference, and 23.14 versus 17.64 dB at −4 dB. The ordering reverses at −2 dB, where JPEG reaches
25.34 dB and DeepJSCC 24.01 dB. At 16 dB, JPEG reaches 37.50 dB and DeepJSCC 26.02 dB.
MS-SSIM follows the same ordering. These observations illustrate low-SNR graceful degradation for
this artifact, dataset slice, and fixed bandwidth ratio; they do not establish universal learned
superiority or rate-distortion optimality.
The reader-facing tables are rounded for comparison. Download the full-precision summary, per-run benchmark projection, chart data, and snapshot manifest for the stored values, run IDs, recipe hashes, resource checks, and statistical design. The manifest identifies the local raw result files by hash; the raw result bundle is not distributed by this documentation snapshot.
Why there is no reconstruction gallery#
The local benchmark records representative reconstructions, including explicit gray outage images. They are intentionally excluded from the published documentation until authoritative Kodak terms covering redistribution and web display are archived. This keeps the experimental metrics reproducible without treating uncertain dataset rights as a cosmetic warning.
Verify your local result#
Set the variable to the ID printed by your benchmark:
cd "$(git rev-parse --show-toplevel)"
RESULT_ID="<paste-the-result-id>"
uv run --extra onnx --extra wireless noema benchmark verify "$RESULT_ID"
Read every verification warning before using the result outside a local experiment. Do not suppress warnings to make an experimental result appear publication-ready.
Publication status#
This benchmark remains experimental, the stored result is not paper-grade evidence, and the Kodak
rights record is unresolved. A future publication path should require:
authoritative dataset terms and an archived dataset citation;
a canonical benchmark with
traceability_profile_requested: trueand the exact current profile binding;substantially more held-out images and channel seeds;
independently trained models when making population-level claims;
a persistently archived result bundle, environment identity, and verification report;
publication without
--allow-warnings.
References and implementation notes#
Bourtsoulatze, Kurka, and Gündüz, “Deep Joint Source-Channel Coding for Wireless Image Transmission”.
This tutorial preserves the paper’s fixed-bandwidth AWGN comparison idea but uses Noema’s CPU-sized residual model, Kodak split, training grid, and metric implementations. It is not a reproduction of the paper’s reported numbers.
JPEG thresholds depend on the Pillow/libjpeg build and the recipe’s exact encoder settings. MS-SSIM uses Noema’s configured
pytorch-msssimimplementation. The local result bundle and lock file provide the implementation context for a reproduced run.