=== versions === python 3.12.0 | torch 2.14.1+cpu | lightgbm 4.7.0 | numpy 2.5.4 | pandas 3.0.6 | odc-stac 0.5.3 | matplotlib 3.11.2 | 8 CPU threads, no GPU === Step 1: per-date Sentinel-2 reflectance at the samples === 9,000 samples x 50 dates x 10 bands; 39.5% of observations clear clear dates per sample: median 20, 10th percentile 14, min 2, max 35; 4 samples have fewer than 5 longest gap between clear views: median 58 days, 90th percentile 80 days share of sample observations clear, by month: Jan 25%, Feb 39%, Mar 47%, Apr 51%, May 34%, Jun 69%, Jul 18%, Aug 23%, Sep 48%, Oct 22%, Nov 33%, Dec 39% median clear dates per sample by class: bog 18, heath 20, bracken 21, seminat_grass 22, improved_grass 23, broadleaf 21, conifer 17, water 17, built_bare 20 === Step 2: models === tempcnn mask 867,337 parameters tempcnn gapfill 654,025 parameters ltae mask 44,297 parameters ltae gapfill 44,297 parameters === Step 3: training (3 runs each: seed 42+r, early stopping on spatial fold r) === TempCNN, raw dates + mask run 0 (val fold 0): val macro F1 0.862, best at 21 epochs, 43 s TempCNN, raw dates + mask run 1 (val fold 1): val macro F1 0.873, best at 31 epochs, 50 s TempCNN, raw dates + mask run 2 (val fold 2): val macro F1 0.897, best at 40 epochs, 63 s TempCNN, gap-filled run 0 (val fold 0): val macro F1 0.854, best at 39 epochs, 47 s TempCNN, gap-filled run 1 (val fold 1): val macro F1 0.863, best at 39 epochs, 44 s TempCNN, gap-filled run 2 (val fold 2): val macro F1 0.886, best at 12 epochs, 25 s L-TAE, raw dates + mask run 0 (val fold 0): val macro F1 0.843, best at 41 epochs, 23 s L-TAE, raw dates + mask run 1 (val fold 1): val macro F1 0.875, best at 50 epochs, 26 s L-TAE, raw dates + mask run 2 (val fold 2): val macro F1 0.908, best at 14 epochs, 13 s L-TAE, gap-filled run 0 (val fold 0): val macro F1 0.839, best at 13 epochs, 12 s L-TAE, gap-filled run 1 (val fold 1): val macro F1 0.882, best at 68 epochs, 30 s L-TAE, gap-filled run 2 (val fold 2): val macro F1 0.896, best at 31 epochs, 18 s LightGBM, raw dates (NaN) run 0 (val fold 0): val macro F1 0.834, best at 120 trees, 12 s LightGBM, raw dates (NaN) run 1 (val fold 1): val macro F1 0.850, best at 144 trees, 14 s LightGBM, raw dates (NaN) run 2 (val fold 2): val macro F1 0.887, best at 137 trees, 14 s LightGBM, gap-filled run 0 (val fold 0): val macro F1 0.825, best at 132 trees, 9 s LightGBM, gap-filled run 1 (val fold 1): val macro F1 0.839, best at 125 trees, 9 s LightGBM, gap-filled run 2 (val fold 2): val macro F1 0.857, best at 141 trees, 10 s total training time: 7.7 min === Step 4: accuracy on the 27 test blocks === three runs per model: mean and s.d. of single runs, and the 3-run ensemble (averaged probabilities) val_macro_f1 test_oa_mean test_oa_sd test_f1_mean test_f1_sd ensemble_oa ensemble_macro_f1 ensemble_kappa model TempCNN, raw dates + mask 0.877 0.848 0.011 0.855 0.008 0.851 0.858 0.830 TempCNN, gap-filled 0.868 0.835 0.008 0.844 0.009 0.842 0.850 0.820 L-TAE, raw dates + mask 0.875 0.850 0.008 0.859 0.007 0.865 0.873 0.846 L-TAE, gap-filled 0.872 0.820 0.016 0.830 0.017 0.821 0.832 0.797 LightGBM, raw dates (NaN) 0.857 0.835 0.009 0.844 0.008 0.842 0.851 0.820 LightGBM, gap-filled 0.840 0.816 0.008 0.826 0.007 0.815 0.826 0.790 Part 1 spectral rules on the same test samples: OA 0.600, macro F1 0.630, kappa 0.547 chosen on validation folds: TempCNN, raw dates + mask (deep), LightGBM, raw dates (NaN) (LightGBM) TempCNN, raw dates + mask (3-run ensemble), n = 2,456 test samples in 27 blocks confusion matrix (rows = Living England reference, columns = prediction): bog heath brack semin impro broad conif water built ref bog 217 29 1 10 0 0 0 0 0 ref heath 46 266 5 8 1 0 0 0 0 ref bracken 2 7 259 6 2 6 1 0 2 ref seminat_grass 2 1 2 251 113 0 0 0 1 ref improved_grass 0 0 0 47 233 0 0 0 2 ref broadleaf 0 1 9 0 4 284 13 0 5 ref conifer 0 2 1 0 0 17 100 0 0 ref water 1 3 1 0 0 0 1 128 4 ref built_bare 0 0 0 2 4 3 1 0 352 n_test producers_acc users_acc f1 f1_lightgbm Blanket bog 257 0.844 0.810 0.827 0.832 Heath 326 0.816 0.861 0.838 0.835 Bracken 285 0.909 0.932 0.920 0.901 Semi-natural grassland 370 0.678 0.775 0.723 0.682 Improved grassland 282 0.826 0.653 0.729 0.726 Broadleaf woodland 316 0.899 0.916 0.907 0.911 Conifer woodland 120 0.833 0.862 0.847 0.859 Water 138 0.928 1.000 0.962 0.958 Built-up and bare 362 0.972 0.962 0.967 0.951 overall accuracy 0.851 (block-bootstrap 95% CI 0.811 to 0.884); macro F1 0.858; kappa 0.830 LightGBM, raw dates (NaN): OA 0.842 (95% CI 0.784 to 0.886), macro F1 0.851 OA difference, deep minus LightGBM: +0.009 (paired block-bootstrap 95% CI -0.007 to +0.029) averaging the deep and LightGBM probabilities: OA 0.855, macro F1 0.863 === Step 5: which dates matter === L-TAE attention relative to an equal share (1.0), averaged over test pixels where the date is clear top 6 dates: 04 Apr 1.61, 22 Mar 1.35, 24 May 1.33, 03 Sep 1.28, 07 Mar 1.26, 25 Nov 1.21 bottom 3 dates: 22 Aug 0.50, 03 Oct 0.47, 16 May 0.47 Blanket bog most attended date 24 May (1.92) Heath most attended date 04 Apr (1.51) Bracken most attended date 03 Sep (2.28) Semi-natural grassland most attended date 04 Apr (2.00) Improved grassland most attended date 04 Apr (2.27) Broadleaf woodland most attended date 03 Sep (1.54) Conifer woodland most attended date 11 Apr (1.59) Water most attended date 22 Mar (1.76) Built-up and bare most attended date 25 Nov (1.61) drop in test OA when all views in one month are hidden (percentage points): Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec L-TAE, raw dates + mask -0.4 0.6 -0.4 0.4 1.1 4.2 -0.1 0.2 0.9 -0.3 0.2 0.4 TempCNN, gap-filled -1.3 -0.3 0.3 0.7 1.8 2.2 -0.0 0.2 0.9 0.4 0.4 0.9 LightGBM, raw dates (NaN) -0.1 -0.0 -0.3 10.2 8.1 13.7 0.0 0.2 4.3 0.2 1.1 1.4 === Step 5b: robustness to fewer clear views (test samples) === test OA when a random share of the clear views is kept: keep 100% keep 75% keep 50% keep 25% TempCNN, raw dates + mask 0.851 0.842 0.824 0.674 TempCNN, gap-filled 0.842 0.836 0.801 0.710 L-TAE, raw dates + mask 0.865 0.850 0.826 0.750 L-TAE, gap-filled 0.821 0.816 0.792 0.702 LightGBM, raw dates (NaN) 0.842 0.728 0.535 0.311 LightGBM, gap-filled 0.815 0.785 0.732 0.627 === Step 6: wall-to-wall prediction === C:\Users\Sean.Blaney\source\tgis-h4\.venv-habitat\Lib\site-packages\rasterio\warp.py:390: NotGeoreferencedWarning: Dataset has no geotransform, gcps, or rpcs. The identity matrix will be returned. dest = _reproject( stack 10/50 dates (37 s) stack 20/50 dates (122 s) stack 30/50 dates (156 s) stack 40/50 dates (212 s) stack 50/50 dates (248 s) downloaded the 50-date x 10-band stack in 250 s stack: (50, 10, 2250, 2500) int16 on disk = 5.6 GB (memory-mapped, read in strips) predicted 5,625,000 pixels with TempCNN, raw dates + mask (3-run ensemble) in 427 s; 0.000% never clear wall-to-wall agreement with Living England: test blocks 0.699, whole study area 0.717 (Part 1 rules: 0.483 and 0.490) model_km2 living_england_km2 Blanket bog 94.9 90.5 Heath 115.8 151.5 Bracken 46.6 41.6 Semi-natural grassland 109.9 96.1 Improved grassland 88.5 90.0 Broadleaf woodland 45.2 39.7 Conifer woodland 16.4 17.2 Water 8.0 8.4 Built-up and bare 37.2 25.7 median top-class probability 0.87; 7.6% of pixels below 0.5 saved 6 figures, metrics.json and the GeoTIFF to output/ total runtime 19.2 min (training 7.7 min, stack and wall-to-wall 11.3 min)