Skip to content

Feature/1d model p2 - CNN & CNN_Transformer - #4

Merged
neilkdbn merged 8 commits into
mainfrom
feature/1d-model-p2
Aug 31, 2026
Merged

neilkdbn merged 8 commits into
mainfrom
feature/1d-model-p2

Conversation

@Aryasurya12

Copy link
Copy Markdown
Collaborator

No description provided.

…suite

- subsystem2_1d/__init__.py: expose public API for normalize_1d_iq,
  IQAugmentation, RFSignalDataset1D, and get_1d_dataloaders

- subsystem2_1d/normalization_1d.py:
  * normalize_1d_iq() - per-instance, per-channel zero-mean/unit-variance
    normalization for single (2,128) and batched (N,2,128) numpy arrays
  * IQAugmentation class - AWGN noise injection and random phase rotation
    for on-the-fly data augmentation during training; master enable/disable switch

- subsystem2_1d/dataloader_1d.py:
  * RFSignalDataset1D - PyTorch Dataset wrapping pre-sliced numpy arrays
    with shape guard (2,128) and optional transform hook
  * get_1d_dataloaders() - factory that reads Person 1s locked split indices
    (train_idx.npy / val_idx.npy / test_idx.npy) and returns three DataLoaders
    with shuffle=True for train only; Windows-safe num_workers handling

- subsystem2_1d/test_dataloader.py:
  * Group A (22 tests, no data files needed): normalization correctness,
    augmentation output shapes, L2-norm preservation, shape guards
  * Group B (4 tests, requires data/X_all.npy): full DataLoader init,
    batch shape assertions, split size checks, zero-index-overlap verification
  * All 22 runnable tests PASS; 4 skipped pending dataset_agent.py run

