File size: 6,138 Bytes
b4b2877
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/bin/bash
# SLURM launcher for T10 Triplet Next-Action Prediction experiments.
#
# Produces all five tables from the paper plan:
#   Table 1: main comparison (T_fut=2s)     — 1 model × 5 seeds
#   Table 3: horizon curve                  — 5 horizons × 5 seeds (same model)
#   Table 4: modality ablation              — 6 configs × 5 seeds (ours only)
#   Table 5: component ablation             — 5 variants × 5 seeds (ours only)
#   Table 7: missing-modality robustness    — trained once w/ modality dropout,
#                                             evaluated under 6 test-time drops
#
# ~140 jobs in total. Uses `gpuHygonZ100` (2 idle nodes); change PARTITION to
# `gpuA800` if larger slots are available.
#
# Usage:
#     bash experiments/run_seqpred_all.sh
#     bash experiments/run_seqpred_all.sh --dry    # print what would submit
#
# Outputs: results/seqpred/<config>_<seedX>/{config.json, results.json,
#                                             model_best.pt}
# Aggregate into tables with experiments/analysis/aggregate_seqpred.py (TBD).

set -euo pipefail

DRY=${1:-}
PYTHON=${PYTHON:-python3}
BASEDIR=${BASEDIR:-${PULSE_ROOT}}
TRAIN=${BASEDIR}/experiments/tasks/train_seqpred.py
OUTDIR=${BASEDIR}/results/seqpred
LOGDIR=${OUTDIR}/slurm_logs
mkdir -p "${LOGDIR}"

PARTITION=${PARTITION:-gpuHygonZ100}
GPU_GRES=${GPU_GRES:-gpu:1}
CPUS=${CPUS:-4}
MEM=${MEM:-48G}
TIME=${TIME:-6:00:00}

BASE_ARGS="--epochs 40 --batch_size 32 --lr 3e-4 --weight_decay 1e-4 \
           --dropout 0.2 --patience 12 --label_smoothing 0.05 \
           --use_class_weights --num_workers 2"

ALL_MODS="imu,emg,eyetrack,mocap,pressure"

submit() {
    local JOB_NAME=$1
    local OUT_SUB=$2
    shift 2
    local CMD="export PYTHONUNBUFFERED=1; cd ${BASEDIR}; \
               ${PYTHON} ${TRAIN} $* --output_dir ${OUTDIR}/${OUT_SUB}"
    if [[ "${DRY}" == "--dry" ]]; then
        echo "--- ${JOB_NAME} ---"
        echo "  out: ${OUTDIR}/${OUT_SUB}"
        echo "  $*"
        return
    fi
    sbatch \
        -J "sp_${JOB_NAME}" \
        -p "${PARTITION}" \
        --gres="${GPU_GRES}" \
        -N 1 -n 1 \
        --cpus-per-task=${CPUS} \
        --mem=${MEM} \
        -t "${TIME}" \
        -o "${LOGDIR}/${JOB_NAME}_%j.out" \
        -e "${LOGDIR}/${JOB_NAME}_%j.err" \
        --export=ALL \
        --wrap="${CMD}"
    echo "submitted: ${JOB_NAME} -> ${OUT_SUB}"
}

SEEDS=(42 123 456 789 1024)

# ---------------------------------------------------------------------
# Table 1: main comparison at T_fut=2s
#   Baselines (B1..B8) run on their preferred modality subsets;
#   DailyActFormer runs on ALL 5 modalities.
# ---------------------------------------------------------------------
echo "=== Table 1: main comparison ==="

