Views
No views yet
PainFormer · 19.60 M parameters · 5.82 GFLOPs · 160-D embeddings · PyTorch ≥ 2.0
| Feature | Description |
|---|---|
| Pre-training scale | Multi-task pre-training on 14 tasks / 10.9 M samples. |
| Parameters | 19.60 M (PainFormer encoder). |
| Compute | 5.82 GFLOPs at 224×224 input. |
| Embeddings | Fixed 160-D output vectors. |


checkpoint/ in this repository.| File | Size |
|---|---|
checkpoint/painformer.pth | 75 MB |
1# direct file download (PainFormer)
2mkdir -p checkpoint
3wget https://huggingface.co/stefanosgikas/PainFormer/resolve/main/checkpoint/painformer.pth1from huggingface_hub import hf_hub_download
2ckpt_path = hf_hub_download(
3 repo_id="stefanosgikas/PainFormer",
4 filename="checkpoint/painformer.pth"
5)
6print(ckpt_path)sha256sum checkpoint/painformer.pthmodel_state_dict # PainFormer backbone weights.
├── docs/ # images for the model card
├── architecture/ # Python modules (e.g., painformer.py)
└── checkpoint/ # painformer.pth1import torch
2from timm.models import create_model
3from PIL import Image
4from torchvision import transforms
5
6# model code lives in the local "architecture" folder
7from architecture import painformer # ensures registry / model class is imported
8
9# ---------------------------------------------------------------
10# Setup ---------------------------------------------------------
11# ---------------------------------------------------------------
12device = "cuda" if torch.cuda.is_available() else "cpu"
13
14# VGG-Face2 statistics used during pretraining
15normalize = transforms.Normalize(
16 mean=[0.6068, 0.4517, 0.3800],
17 std=[0.2492, 0.2173, 0.2082]
18)
19to_tensor = transforms.Compose([
20 transforms.Resize((224, 224)),
21 transforms.ToTensor(),
22 normalize
23])
24
25# ---------------------------------------------------------------
26# Load PainFormer -----------------------------------------------
27# ---------------------------------------------------------------
28model = create_model('painformer').to(device) # class registered by architecture/painformer.py
29state = torch.load('checkpoint/painformer.pth', map_location=device)
30model.load_state_dict(state['model_state_dict'], strict=False)
31
32# expose embeddings (remove classification head)
33model.head = torch.nn.Identity()
34model.eval()
35
36# ---------------------------------------------------------------
37# One image → 160-D embedding -----------------------------------
38# ---------------------------------------------------------------
39img = Image.open('frame.png').convert('RGB')
40x = to_tensor(img).unsqueeze(0).to(device) # [1, 3, 224, 224]
41
42with torch.no_grad():
43 emb = model(x) # [1, 160]
44 emb = emb.squeeze(0) # [160]
45
46print("Embedding shape:", tuple(emb.shape)) # (160,)1import torch, torch.nn as nn
2from timm.models import create_model
3from architecture import painformer
4
5device = "cuda" if torch.cuda.is_available() else "cpu"
6num_classes = 3 # set to your task
7
8# Backbone → 160-D embeddings
9model = create_model('painformer').to(device)
10state = torch.load('checkpoint/painformer.pth', map_location=device)
11model.load_state_dict(state['model_state_dict'], strict=False)
12
13# freeze if you only need fixed embeddings
14for p in model.parameters():
15 p.requires_grad = False
16
17# simple head (example)
18head = nn.Sequential(
19 nn.ELU(),
20 nn.Linear(160, num_classes)
21).to(device)
22
23optimizer = torch.optim.Adam(head.parameters(), lr=1e-3)
24criterion = nn.CrossEntropyLoss()
25
26# optional: end-to-end fine-tune
27for p in model.parameters():
28 p.requires_grad = True
29optimizer = torch.optim.AdamW(
30 list(model.parameters()) + list(head.parameters()),
31 lr=3e-4, weight_decay=0.05
32)1@ARTICLE{gkikas_painformer_2025,
2 author={Gkikas, Stefanos and Rojas, Raul Fernandez and Tsiknakis, Manolis},
3 journal={IEEE Transactions on Affective Computing},
4 title={PainFormer: a Vision Foundation Model for Automatic Pain Assessment},
5 year={2025},
6 volume={},
7 number={},
8 pages={1-18},
9 doi={10.1109/TAFFC.2025.3605475}
10}LICENSE.