sEMG Adaptive Intent Detection & Restoration Pipeline
Three chained PyTorch models (plus one exploratory variant) implementing the sEMG processing pipeline described in:
Ortiz Ceballos, J.; Abundez Barrera, I.M.; RendΓ³n-Lara, E. Gestural Intent Detection and Adaptive Restoration of Degraded sEMG Signals Using Temporal Convolutional Networks and an Autoencoder. Symmetry 2026, 18, 1540. https://doi.org/10.3390/sym18091540
Each 200 ms / 400-sample sEMG window (2000 Hz, single channel, MyoWare-compatible) is routed through: intent detection β quality assessment β (optional) restoration.
Pipeline overview
raw sEMG window (1, 400)
β
βΌ
Intent Classifier βββΊ p_intent < 0.40? βββΊ DISCARD
β (β₯ 0.40)
βΌ
Quality Assessor βββΊ quality β₯ 0.50? βββΊ DIRECT PASS
β (< 0.50)
βΌ
Convolutional Autoencoder βββΊ RESTORED WINDOW
Operating thresholds (Ο_intent = 0.40, Ο_quality = 0.50) were selected via grid search on the validation split only, and evaluated once on a held-out test split.
Models in this repository
| File | Role | Used for |
|---|---|---|
intent_binary_best.pt |
Motor-intent classifier (dilated TCN) | Main pipeline β all reported results |
quality_judge_best.pt |
Dual-output signal-quality assessor | Main pipeline β all reported results |
restorer_best.pt |
Convolutional autoencoder (restoration) | Main pipeline β Table 3, Figures 4β7, latency (Sec. 4.9), and the "Restored (original autoencoder)" row of Table 4 |
restorer_taskaware_best.pt |
Convolutional autoencoder, retrained with a task-aware loss term | Exploratory, post hoc only β the "Restored (task-aware retraining)" row of Table 4, added in response to a downstream-evaluation request during peer review. Not part of the main reported pipeline. |
β οΈ If you want to reproduce the pipeline exactly as described in Section 4.7
and Figure 1 of the paper, use only the first three files. The task-aware
variant is a separate experiment reported transparently as a limitation, not
a replacement for restorer_best.pt β see the "Downstream Motor-Intent
Classification" section and Table 4 of the paper for full context (restoration,
including the task-aware variant, did not outperform using the degraded
signal directly for downstream intent classification).
Architectures
1. Intent Classifier β intent_binary_best.pt
- Input:
(1, 400)normalized window - Conv1D (16 filters, kernel 7) β 3Γ TCN blocks with dilations 1, 2, 4 (residual connections; channel progression 16β16β32β32)
- Global average pooling β 2 dense layers with dropout β sigmoid
- Output: scalar intent probability β [0, 1]
- Loss: binary cross-entropy with positive-class weighting
- Optimizer: Adam, lr = 1e-3, L2 = 1e-4
- Early stopping: 5 epochs without improvement in 0.6Β·F1 + 0.4Β·AUROC
2. Signal-Quality Assessor β quality_judge_best.pt
- Input:
(1, 400)normalized window - 3Γ (Conv + BatchNorm + ReLU + MaxPool) β global average pooling β dense(32)
- Two output branches: continuous quality score β [0, 1] (sigmoid) and a binary acceptability label (auxiliary task, not used at inference)
- Loss: 0.7 Β· MSE (score) + 0.3 Β· BCE (label)
3. Convolutional Autoencoder (restoration) β restorer_best.pt
- Encoder: 3Γ strided Conv (stride 2), 400 β 200 β 100 β 50
- Bottleneck: Conv(64, kernel 3)
- Decoder: 3Γ transposed Conv (expansion factor 2), 50 β 100 β 200 β 400
- Loss: 0.7 Β· MAE + 0.3 Β· MSE
- Trained only on windows with intent = 1
4. Convolutional Autoencoder, task-aware β restorer_taskaware_best.pt
- Identical architecture to
restorer_best.pt - Additional frozen intent-classifier term during training: total loss = reconstruction loss + 2.0 Γ task_loss, where task_loss penalizes divergence between the frozen intent classifier's prediction on the restored signal vs. on the clean signal
Training data
- NinaPro DB1, DB3, DB10 (public dataset, http://ninapro.hevs.ch/)
- 410 source recordings reduced to a single channel (per-sample median, emulating a MyoWare sensor), normalized with median/MAD
- Participant-level split (no window-level leakage): 278 recordings / 59 participants (train), 67 recordings / 13 participants (validation), 65 recordings / 13 participants (test)
- Synthetic corruption (Gaussian noise, sinusoidal drift, saturation, transient spikes) used to train the quality assessor and the restorer
Reported metrics (held-out test split)
Downstream motor-intent classification (frozen intent classifier evaluated on 4 signal versions, n = 198,348 windows, 120,418 positive):
| Signal version | Sensitivity | Precision | F1 | AUROC |
|---|---|---|---|---|
| Degraded (no restoration) | 0.7896 | 0.8817 | 0.8331 | 0.8860 |
Restored (restorer_best.pt) |
0.6723 | 0.8639 | 0.7561 | 0.8215 |
Restored (restorer_taskaware_best.pt) |
0.6884 | 0.8666 | 0.7673 | 0.8316 |
| Clean reference | 0.7041 | 0.8692 | 0.7780 | 0.8354 |
Inference latency (host CPU, per 400-sample window): 3.71 ms (p50), 5.29 ms (p90), 10.79 ms (p95), 15.18 ms (p99) β all well under the 200 ms window period.
Usage
import torch
# Define the same architectures used in training (see paper Sec. 4.7 / Fig. 3)
# from your_module import IntentTCN, QualityNet, ConvAE1D
device = "cuda" if torch.cuda.is_available() else "cpu"
intent_model = IntentTCN().to(device)
intent_model.load_state_dict(torch.load("intent_binary_best.pt", map_location=device))
intent_model.eval()
quality_model = QualityNet().to(device)
quality_model.load_state_dict(torch.load("quality_judge_best.pt", map_location=device))
quality_model.eval()
restorer_model = ConvAE1D().to(device)
restorer_model.load_state_dict(torch.load("restorer_best.pt", map_location=device))
restorer_model.eval()
# x: torch.Tensor of shape (batch, 1, 400), median/MAD-normalized sEMG window
p_intent = torch.sigmoid(intent_model(x))
quality_score = quality_model(x)["quality_score"] # adjust to your actual output signature
x_restored = restorer_model(x)
Note: the class definitions (
IntentTCN,QualityNet,ConvAE1D) are not included as a package in this repository β only the trained weights. See the accompanying source code: https://github.com/ocjorge/SignalReconstructionFilter
Limitations
- Signal-level fidelity improvements from restoration (SNR, MAE, correlation) did not translate into improved downstream motor-intent classification; restoration reduced sensitivity relative to using the degraded signal directly, and task-aware retraining only partially recovered this gap.
- The task-aware evaluation (Table 4) is a post hoc, exploratory analysis reusing the same held-out test split after observing the initial downstream degradation β it does not constitute an independent evaluation of the task-aware approach.
- Real-participant (amputee) evaluation is pilot-scale (n = 2); results should not be read as statistically generalizable.
- For real (non-synthetic) recordings, no independent clean reference exists, so reconstruction metrics on those recordings measure how much restoration changes the signal, not verified improvement toward ground truth.
License
Model weights released under CC BY 4.0, matching the paper's license. Change this if you'd prefer a different license (e.g. MIT, Apache-2.0) β just make sure the license file/tag in this repo matches what you actually intend.
Citation
@article{ortizceballos2026gestural,
title = {Gestural Intent Detection and Adaptive Restoration of Degraded sEMG Signals Using Temporal Convolutional Networks and an Autoencoder},
author = {Ortiz Ceballos, Jorge and Abundez Barrera, Itzel Mar{\'i}a and Rend{\'o}n-Lara, Er{\'e}ndira},
journal = {Symmetry},
volume = {18},
number = {9},
pages = {1540},
year = {2026},
publisher = {MDPI},
doi = {10.3390/sym18091540},
url = {https://doi.org/10.3390/sym18091540}
}