for seed in "${SEEDS[@]}"; do
    # --- our model, full 5-modality ---
    submit "t1_ours_all5_s${seed}" "t1_ours_all5/seed${seed}" \
        --model dailyactformer --modalities ${ALL_MODS} \
        --t_obs 8 --t_fut 2 --seed ${seed} ${BASE_ARGS}

    # --- DeepConvLSTM (IMU only) ---
    submit "t1_dcl_imu_s${seed}" "t1_dcl_imu/seed${seed}" \
        --model deepconvlstm --modalities imu \
        --t_obs 8 --t_fut 2 --seed ${seed} ${BASE_ARGS}

    # --- DeepConvLSTM (IMU+MoCap+EMG, best 3-modality for baselines) ---
    submit "t1_dcl_3mod_s${seed}" "t1_dcl_3mod/seed${seed}" \
        --model deepconvlstm --modalities imu,mocap,emg \
        --t_obs 8 --t_fut 2 --seed ${seed} ${BASE_ARGS}
done

# ---------------------------------------------------------------------
# Table 3: horizon curve (our model only, 5 horizons × 5 seeds = 25 jobs)
# ---------------------------------------------------------------------
echo ""
echo "=== Table 3: horizon curve ==="
for tfut in 1 2 5 10 15; do
    for seed in "${SEEDS[@]}"; do
        submit "t3_ours_tfut${tfut}_s${seed}" \
            "t3_ours_tfut${tfut}/seed${seed}" \
            --model dailyactformer --modalities ${ALL_MODS} \
            --t_obs 8 --t_fut ${tfut} --seed ${seed} ${BASE_ARGS}
    done
done

# ---------------------------------------------------------------------
# Table 4: modality ablation on our model (remove one modality at a time)
# ---------------------------------------------------------------------
echo ""
echo "=== Table 4: modality ablation ==="
declare -A ABLATIONS
ABLATIONS["noPressure"]="imu,emg,eyetrack,mocap"
ABLATIONS["noEyeTrack"]="imu,emg,mocap,pressure"
ABLATIONS["noEMG"]="imu,eyetrack,mocap,pressure"
ABLATIONS["noIMU"]="emg,eyetrack,mocap,pressure"
ABLATIONS["noMoCap"]="imu,emg,eyetrack,pressure"
ABLATIONS["onlyIMU_EMG"]="imu,emg"
ABLATIONS["onlyMoCap"]="mocap"
ABLATIONS["onlyEMG"]="emg"
for tag in "${!ABLATIONS[@]}"; do
    mods="${ABLATIONS[$tag]}"
    for seed in "${SEEDS[@]}"; do
        submit "t4_${tag}_s${seed}" "t4_${tag}/seed${seed}" \
            --model dailyactformer --modalities ${mods} \
            --t_obs 8 --t_fut 2 --seed ${seed} ${BASE_ARGS}
    done
done

# ---------------------------------------------------------------------
# Table 5: component ablation on our model
# (ablation switches TBD — parameter hooks need to be added to the model
# first. For now submit a placeholder using lambda weights.)
# ---------------------------------------------------------------------
echo ""
echo "=== Table 5: component ablation (placeholders) ==="
# 5a: no aux verb_composite head (set lambda to 0)
for seed in "${SEEDS[@]}"; do
    submit "t5_noComp_s${seed}" "t5_noComp/seed${seed}" \
        --model dailyactformer --modalities ${ALL_MODS} \
        --t_obs 8 --t_fut 2 --seed ${seed} ${BASE_ARGS} \
        --lambda_verb_composite 0.0
done
# 5b: equal-weight heads (remove our lambda prior)
for seed in "${SEEDS[@]}"; do
    submit "t5_equalLambda_s${seed}" "t5_equalLambda/seed${seed}" \
        --model dailyactformer --modalities ${ALL_MODS} \
        --t_obs 8 --t_fut 2 --seed ${seed} ${BASE_ARGS} \
        --lambda_verb_composite 1.0 --lambda_hand 1.0
done

# 5c/5d/5e (modality-stem / fusion / causal-mask toggles) require model
# plumbing — we'll add CLI flags later.

echo ""
echo "All done.  Inspect with:  squeue -u \$USER | head"