In this repository, we share the baseline implementation, baseline results, as well as code for feature extraction.
We evaluated all our feature sets on all available test datasets. Models tested on NoXI, NoXI (Additional Languages), and MPIIGroupInteraction were trained on NoXI. Models tested on NoXI-J were trained on NoXI-J.
We use the best performing model on the test set for our baseline performance.
| Feature set | NOXI | NOXI (Add.) | NOXI-J | MPIIGI | Combined |
|---|---|---|---|---|---|
| Video | |||||
| Β Β OpenFace 2.0 | 0.1070 | 0.1948 | 0.1556 | 0.1159 | 0.1433 |
| Β Β OpenFace 3.0 | 0.2192 | 0.1081 | 0.2701 | 0.0880 | 0.1714 |
| Β Β OpenPose | 0.4801 | 0.4272 | 0.2687 | 0.0854 | 0.3153 |
| Β Β CLIP | 0.4350 | 0.3652 | 0.2206 | -0.0099 | 0.2527 |
| Β Β DINO | 0.5290 | 0.4592 | 0.1071 | 0.0068 | 0.2755 |
| Β Β SwinTransformer | 0.5406 | 0.4649 | 0.2627 | -0.0482 | 0.3050 |
| Β Β VideoMAE | 0.6065 | 0.5602 | 0.2168 | 0.0173 | 0.3502 |
| Voice | |||||
| Β Β eGeMAPS v2 | 0.5535 | 0.4909 | 0.3132 | 0.4539 | 0.4529 |
| Β Β w2vBERT2 | 0.5986 | 0.4710 | 0.3178 | 0.0540 | 0.3604 |
| Text | |||||
| Β Β XLM RoBERTa | 0.3916 | 0.2698 | 0.2553 | 0.0090 | 0.2314 |
As eGeMAPs v2 achieves the best combined performance, please at least always compare your approach to this baseline method.
We use the best performing model on each pinsoro subset for our classification task baseline.
| Feature set | Pinsoro-CC Social | Pinsoro-CC Task | Pinsoro-CR Social | Pinsoro-CR Task | Combined |
|---|---|---|---|---|---|
| Video | |||||
| Β Β OpenFace 2.0 | 0.0776 | 0.0583 | -0.0118 | 0.2463 | 0.0926 |
| Β Β OpenFace 3.0 | 0.1250 | 0.0980 | 0.0164 | 0.1715 | 0.1027 |
| Β Β OpenPose | 0.0615 | 0.0332 | -0.0261 | 0.2090 | 0.0694 |
| Β Β CLIP | 0.0933 | 0.1245 | -0.0216 | 0.1601 | 0.0891 |
| Β Β DINO | 0.0752 | 0.0729 | 0.0121 | 0.0826 | 0.0607 |
| Β Β SwinTransformer | 0.0905 | 0.0844 | 0.0901 | 0.2426 | 0.1269 |
| Β Β VideoMAE | 0.1436 | 0.1347 | -0.0191 | 0.0465 | 0.0764 |
| Voice | |||||
| Β Β eGeMAPS v2 | 0.1320 | 0.0207 | -0.0188 | -0.0262 | 0.0269 |
| Β Β w2vBERT2 | 0.1089 | 0.0549 | 0.0032 | 0.0262 | 0.0483 |
| Text | |||||
| Β Β XLM RoBERTa | 0.1438 | 0.1609 | -0.0265 | 0.1044 | 0.0956 |
Details on the feature extraction methods can be found under the feature_extraction directory in this repository.
A SLURM-ready deep learning pipeline for hyperparameter tuning and training of neural regressors on multimodal data.
This repository enables flexible experimentation through external config files and supports scalable GPU-based training on HPC clusters.
baseline/
βββ env_gpu.yml # Conda environment file
βββ results.md # Summary of results
β
βββ 1_TrainingNN_tuner.py # Step 1: Hyperparameter tuning
βββ 1.1_TuneResultExtraction.py # Step 1.1: Extract tuning results
βββ 2_RetrainNN_full.py # Step 2: Full retrain with best hyperparameters
βββ 2.1_RetrainResultExtraction.py # Step 2.1: Extract retrain results
βββ 3_TestingNN_infer_plot.py # Step 3: Inference and prediction plots
βββ 4_TestingNN_fairness_per_session.py # Step 4: Per-session fairness evaluation
βββ 5_CreateResulttable.py # Step 5: Recompute metrics from predictions/GT and generate markdown result table
β
βββ run_1_tuner_noxi.slurm # SLURM submission scripts for step 1
βββ run_1_tuner_noxi_j.slurm
βββ run_1_tuner_pinsoro.slurm
βββ run_1_tuner_pinsoro_cc.slurm
βββ run_1_tuner_pinsoro_cc_videomae.slurm
βββ run_1_tuner_pinsoro_cr.slurm
βββ run_2_full_trainer_noxi.slurm # SLURM submission scripts for step 2
βββ run_2_full_trainer_noxij.slurm
βββ run_2_full_trainer_pinsoro.slurm
βββ run_2_full_trainer_pinsoro_cc.slurm
βββ run_2_full_trainer_pinsoro_cr.slurm
βββ run_3_test_plots.slurm
βββ run_4_test_fairness_allmod_psess.slurm
βββ run_all_1.sh ... run_all_4.sh # Convenience scripts to submit all jobs
β
βββ configs/ # Experiment configuration files (JSON)
β βββ noxi-base/
β β βββ dataset-config.json
β β βββ tune/ # Per-modality tuning configs
β β βββ retrain/ # Per-modality retrain configs
β β βββ full_train/ # Full training configs (config1β4.json)
β β βββ test/
β βββ noxi-j/ # Same structure as noxi-base
β βββ pinsoro-cc/ # Same structure as noxi-base
β βββ pinsoro-cr/ # Same structure as noxi-base
β βββ mpiigroupinteraction/
β β βββ dataset-config.json
β β βββ test/
β βββ test-additional/
β βββ dataset-config.json
β βββ test/
β
βββ final_models/ # Tuned model checkpoints (.keras) per dataset
β
βββ results/ # Output folder for results
- Python 3.8+
- Miniconda or Anaconda
- A Slurm-managed HPC cluster with GPU nodes (A40 in this example)
- Required Python packages (handled by
env_gpu.yml) - Your data directory structure (see config files)
Each SLURM script automatically creates or updates the conda environment from env_gpu.yml on first run.
Edit the env_name variable at the top of any .slurm file to change the environment name.
All experiment settings are defined in JSON files under configs/<dataset>/.
There are three types of config, used by different pipeline steps:
Used by step 1. One file per modality per dataset.
{
"modalities": [".audio.egemapsv2.stream~"],
"modalities_dim": [88],
"debug_mode": false,
"tuning_subset_frac": 1.0,
"training_subset_frac": 1.0,
"train_dir": "/mnt/data/noxi/train/",
"val_dir": "/mnt/data/noxi/val/",
"tuner_base_dir": "./nn/tuner/tuner_models_regression",
"final_base_dir": "./final_models/nn/single_modality"
}Auto-generated by step 1.1 (1.1_TuneResultExtraction.py). Contains the best hyperparameters found during tuning.
{
"modalities": [".audio.egemapsv2.stream~"],
"modalities_dim": [88],
"train_dir": "/mnt/data/noxi/train/",
"val_dir": "/mnt/data/noxi/val/",
"full_base_dir": "./results/full_models",
"best_hyperparameters": {
".audio.egemapsv2.stream~": {
"units1": 360, "units2": 384, "units3": 128,
"dropout": 0.35, "learning_rate": 0.001, "batch_size": 32
}
}
}Used by steps 3 and 4. Lists all modalities and points to the test split and ground-truth labels.
{
"modalities": [".audio.egemapsv2.stream~", ".clip.stream~", "..."],
"modalities_dim": [88, 512, "..."],
"train_dir": "/mnt/data/noxi/train/",
"val_dir": "/mnt/data/noxi/val/",
"test_dir": "/mnt/data/noxi/test-base/",
"full_base_dir": "./results/full_models",
"engagement_gt": "./engagement-mm26-test/noxi/test-base"
}| Parameter | Description |
|---|---|
modalities |
List of feature modalities to use |
modalities_dim |
Feature dimensions matching each modality |
debug_mode |
Set true for fast test runs (reduced epochs) |
tuning_subset_frac |
Fraction of training data used for hyperparameter search |
training_subset_frac |
Fraction of training data used during tuningβs final fit |
train_dir / val_dir / test_dir |
Data directories for each split |
tuner_base_dir |
Where KerasTuner checkpoints and logs are stored |
final_base_dir |
Where retrained full models are saved |
best_hyperparameters |
Best hyperparameters per modality (auto-filled by step 1.1) |
engagement_gt |
Path to ground-truth engagement labels for testing |
The pipeline runs in 5 steps. Use the run_all_*.sh scripts to submit all jobs for all datasets at once, or submit individual SLURM jobs manually. Without test set annotations, only the first 2 steps can be run.
# All datasets at once:
bash run_all_1.sh
# Or a single job:
sbatch run_1_tuner_noxi.slurm configs/noxi-base/tune/config_audio_egemapsv2.jsonReads tuner output and writes retrain configs to configs/<dataset>/retrain/.
python 1.1_TuneResultExtraction.py# All datasets at once:
bash run_all_2.sh
# Or a single job:
sbatch run_2_full_trainer_noxi.slurm configs/noxi-base/retrain/audio.egemapsv2.stream.jsonpython 2.1_RetrainResultExtraction.pybash run_all_3.sh
# Or a single job:
sbatch run_3_test_plots.slurm configs/noxi-base/test/config1.jsonbash run_all_4.sh
# Or a single job:
sbatch run_4_test_fairness_allmod_psess.slurm configs/noxi-base/test/config1.jsonRecomputes CCC (regression) and Cohen's Kappa / Accuracy (classification) metrics directly from prediction and ground-truth CSV files, and writes a markdown result table.
python 5_CreateResulttable.py \
--results_dir results/2026 \
--gt_root ./engagement-mm26-test \
--output ../results.mdAll arguments are optional and default to the values shown above.
-
SLURM logs:
logs/<jobname>-<jobid>.log -
Tuned model checkpoints:
final_models/<dataset>/nn/single_modality/*.keras(path set byfinal_base_dirin tune configs) -
Retrained full models:
results/full_models/retrained_full_nn_model_<modality>.keras(path set byfull_base_dirin retrain/test configs) -
CCC / MSE scores per modality:
results/full_models/final_ccc_<modality>.txtandfinal_mse_<modality>.txt -
Test predictions and plots:
results/<dataset>/β scatter plots, residuals, per-session metrics
# Check job status
squeue -u $USER
# Live log output
tail -f logs/<jobname>-<jobid>.logimport tensorflow as tf
model = tf.keras.models.load_model(
βresults/full_models/retrained_full_nn_model_audio.egemapsv2.stream.kerasβ
)- If
module: command not found, check your clusterβs module system documentation. - If jobs fail, check resource requests and verify data/config paths in the JSON files.
- Check
logs/for Python errors or data shape mismatches.
- Add tune configs in
configs/<dataset>/tune/for new modalities or datasets. - Adjust GPU/CPU/memory requests at the top of any
.slurmfile. - Modify model architecture or training logic in
1_TrainingNN_tuner.pyor2_RetrainNN_full.py.
For questions, consult your cluster admin or the script author.
Happy training and experimentation!