This repository implements an automatic modulation classification (AMC) pipeline for raw I/Q radio samples using PyTorch. It includes synthetic-data smoke tests, local RadioML-style dataset loading, 1D CNN and ResNet1D classifiers, training/evaluation CLIs, reproducible configuration files, unit tests, and selected final experiment artifacts.
The main reported run uses RadioML 2016.10A + ResNet1D + AdamW + regularization + learning-rate scheduling + early stopping.
automatic-modulation-classification-dl/
├── README.md
├── README.zh-CN.md
├── requirements.txt
├── pytest.ini
├── configs/
│ └── default_config.json
├── data/
│ └── .gitkeep
├── checkpoints/
│ └── .gitkeep
├── notebooks/
│ └── exploratory_analysis.ipynb
├── scripts/
│ ├── audit_radioml_data.py
│ ├── compare_synthetic_vs_radioml.py
│ ├── evaluate_model.py
│ ├── generate_synthetic_dataset.py
│ ├── inspect_radioml.py
│ ├── predict_example.py
│ └── train_cnn.py
├── src/
│ ├── config.py
│ ├── dataset.py
│ ├── evaluate.py
│ ├── impairments.py
│ ├── models.py
│ ├── modulation.py
│ ├── plots.py
│ ├── radioml_loader.py
│ ├── train.py
│ └── utils.py
├── tests/
│ ├── test_dataset.py
│ ├── test_model_shapes.py
│ ├── test_modulation.py
│ ├── test_radioml_loader.py
│ └── test_scientific_pipeline.py
└── results/
└── final/
Large dataset files and trained checkpoints are intentionally not tracked. Place local RadioML files under data/ and trained .pt files under checkpoints/.
Automatic modulation classification estimates the modulation format of a received signal from I/Q samples. It is useful in spectrum monitoring, cognitive radio, wireless signal analysis, and receiver-side signal understanding.
Classical AMC pipelines often rely on expert features such as higher-order cumulants, constellation statistics, cyclostationary features, or likelihood-based decision rules followed by an SVM, KNN, or decision-tree classifier. This project instead learns directly from fixed-length I/Q sequences and keeps the preprocessing path minimal.
The model input is a complex baseband signal represented as two channels:
input shape: [batch, 2, signal_length]
channels: I and Q
default signal_length: 128
classes: BPSK, QPSK, 8PSK, 16QAM, 64QAM
Two data modes are supported:
synthetic: locally generated I/Q samples with configurable channel impairments.radioml: local RadioML-style pickle or HDF5 datasets. The project does not download datasets automatically.
The final run uses a residual 1D CNN over raw I/Q sequences. The training configuration includes:
model: resnet1d
optimizer: AdamW
learning rate: 0.001
weight decay: 0.0005
dropout: 0.45
label smoothing: 0.05
gradient clipping: 1.0
scheduler: ReduceLROnPlateau
early stopping: validation accuracy
The final RadioML run used 100,000 selected examples split into 70,000 training, 15,000 validation, and 15,000 test examples.
best validation accuracy: 0.6657
overall test accuracy: 0.6636
QAM true accuracy: 0.6422
-20 dB test accuracy: 0.2133
18 dB test accuracy: 0.9613
Per-class test accuracy:
BPSK: 0.7220
QPSK: 0.6797
8PSK: 0.6320
16QAM: 0.6143
64QAM: 0.6700
Selected final artifacts are stored in results/final/.
Python 3.10 or newer is recommended.
pip install -r requirements.txtDownload RadioML data according to its own license and place it under data/.
Common local paths:
data/RML2016.10a_dict.pkl
data/RML2016.10b.pkl
data/RML2016.10a_dict_optimized.pkl
Inspect a local dataset:
python scripts/inspect_radioml.py --data-path data/RML2016.10a_dict_optimized.pklAudit candidate files under data/:
python scripts/audit_radioml_data.pypython scripts/train_cnn.py \
--dataset-mode radioml \
--data-path data/RML2016.10a_dict_optimized.pkl \
--classes BPSK QPSK 8PSK 16QAM 64QAM \
--epochs 80 \
--batch-size 128 \
--model resnet1d \
--run-name radioml_resnet1d_regularized \
--optimizer adamw \
--learning-rate 0.001 \
--weight-decay 0.0005 \
--dropout 0.45 \
--label-smoothing 0.05 \
--max-grad-norm 1.0 \
--scheduler reduce_on_plateau \
--scheduler-patience 3 \
--scheduler-factor 0.5 \
--min-lr 0.00001 \
--early-stopping \
--early-stopping-patience 10 \
--early-stopping-min-delta 0.0005python scripts/evaluate_model.py \
--dataset-mode radioml \
--data-path data/RML2016.10a_dict_optimized.pkl \
--checkpoint checkpoints/radioml_resnet1d_regularized_best_model.pt \
--classes BPSK QPSK 8PSK 16QAM 64QAM \
--run-name radioml_resnet1d_regularizedpython scripts/train_cnn.py --dataset-mode synthetic --epochs 2 --samples-per-class-per-snr 20 --batch-size 64
python scripts/evaluate_model.py --dataset-mode synthetic --samples-per-class-per-snr 20python -m pytest tests/The tests cover synthetic dataset generation, RadioML mock loading, class-name normalization, I/Q shape handling, stratified splits, model output shapes, HDF5 loading, and SNR sanity checks.
The repository does not include RadioML data or trained checkpoint files. Current metrics depend on selected classes, SNR range, random seed, model architecture, and training parameters. Low-SNR classification remains the main bottleneck, and 16QAM/64QAM confusion is still a useful target for future improvements.



