Feature Extraction
PyTorch
timm
English
biosignals
ecg
emg
eeg
embedding
mixture-of-experts
lightweight
Instructions to use stefanosgikas/TinyBioMoE with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- timm
How to use stefanosgikas/TinyBioMoE with timm:
import timm model = timm.create_model("hf_hub:stefanosgikas/TinyBioMoE", pretrained=True) - Notebooks
- Google Colab
- Kaggle
| license: mit | |
| language: | |
| - en | |
| library_name: pytorch | |
| pipeline_tag: feature-extraction | |
| tags: | |
| - biosignals | |
| - ecg | |
| - emg | |
| - eeg | |
| - embedding | |
| - mixture-of-experts | |
| - timm | |
| - pytorch | |
| - lightweight | |
| thumbnail: docs/overview.png | |
| pretty_name: Tiny-BioMoE | |
| model-index: | |
| - name: Tiny-BioMoE | |
| results: [] | |
| # Tiny-BioMoE | |
| a Lightweight Embedding Model for Biosignal Analysis | |
| > **Tiny-BioMoE** · **7.34 M parameters** · **3.04 GFLOPs** · **192-D embeddings** · **PyTorch ≥ 2.0** | |
| --- | |
| ## Paper | |
| [**Tiny-BioMoE: a Lightweight Embedding Model for Biosignal Analysis**](https://dl.acm.org/doi/full/10.1145/3747327.3764788) | |
| --- | |
| ## Highlights | |
| | Feature | Description | | |
| | ---------------- | --------------------------------------------------------------------------- | | |
| | **Compact** | <8 M parameters – runs comfortably on a laptop GPU / modern CPU | | |
| | **Cross-domain** | Pre-trained on **4.4 M** ECG, EMG & EEG representations via multi-task learning | | |
| <br/> | |
| |  |  | | |
| |:--:|:--:| | |
| | **Overall Tiny-BioMoE architecture** | **Expert encoders** | | |
| --- | |
| ## Table of Contents | |
| 1. [Pre-trained checkpoint](#pre-trained-checkpoint) | |
| 2. [Quick start](#quick-start) | |
| * [Extract embeddings](#extract-embeddings) | |
| 3. [Fine-tuning](#fine-tuning) | |
| 4. [Citation](#citation) | |
| 5. [Licence & acknowledgements](#licence--acknowledgements) | |
| --- | |
| ## Pre-trained Checkpoint | |
| The checkpoint is stored under `checkpoint/` in this repository. | |
| | File | Size | | |
| | ----------------------------- | ------ | | |
| | `checkpoint/Tiny-BioMoE.pth` | **89 MB** | | |
| Download options: | |
| ```bash | |
| # direct file download | |
| wget https://huggingface.co/stefanosgikas/TinyBioMoE/resolve/main/checkpoint/Tiny-BioMoE.pth | |
| ``` | |
| ```python | |
| from huggingface_hub import hf_hub_download | |
| ckpt_path = hf_hub_download( | |
| repo_id="StefanosGkikas/Tiny-BioMoE", | |
| filename="checkpoint/Tiny-BioMoE.pth" | |
| ) | |
| print(ckpt_path) | |
| ``` | |
| Optional integrity check: | |
| ```bash | |
| sha256sum checkpoint/Tiny-BioMoE.pth | |
| ``` | |
| The checkpoint contains: | |
| ``` | |
| model_state_dict # MoE backbone weights (SpectFormer-T-w + EfficientViT-w) | |
| ``` | |
| --- | |
| ## Quick start | |
| Assumes **PyTorch ≥ 2.0** and **timm ≥ 0.9** are installed. | |
| Repository layout expected: | |
| ``` | |
| . | |
| ├── docs/ # images for the model card | |
| ├── architecture/ # Python modules for the encoders / MoE | |
| └── checkpoint/ # Tiny-BioMoE.pth | |
| ``` | |
| ### Extract embeddings | |
| ```python | |
| import torch, torch.nn as nn | |
| from PIL import Image | |
| from torchvision import transforms | |
| from timm.models import create_model | |
| # local "architecture" folder | |
| from architecture import spectformer, efficientvit | |
| emb_size, num_experts = 96, 2 | |
| final_emb_size = emb_size * num_experts # 192-D | |
| device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') | |
| class MoE(nn.Module): | |
| def __init__(self, enc1, enc2): | |
| super().__init__() | |
| self.enc1, self.enc2 = enc1, enc2 | |
| self.ln_img = nn.LayerNorm((3, 224, 224)) | |
| self.ln_e = nn.LayerNorm(emb_size) | |
| self.ln_out = nn.LayerNorm(final_emb_size) | |
| self.fcn = nn.Sequential(nn.ELU(), nn.Linear(emb_size, emb_size), | |
| nn.Hardtanh(0, 1)) | |
| @torch.no_grad() | |
| def forward(self, x): | |
| x = self.ln_img(x) | |
| z1, *_ = self.enc1(x) | |
| z2 = self.enc2(x) | |
| z1 = self.ln_e(z1) * self.fcn(z1) | |
| z2 = self.ln_e(z2) * self.fcn(z2) | |
| return self.ln_out(torch.cat((z1, z2), 1)) | |
| enc1 = create_model('spectformer_t_w'); enc1.head = nn.Identity() | |
| enc2 = create_model('EfficientViT_w'); enc2.head = nn.Identity() | |
| backbone = MoE(enc1, enc2).to(device).eval() | |
| state = torch.load("checkpoint/Tiny-BioMoE.pth", map_location=device) | |
| backbone.load_state_dict(state['model_state_dict']) | |
| tr = transforms.Compose([transforms.Resize((224,224)), transforms.ToTensor()]) | |
| img = Image.open('img.png').convert('RGB') | |
| x = tr(img).unsqueeze(0).to(device) | |
| feat = backbone(x).squeeze(0) | |
| print(feat.shape) | |
| ``` | |
| --- | |
| ## Fine-tuning | |
| ```python | |
| import torch, torch.nn as nn | |
| num_classes = 3 | |
| head = nn.Sequential( | |
| nn.ELU(), | |
| nn.Linear(192, num_classes) | |
| ) | |
| for p in backbone.parameters(): | |
| p.requires_grad = False | |
| model = nn.Sequential(backbone, head).to(device) | |
| optimizer = torch.optim.AdamW(head.parameters(), lr=1e-3, weight_decay=1e-4) | |
| ``` | |
| --- | |
| ## Citation | |
| ```bibtex | |
| @inproceedings{tiny_biomoe, | |
| author = {Gkikas, Stefanos and Kyprakis, Ioannis and Tsiknakis, Manolis}, | |
| title = {Tiny-BioMoE: a Lightweight Embedding Model for Biosignal Analysis}, | |
| year = {2025}, | |
| isbn = {9798400720765}, | |
| publisher = {Association for Computing Machinery}, | |
| address = {New York, NY, USA}, | |
| url = {https://doi.org/10.1145/3747327.3764788}, | |
| doi = {10.1145/3747327.3764788}, | |
| booktitle = {Companion Proceedings of the 27th International Conference on Multimodal Interaction}, | |
| pages = {117–126}, | |
| numpages = {10}, | |
| series = {ICMI '25 Companion} | |
| } | |
| ``` | |
| --- | |
| ## Licence & acknowledgements | |
| * Code & weights: **MIT Licence** – see `LICENSE`. | |
| --- | |
| ### Contact | |
| Email **Stefanos Gkikas:** gkikas[at]ics[dot]forth[dot]gr / gikasstefanos[at]gmail[dot]com | |