|
Download visuals/finetuning_walkthrough_transcript.md from Dhruv1000/TSRDA: direct link, hf CLI and curl.
- Browser
- Download file 10.8 kB
-
https://huggingface.co/Dhruv1000/TSRDA/resolve/main/visuals/finetuning_walkthrough_transcript.md
- Command line
-
hf download hf://Dhruv1000/TSRDA/visuals/finetuning_walkthrough_transcript.md
-
curl -L -o finetuning_walkthrough_transcript.md https://huggingface.co/Dhruv1000/TSRDA/resolve/main/visuals/finetuning_walkthrough_transcript.md
10.8 kB
| # Animation transcript | |
| All animated arrows are schematic. Scores are historical measurements, not simulated training curves. | |
| ## 1. Read the unlabeled satellite sequence | |
| **Stage:** Pretraining. 496 fold5 patches; crop labels are not loaded. | |
| - **PASTISPatchDataset:** load_target=False; normalize ten bands | |
| - **Sixteen fixed tiles:** 4×4 grid; each tile is32×32 | |
| - **Separate crop updates:** Batch4; 1,984 optimizer steps/epoch | |
| Pretraining learns a representation of spectral and temporal structure. It does not directly learn the eighteen crop labels. | |
| Code: `pretrain.py: main() → dataset.py: crop_ij()`. | |
| ## 2. Mask eligible observations | |
| **Stage:** Pretraining. Historical NDVI-style frame gate, calculated on normalized bands. | |
| - **Eligibility gate:** NDVI index6/2 >0.2; vegetation fraction >0.9 | |
| - **Random spatial mask:** Nominal40% masking in eligible frames | |
| - **Learned mask token:** Same pixel mask spans all ten spectral bands | |
| Frames failing the gate remain visible. Controlled pilots found roughly3% effective masking; nominal40% is not whole-dataset coverage. | |
| Code: `model.py: UTAEPrediction.forward()`. | |
| ## 3. Reconstruct the hidden spectral values | |
| **Stage:** Pretraining. The encoder sees corrupted inputs and predicts original ten-band values. | |
| - **Spatial encoder:** Full-resolution convolutions + ASPP + SE | |
| - **Temporal encoder:** Three reduced dual-attention blocks | |
| - **Reconstruction head:** Linear256→10 at every pixel and time | |
| Masked-value mean-squared error supplies the gradients. The auxiliary reconstruction head exists, but DEEP_SUP=False disables its extra loss. | |
| Code: `UTAE_ASPP.forward() → UTAEPrediction.forward()`. | |
| ## 4. Save the encoder checkpoint | |
| **Stage:** Pretraining. The supplied encoder artifact records epoch99. | |
| - **latest.tar:** Full wrapper + optimizer/scaler/RNG state | |
| - **latest.utae.tar:** Encoder weights only | |
| - **Transferable representation:** Original pretrained folder retained untouched | |
| We used the supplied pretrained artifact. This animation is not a claim that its original100-epoch pretraining was rerun in this session. | |
| Code: `pretrain.py: main() → torch.save()`. | |
| ## 5. Load your encoder; attach the supervised task | |
| **Stage:** Fine-tuning. Reconstruction heads are replaced by a segmentation wrapper. | |
| - **Strict encoder load:** Reuse spatial + temporal pretrained weights | |
| - **Fresh supervised layers:** STA, semantic, boundary, gated refinement | |
| - **Train the complete model:** Encoder and new layers both receive gradients | |
| At the original supervised start, the task layers are new. Later continuation stages load the entire selected fine-tuned model, including its heads. | |
| Code: `train_spatial_temporal.py: main() / --init_finetuned`. | |
| ## 6. Keep the labeled sampling protocol fixed | |
| **Stage:** Fine-tuning. Training fold1:76 entries /72 unique; validation fold2:76/71. | |
| - **Batch of2 patches:** X:2×T×10×128×128; preserve duplicate IDs | |
| - **Two fixed diagonal crops:** [0:32,0:32] and [32:64,32:64] | |
| - **76 updates per epoch:** 38 batches ×2 separate crop steps | |
| Training transforms operate inside these selected windows. Validation uses the same fixed windows without those random transformations. | |
| Code: `dataset.py: pad_collate(), crop_ij()`. | |
| ## 7. Apply the recorded training transforms | |
| **Stage:** Fine-tuning. Augmentations are method-specific; sample IDs and crop windows stay fixed. | |
| - **Spatial transform:** Paired flips /90-degree rotations of X and Y | |
| - **Temporal transform:** Observation subsampling and frame dropout | |
| - **Spectral transform:** Per-band gain/bias jitter plus noise | |
| Subsampling keeps the retained observation positions. Label geometry follows the spatial transformation; validation and test are not augmented. | |
| Code: `aug_dihedral(), aug_temporal_subsample(), aug_frame_dropout(), aug_spectral()`. | |
| ## 8. Extract spatial features for every acquisition | |
| **Stage:** Fine-tuning. The spatial encoder preserves H×W instead of downsampling the crop. | |
| - **Stem10→64:** 3×3 convolution; second convolution dilation2 | |
| - **ASPP64→256:** Dilations1/2/4 plus global pooling | |
| - **Channel attention:** SE weighting; reshape to per-pixel sequences | |
| Each pixel now has a256-dimensional feature vector at every acquisition. Spatial context and temporal modeling have separate roles. | |
| Code: `AtrousSpatialEncoder.forward() / ASPP.forward()`. | |
| ## 9. Model crop evolution with temporal dual attention | |
| **Stage:** Fine-tuning. Index positions are encoded; actual acquisition-day gaps are not used. | |
| - **Reduced KV tokens:** 256→64; group4 observations→256 | |
| - **Two attention operations:** Reduced self-attention; full-T queries to reduced KV | |
| - **Three residual blocks:** Eight heads; GELU + parallel depthwiseConv1D MLP | |
| The winning backbone preserves its original padding behavior. Explicit padding-mask variants existed, but they are not the deployed encoder. | |
| Code: `TemporalSRDABlock.forward() / TemporalSRDAEncoder.forward()`. | |
| ## 10. Collapse time and predict class / boundary outputs | |
| **Stage:** Fine-tuning. STA pools time; three spatial convolutions refine the pooled map. | |
| - **Learned temporal pooling:** softmax scores over T → weighted feature sum | |
| - **Semantic + boundary heads:** 20 class logits and1 boundary logit | |
| - **Gated refinement:** Features ×(1+sigmoid(boundary)); residual class correction | |
| Boundary predictions directly affect the refined class logits inside the network. They are not an external mask-cleaning stage. | |
| Code: `STA.forward() → UTAEClassificationDual.forward()`. | |
| ## 11. Compute the supervised objective | |
| **Stage:** Fine-tuning. Two segmentation losses and auxiliary boundary supervision. | |
| - **Semantic objective:** CE +0.75 Lovász | |
| - **Refined objective:** CE +0.75 Lovász | |
| - **Boundary objective:** 0.5 BCE; local max/min label-gradient target | |
| CE/Lovász ignore GT0/19; label smoothing0.05. Boundary BCE is applied to the constructed boundary map without that foreground mask. | |
| Code: `training_loss(), compute_boundary_target(), LovaszSoftmaxLoss.forward()`. | |
| ## 12. Backpropagate; update encoder and task layers | |
| **Stage:** Fine-tuning. AdamW parameter groups give the encoder a lower learning rate. | |
| - **Gradient computation:** FP16 forward + GradScaler backward | |
| - **Stabilize the update:** Unscale gradients; clip norm5 | |
| - **Parameter update:** Encoder LR0.5×head LR; update EMA copy | |
| Raw and EMA weights are evaluated, but the final SAM component uses the selected raw checkpoint. EMA maintenance is not proof of an EMA gain. | |
| Code: `build_param_groups(), lr_factor(), ModelEMA.update()`. | |
| ## 13. Continue from the low-learning-rate checkpoint | |
| **Stage:** SAM refinement. Same architecture and losses; change the optimization step. | |
| - **Selected low-LR model:** Load encoder AND supervised heads | |
| - **Low learning rates:** Head1e-5; encoder5e-6 | |
| - **SAM budget:** 20 epochs; radius0.02; batch2; fixed32 | |
| The SAM run starts from a previously fine-tuned checkpoint, not directly from a bare pretrained encoder. Its optimizer and schedule start fresh. | |
| Code: `main(): --init_finetuned ... --research sam`. | |
| ## 14. First SAM pass: find a weight perturbation | |
| **Stage:** SAM refinement. Calculate the gradient at current weights θ. | |
| - **Loss atθ:** Forward → loss → backward | |
| - **Normalize gradient:** g /(||g|| + epsilon) | |
| - **Temporary perturbation:** θtemporary = θ +0.02 ×normalized gradient | |
| This is Sharpness-Aware Minimization. No Segment Anything encoder, prompt, mask generator, or extra architecture is introduced. | |
| Code: `train_spatial_temporal.py: main(), research==sam branch`. | |
| ## 15. Second SAM pass: restore and update | |
| **Stage:** SAM refinement. Compute a new gradient at the temporarily perturbed weights. | |
| - **Second loss/backward:** Same crop; BatchNorm held in eval mode | |
| - **Restore originalθ:** Subtract stored perturbations | |
| - **AdamW update:** Apply second-pass gradient; update scaler/EMA | |
| Select raw epoch11 using validation. Once saved, the network needs only its ordinary forward pass at inference. | |
| Code: `research==sam: offsets → second_loss → restore → scaler.step()`. | |
| ## 16. Freeze the SAM encoder and collect earlier features | |
| **Stage:** Feature clusters. Reuse its first temporal block, rather than training another encoder. | |
| - **Forward hook:** DepthCollector captures block1 output | |
| - **Valid-time statistics:** Mean256 +standard deviation256 =vector512 | |
| - **Training normalization:** Fit mean/std on training features; then L2 normalize | |
| The readout shares the network forward pass. Hooks summarize real features; the diagram does not visualize measured feature activations. | |
| Code: `DepthCollector.begin(), hook(), end(); train_normalizer()`. | |
| ## 17. Fit three feature-cluster centres per crop class | |
| **Stage:** Feature clusters. Use labeled training pixels only; no validation/test labels fit centres. | |
| - **Balanced memory:** 32 pixels per supporting training patch/class | |
| - **KMeans fitting:** 18 classes ×3 centres; seed3407; n_init3 | |
| - **Similarity classifier:** Similarity/0.1 → logsumexp over3 → softmax18 | |
| Repeated patch/crop occurrences are deduplicated for the memory bank only. The supervised dataset list itself retains duplicate entries. | |
| Code: `make_prototypes() / probability()`. | |
| ## 18. Train the original independent temporal specialist | |
| **Stage:** Temporal CNNs. A small model of each pixel’s spectral evolution, trained from scratch. | |
| - **Input projection:** T×10 → T×64; valid-time mask | |
| - **Four Conv1D blocks:** Kernel3; depthwise; dilation1/2/4/8 | |
| - **Mean +max classifier:** Vector128 →64 →18 crop classes | |
| 100 epochs; AdamW1e-3, WD0.01, CE smoothing0.05, warmup3/cosine. Combine25% CNN probabilities with75% SAM/cluster blend. | |
| Code: `TemporalCNN.forward(); historical original CNN training`. | |
| ## 19. Add the new plain-CNN control | |
| **Stage:** Temporal CNNs. A separate training run with the same architecture and seed value. | |
| - **Matched control:** Same data, fixed32 crops,100-epoch budget | |
| - **Distinct training trajectory:** New trainer resets RNG after model construction | |
| - **Validation-selected blend:** 75% reference +25% new CNN probabilities | |
| The CNN is weaker alone but changes useful class rankings. A matched attention alternative replaces mean pooling and adds65 parameters. | |
| Code: `train_temporal_cnn.py: train(); AttentionCNN.forward()`. | |
| ## 20. Run the complete system on full128 test patches | |
| **Stage:** Final evaluation. 482 fold4 patches; no TTA or external mask post-processing. | |
| - **Four probability sources:** SAM /shared-feature clusters /old CNN /new CNN | |
| - **Recommended weights:** 28.125% /28.125% /18.75% /25% | |
| - **Final argmax +metrics:** Full20×20 matrix; score GT classes1–18 | |
| Recommended: validation52.5640%, test49.4555%. Attention alternative: validation51.8368%, highest observed test49.5298%; reported separately. | |
| Code: `evaluate.py: load_models(), main(); metrics_cm()`. |