- .gitignore: add rules to exclude subsystem2_1d/checkpoints/* and
  subsystem2_1d/results/* while preserving .gitkeep directory stubs

Does NOT modify any files by Person 1 or Person 3.
- subsystem2_1d/classifiers_1d.py:
  * CNN1DClassifier: 4-block deep 1D CNN with progressive feature extraction
    - Block 1: Conv1d(2->64,  k=7, same) -> BN -> ReLU -> MaxPool2 => (B,64,64)
    - Block 2: Conv1d(64->128,k=5, same) -> BN -> ReLU -> MaxPool2 => (B,128,32)
    - Block 3: Conv1d(128->256,k=3,same) -> BN -> ReLU -> MaxPool2 => (B,256,16)
    - Block 4: Conv1d(256->256,k=3,same) -> BN -> ReLU -> MaxPool2 => (B,256,8)
    - FC head: Flatten -> Linear(2048->256) -> BN -> ReLU -> Dropout(0.5) -> Linear(256->11)
    - Total trainable params: 865,803
  * CNNTransformerHybrid: strided CNN frontend + sinusoidal PE + TransformerEncoder
    - CNN frontend (strided): Conv1d(2->64,k=7,s=2) -> Conv1d(64->128,k=5,s=2) => (B,128,32)
    - Transpose => (B,32,128); d_model=128, nhead=8, dim_per_head=16
    - PositionalEncoding: sinusoidal fixed embeddings, batch-first, dropout=0.1
    - TransformerEncoder: num_layers=2, nhead=8, dim_feedforward=256, batch_first=True
    - Global avg pool over sequence dim => (B,128); Linear(128->11)
    - Total trainable params: 308,619
  * PositionalEncoding: standalone nn.Module with register_buffer PE table
  * build_model() factory: instantiate models by string key with **kwargs passthrough
  * get_param_count() utility on both model classes
  * Shape contract enforced: input (B,2,128) -> output (B,11)

- subsystem2_1d/test_classifiers.py: 11-section, 41-assertion test suite
  * T-1/T-2: import paths (direct module + __init__.py public API)
  * T-3: instantiation smoke tests for both architectures
  * T-4: forward pass output shape [32, 11] verified for both models
  * T-5: variable batch sizes {1, 16, 64} all produce correct shapes
  * T-6: CNN1D intermediate shapes at every MaxPool block verified
  * T-7: Hybrid intermediate shapes (CNN frontend, transpose, PE, Transformer, GAP)
  * T-8: PositionalEncoding shape, non-trivial encoding, [-1,1] bounds
  * T-9: param counts (CNN1D 865,803 > Hybrid 308,619; both in expected ranges)
  * T-10: build_model factory and KeyError on unknown model name
  * T-11: gradient flow back to input (model is differentiable)
  * Result: 41/41 PASS

- subsystem2_1d/__init__.py: extended public API to include
  CNN1DClassifier, CNNTransformerHybrid, PositionalEncoding, build_model

Does NOT modify any files by Person 1 or Person 3.
train_1d.py -- Full training loop
  - AdamW optimizer (lr=1e-3, wd=1e-4) + CrossEntropyLoss
  - ReduceLROnPlateau scheduler (factor=0.5, patience=3)
  - EarlyStopping class: configurable patience + min_delta, reset(), step()
  - Gradient clipping (max_norm=1.0) for training stability
  - Best-checkpoint saving to subsystem2_1d/checkpoints/best_<model>.pt
  - TrainingConfig dataclass (model_name, epochs, lr, wd, patience, ckpt_dir)
  - train_model() importable function + argparse CLI (--model/--batch_size/--epochs/--lr)
  - Epoch log: Epoch | TrainLoss | TrainAcc | ValLoss | ValAcc | LR | Status

eval_1d.py -- Scientifically rigorous evaluation
  - Multi-SNR accuracy: all 20 levels (-20 to +18 dB, step 2 dB)
  - Per-SNR accuracy table printed + exported as JSON (accuracy_vs_snr_<model>.json)
    for Person 4 joint plotting on Day 7
  - Confusion matrices at -10, 0, +10 dB SNR:
      * Row-normalised PNG heatmap with cell count annotations
      * Raw numpy .npy array (shape 11x11)
      * Fixed safe-denominator normalisation (no RuntimeWarning on empty rows)
  - CPU inference latency profiling: 100 warm-up + 200 timed passes (ms/sample)
  - load_model_from_checkpoint() factory
  - print_edge_suitability_report() side-by-side comparison table
  - Headless-safe: matplotlib.use('Agg') before pyplot import
  - argparse CLI: --model --checkpoint --data_dir --batch_size

test_training_pipeline.py -- 85-assertion end-to-end pipeline test
  - T-1: EarlyStopping unit tests (13 assertions)
      improvement, counter increment, patience trigger, late improvement, reset()
  - T-2/T-3: Training smoke tests -- CNN1DClassifier + CNNTransformerHybrid (2 epochs)
      gradient flow (params differ from initial state), checkpoint saved/loadable,
      history dict structure, finite losses, accuracies in [0,1]
  - T-4/T-5: Evaluation dry-runs -- both architectures
      JSON with all 20 SNR keys, CM .npy files at -10/0/+10 dB (shape 11x11,
      integer dtype, correct sample count), CM .png files, latency > 0,
      overall accuracy in [0,1]
  - All I/O to tempfile.mkdtemp() -- nothing written to real checkpoints/results/
  - Result: 85/85 PASS, EXIT:0, zero warnings

subsystem2_1d/__init__.py: extended public API
  - Added: EarlyStopping, TrainingConfig, train_model
  - Added: evaluate_model, print_edge_suitability_report,
           load_model_from_checkpoint, measure_inference_latency

Does NOT modify any files by Person 1, Person 3, or Person 4.
@Aryasurya12
Aryasurya12 requested a review from neilkdbn August 30, 2026 08:07
@neilkdbn
neilkdbn merged commit 73a2ec3 into main Aug 31, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants