1
0
Fork
You've already forked ml_project_2026
0
REASSEMBLE GEARS ACTION RECOGNITION (1ST EDITION, 2026) REASSEMBLE GEARS TEMPORAL ACTION SEGMENTATION (1ST EDITION, 2026)
  • Python 100%
Philipp Oismüller d319a9fd0c working pipeline
2026年06月18日 08:14:49 +02:00
.vscode backup 2026年06月13日 14:41:18 +02:00
starting_kit_Ar_v5 working pipeline 2026年06月18日 08:14:49 +02:00
.gitignore backup 2026年06月13日 14:41:18 +02:00
ML_2026SS_Projects.pdf adding readme and stuff 2026年06月13日 14:09:34 +02:00
README.md adding readme and stuff 2026年06月13日 14:09:34 +02:00

Gear Manipulation Dataset — PyTorch Loaders

A pair of PyTorch Dataset classes for loading robot manipulation data that combines RGB video frames with proprioceptive sensor streams. The data covers a robotic arm picking, inserting, removing, and placing gears of three sizes.


Action Classes

Both datasets share the same 13-class action vocabulary:

ID Action
0 pick_small_gear
1 pick_medium_gear
2 pick_large_gear
3 insert_small_gear
4 insert_medium_gear
5 insert_large_gear
6 remove_small_gear
7 remove_medium_gear
8 remove_large_gear
9 place_small_gear
10 place_medium_gear
11 place_large_gear
12 no_action

Datasets

SegDataset — Frame-level segmentation

Loads a full recording and returns a per-frame action label for every frame. Use this when you need dense, frame-by-frame supervision.

Expected directory layout

dataset_path/
 train/
 annotations/
 recording_001/
 action_labels.txt ← one action string per line, one per frame
 recording_002/
 action_labels.txt
 ...
 data/
 recording_001/
 frames/ ← 00000.jpg, 00001.jpg, ...
 proprioception/ ← 00000.npz, 00001.npz, ...
 recording_002/
 ...
 val/ (same structure)
 test/ (same structure)

action_labels.txt format

pick_small_gear
pick_small_gear
insert_small_gear
no_action
...

One action string per line, matching the keys in action_dict. The number of lines must equal the number of image files.

What __getitem__ returns

Key Type Shape Description
frames np.ndarray (N, H, W, C) RGB frames stacked along axis 0
labels np.ndarray (N,) Integer class ID per frame
pose np.ndarray (N, 7) End-effector pose [x, y, z, qx, qy, qz, qw]
velocity np.ndarray (N, 6) Cartesian velocity [vx, vy, vz, wx, wy, wz]
joint_positions np.ndarray (N, 7) Joint angles
joint_velocities np.ndarray (N, 7) Joint angular velocities
gripper_positions np.ndarray (N, 2) Left / right gripper position
gripper_velocities np.ndarray (N, 2) Left / right gripper velocity
measured_wrench np.ndarray (N, 6) Force–torque [fx, fy, fz, tx, ty, tz]

Quick start

from datamodule.SegDataset import SegDataset
dataset = SegDataset(dataset_path="/path/to/dataset", type="train")
print(len(dataset)) # number of recordings
sample = dataset[0]
print(sample["frames"].shape) # (N, H, W, 3)
print(sample["labels"].shape) # (N,)

ActionRecognitionDataset — Segment-level recognition

Splits each recording into action segments defined by a segments.txt file and returns one sample per segment along with a success flag. Use this for clip-level classification or success prediction.

Additional annotation file — segments.txt

Placed alongside action_labels.txt inside each recording's annotation folder:

frame_start	frame_end	success	text
0	24	1	pick small gear
25	61	1	insert small gear
62	80	0	
  • Tab-separated with a header row.
  • text is the human-readable action label (spaces, not underscores). An empty text field maps to no_action.
  • success is 1 (succeeded) or 0 (failed).

What __getitem__ returns

Same proprioceptive keys as SegDataset, plus:

Key Type Description
label int Integer class ID for the segment
success int 1 if the action succeeded, 0 otherwise

Note: frames and all proprioceptive arrays cover only the frames in [frame_start, frame_end] (inclusive).

Quick start

from datamodule.ActionRecognitionDataset import ActionRecognitionDataset
dataset = ActionRecognitionDataset(dataset_path="/path/to/dataset", type="train")
print(len(dataset)) # number of segments (across all recordings)
sample = dataset[0]
print(sample["frames"].shape) # (N, H, W, 3) — N = segment length
print(sample["label"]) # e.g. 3
print(sample["success"]) # 0 or 1

Proprioception .npz Format

Each .npz file stores one or more time-steps of sensor data (the sensor runs at a higher frequency than the camera). The dataset loader always takes the last sample in each file so that the proprioception timestamp aligns with the corresponding image frame:

proprioception[key][-1] # last reading in the file → aligned with the image

The keys present in the .npz files determine which proprioceptive signals appear in the returned dict — no hard-coding is needed.


Visualization (visualize.py)

visualize.py provides animated GIF generators for quick dataset inspection.

from visualize import animate_seg_sample, animate_action_sample
Function Dataset Output
animate_seg_sample(sample, filename, fps) SegDataset GIF with per-frame action label overlay
animate_action_sample(sample, title, filename, fps) ActionRecognitionDataset GIF with segment label + success flag in the title

Both functions render the RGB video alongside scrolling time-series plots of every available proprioceptive signal. A red vertical line tracks the current frame.

Running the built-in demo

python visualize.py
# Produces:
# action_successful.gif — first successful segment found in train split
# action_failed.gif — first failed segment found in train split

Evaluation (metrics.py)

metrics.py provides three evaluation functions, one per task. All values are returned as percentages in a plain dict so they are easy to log (e.g. to wandb or a CSV).

recognition_metrics(y_true, y_pred)

Clip-level metrics for ActionRecognitionDataset. Expects one integer class ID per clip.

from metrics import recognition_metrics
from datamodule.ActionRecognitionDataset import ActionRecognitionDataset
dataset = ActionRecognitionDataset(dataset_path=..., type="test")
all_labels, all_preds = [], []
for sample in dataset:
 label = sample["label"]
 pred = model(sample["frames"]) # → int class id
 all_labels.append(label)
 all_preds.append(pred)
results = recognition_metrics(all_labels, all_preds)
# {'accuracy': 82.5, 'precision': 82.5, 'recall': 82.5, 'f1': 82.5}
Metric Description
accuracy Fraction of correctly classified clips (%)
precision Micro-averaged precision (%)
recall Micro-averaged recall (%)
f1 Micro-averaged F1 (%)

For micro-averaging over a single-label classification task, accuracy = precision = recall = F1. They are all returned for API consistency with the other two functions.


segmentation_metrics(recognized_seqs, ground_truth_seqs, ...)

Frame-wise metrics for SegDataset. Both arguments are lists of lists of label strings (one list per recording).

from metrics import segmentation_metrics
from datamodule.SegDataset import SegDataset
from datamodule.ActionRecognitionDataset import action_dict
inv = {v: k for k, v in action_dict.items()} # int → string
dataset = SegDataset(dataset_path=..., type="test")
gt_seqs, pred_seqs = [], []
for sample in dataset:
 gt_seqs.append([inv[l] for l in sample["labels"]])
 preds = model(sample["frames"]) # → (N,) int array
 pred_seqs.append([inv[p] for p in preds])
results = segmentation_metrics(
 pred_seqs,
 gt_seqs,
 overlap_thresholds=(0.10, 0.25, 0.50),
 bg_class=("no_action",), # frames with this label are treated as background
)
# {'accuracy': 78.3, 'edit': 85.1, 'F1@0.10': 91.2, 'F1@0.25': 87.4, 'F1@0.50': 72.6}
Metric Description
accuracy Frame-level accuracy (%)
edit Mean normalised edit distance score (%) — higher is better
F1@0.10 Segment-level F1 at IoU ≥ 0.10 (%)
F1@0.25 Segment-level F1 at IoU ≥ 0.25 (%)
F1@0.50 Segment-level F1 at IoU ≥ 0.50 (%)

The IoU thresholds can be changed via the overlap_thresholds argument. The bg_class argument controls which label strings are ignored when building segments (defaults to ("background",); set to ("no_action",) for this dataset).


anomaly_detection_metrics(y_true, y_pred)

Binary metrics for success/failure detection. Uses the success flag from ActionRecognitionDataset (inverted: success=0 → anomaly label 1).

from metrics import anomaly_detection_metrics
from datamodule.ActionRecognitionDataset import ActionRecognitionDataset
dataset = ActionRecognitionDataset(dataset_path=..., type="test")
all_labels, all_preds = [], []
for sample in dataset:
 gt_anomaly = 1 - sample["success"] # 0 = normal, 1 = anomaly
 pred_anomaly = anomaly_model(sample) # → 0 or 1
 all_labels.append(gt_anomaly)
 all_preds.append(pred_anomaly)
results = anomaly_detection_metrics(all_labels, all_preds)
# {'accuracy': 91.0, 'precision': 91.0, 'recall': 91.0, 'f1': 91.0}
Metric Description
accuracy Fraction of correctly classified clips (%)
precision Micro-averaged precision (%)
recall Micro-averaged recall / detection rate (%)
f1 Micro-averaged F1 (%)

Running the built-in demo

python metrics.py

Runs all three functions on synthetic data with realistic noise levels and prints a formatted table for each task.


Dependencies

torch
numpy
Pillow
matplotlib
scikit-learn

Install with:

pip install torch numpy Pillow matplotlib scikit-learn