PTENES
MODULE 5.4 · PRACTICE

🎓 Learning by demonstration

Instead of programming every angle, you show the arm the task a few dozen times using the SO-101 leader, record it, train a neural network, and let the follower repeat it on its own. Here you complete the full cycle with LeRobot: record, publish, train, and evaluate, and learn about policies that understand text instructions.

6
Topics
Advanced
Level
Practice
Type
SO-101
+ camera and GPU
0%
0 of 0 topics read · Section 1 of 6

Detailed content

1

🎓 Learning by demonstration (imitation)

In module 5.3, you made the follower copy the leader in real time. Now the idea is to take it one step further: record these demonstrations and train a neural network that learns the connection “what I see and where my joints are → what the next movement should be.” Once trained, it controls the follower without anyone at the leader. This is called imitation learning.

🌱 New here?

A policy is the program that decides the next action based on what the robot observes. Here, it’s a neural network, not code with if. Imitation means the network learns by copying examples from a person, instead of figuring things out through trial and error (that would be reinforcement learning, which is almost always done in simulation and is covered in 5.5).

DEMONSTRATEyou movethe leader RECORDepisodescamera + joints TRAINneural networkon the GPU EVALUATEarm on its owncount successes did it fail? record more examples of the case it got wrong

How to read this map: the green arrows show one cycle; the glowing block (training) is the only part that needs a GPU. The cyan arrow marks the difference between those who succeed and those who give up: evaluation shows where the policy fails, and the fix is to record more examples of exactly that situation.

✓ Good first task

  • ✓Pick up a foam cube and put it in a shallow box.
  • ✓A lightweight, colorful object that contrasts with the table.
  • ✓Easy to judge success: is it in the box or not?

✗ Save for later

  • ✗Folding fabric, opening a screw-top lid, tight-fitting parts.
  • ✗A transparent, shiny, or heavier object than the gripper can handle.
  • ✗Several different tasks in the same dataset right from the start.

Why learn this

Programming the arm to “pick and place” works until the cube moves 3 cm from its spot. The learned policy looks at the camera at every moment and adjusts its path. That’s how labs train arms today, and the SO-101 with LeRobot brings this method to your desk.

Key concepts

Policy
observation → action
Imitation
learns from examples
Leader / follower
you teach, it copies
Success rate
successes in N attempts
2

⏺️ Record episodes with lerobot-record

Each recorded demonstration is an episode. The command lerobot-record connects the leader, follower, and cameras, and saves three things at each frame: the images, the follower’s current joint positions (the state) and the position the leader commanded (the action). Between episodes, there’s a reset period so you can set up the table.

🌱 New here?

Frame is a recorded moment (at 30 frames per second, one every 33 ms). State is where the arm is; action is where it was commanded to go. The network learns to predict the action from the image and the state. The 6 numbers in each are the SO-101’s joints: base, shoulder, elbow, wrist bend and rotation, gripper.

imagestateaction … 6 joints6 joints6 joints6 joints 6 targets6 targets6 targets6 targets t = 0t + 33 mspick uprelease + instruction: “put the cube in the box” · then: reset time

How to read this map: each column is a frame. The top row shows what the camera saw (the cube gets closer, is picked up, and appears in the box). The rows below show the numbers the network will learn to connect: given the state and image, predict the action. The text instruction applies to the entire episode.

Step-by-step: your first recording

1

Check ports, calibration, and camera

Use the same ports and the same id calibration files as in 5.3. Run lerobot-find-cameras and note the index of the front-facing camera.

2

Keep the scene fixed

Secure the camera (with tape or a mount), keep the lighting constant, and always put the box in the same place. Only the cube’s position changes between episodes.

3

Record 2 test episodes

Run the command below with num_episodes=2, without uploading to the cloud. If everything works, delete the test folder and record for real (50 episodes is a good start).

Goal: record episodes for the task “put the cube in the box” with a front-facing camera. Replace the ports, the id and your Hugging Face username (without the < > symbols).

gravar.sh
# Record demonstrations with the SO-101 pair (Linux; on Windows the port is COM3, COM4...)
HF_USER=<seu_usuario_hf>          # replace with your Hugging Face username
DATASET=cubo-na-caixa-teste        # dataset name

lerobot-record \
  --robot.type=so101_follower --robot.port=/dev/ttyACM0 --robot.id=seguidor \
  --robot.cameras="{ frente: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}}" \
  --teleop.type=so101_leader --teleop.port=/dev/ttyACM1 --teleop.id=lider \
  --dataset.repo_id=${HF_USER}/${DATASET} \
  --dataset.single_task="Put the red cube in the gray box." \
  --dataset.num_episodes=2 \
  --dataset.episode_time_s=20 \
  --dataset.reset_time_s=10 \
  --dataset.push_to_hub=false \
  --display_data=true

How to check

  • ✓A window opens with the camera image and joint graphs that change as you move the leader.
  • ✓The terminal announces the start of each episode and the reset; at the end, it shows the folder in ~/.cache/huggingface/lerobot/.
  • ✗Port or calibration error? Go back to 5.3. Flag names change between versions: check with lerobot-record --help and in the current docs.

✓ Good demonstration

  • ✓Calm movement, done the same way every time.
  • ✓Cube in varied positions, covering the entire area.
  • ✓Starts and ends with the arm at rest.

✗ Ruins the dataset

  • ✗Hesitating, backtracking, trying two different ways.
  • ✗Your hand or arm appearing in front of the camera.
  • ✗Moving the camera or changing the lighting during recording.

Why learn this

The policy can never be better than the demonstrations. If you record calmly and consistently, you train once; if you record in a hurry, you train five times and still don’t understand why it doesn’t work.

Key concepts

Episode
a complete demonstration
State
where the joints are
Action
where they were commanded to go
Reset
set up the table between episodes
3

🗂️ Dataset on the Hugging Face Hub

LeRobot saves each dataset in a standard format: tables with state and action, camera videos, and a metadata file. This same format can be uploaded to the Hugging Face Hub, where you can train on a machine with a GPU (or in Colab) without copying files by hand, and where other people can use your data if you want.

🌱 New here?

O Hugging Face Hub is a free site that hosts models and datasets, similar to a GitHub for AI. The repo_id is the dataset address: username/name. To upload, create an account, generate a write token in settings, and log in once in the terminal.

username/cubo-na-caixa meta/ fps, cameras,tasks, averages data/ parquet tablesstate + action videos/ one MP4per camera same structure on your disk and on the Hub

How to read this map: the name at the top is the repo_id. The tables (middle) are lightweight; the videos (right, in cyan) take up almost all the space. If the dataset is too large, reduce the resolution or number of cameras, not the number of episodes.

Goal: log in, check a recorded episode, and upload the dataset to the Hub as private. Run this in the same Python environment where you installed LeRobot.

conferir.sh
hf auth login                       # paste the write token (once per machine)
lerobot-dataset-viz --repo-id <seu_usuario_hf>/<dataset> --episode-index 0
subir_dataset.py
# Open the local dataset, show its size, and upload it to the Hub as private.
import sys
from lerobot.datasets.lerobot_dataset import LeRobotDataset

repo_id = sys.argv[1]                    # e.g.: <your_hf_username>/<dataset>
ds = LeRobotDataset(repo_id)             # reads from ~/.cache/huggingface/lerobot/
print("episodes:", ds.num_episodes, "| quadros:", ds.num_frames, "| fps:", ds.fps)
print("colunas:", list(ds.features))
ds.push_to_hub(private=True)             # private: only you can see it
print("uploaded: https://huggingface.co/datasets/" + repo_id)

How to check

  • ✓The viewer shows the video for episode 0 with the curves for all 6 joints synchronized.
  • ✓python subir_dataset.py <your_hf_username>/<dataset> prints the number of episodes (what you recorded) and the columns, including state, action, and the "front" camera.
  • ✓The dataset page opens in your logged-in browser and appears as private.

💡 Privacy

The camera records whatever is in the background: faces, your home, papers on the table. In a school setting, keep the dataset private and frame only the workbench. Make it public only after reviewing it episode by episode.

Why learn this

Separating "where you record" from "where you train" solves the problem for people without a GPU at home: record on the laptop next to the arm, then train in Colab or in the lab. A well-documented dataset also becomes lesson material for the whole class.

Key concepts

Hub
GitHub for models and data
repo_id
username/name
Token
Hub write password
Private
the default at school
4

🏋️ Train ACT with lerobot-train

A ACT (Action Chunking with Transformers) is the recommended policy to start with: it is small, trains quickly, and works well with 50 episodes of one task. The trick is in the name: instead of predicting one movement at a time, it predicts a chunk of several consecutive movements, which makes the arm smoother and less hesitant.

front camera wrist camera state (6) ACTtransformer chunk of future actions executesdiscards observes again and predicts the next chunk

How to read this map: on the left is everything the network sees at a given moment. On the right, the bars represent future movements: the solid ones are executed, while the outlined ones are discarded because by then the camera will have new information. The cyan arrow closes the loop, as in the sense-think-act cycle in 1.1.

🌱 New here?

Training means adjusting millions of network parameters until it makes few errors when predicting the recorded actions. Each adjustment uses a batch of frames (batch) and counts as one step (step). From time to time, training saves a checkpoint: a copy of the network at that point, which you can test or resume training from.

Goal: train an ACT on your dataset on a machine with an NVIDIA GPU. On a Mac with an Apple chip, replace cuda with mps; without a GPU, use Colab (there’s a ready-to-use notebook in the LeRobot documentation).

treinar.sh
# Train the ACT policy (check the flags with: lerobot-train --help)
HF_USER=<seu_usuario_hf>
DATASET=<dataset>

lerobot-train \
  --dataset.repo_id=${HF_USER}/${DATASET} \
  --policy.type=act \
  --policy.device=cuda \
  --output_dir=outputs/train/act-${DATASET} \
  --job_name=act-${DATASET} \
  --batch_size=8 \
  --steps=20000 \
  --wandb.enable=false \
  --policy.push_to_hub=false

How to check

  • ✓The terminal shows lines with the current step and the loss (the error), which should drop quickly at first, then more slowly.
  • ✓Folders appear in outputs/train/…/checkpoints/; the latest one is in last/pretrained_model.
  • ✗"CUDA out of memory"? Reduce --batch_size (4 or 2). Training can take anywhere from minutes to many hours, depending on the GPU and the number of steps.

💡 A low loss doesn’t mean success

Loss measures how well the network copies the recorded demonstrations, not how well it performs the task in the real world. A network can memorize the 50 episodes and fail when the cube appears in a new location. The only number that matters is the success rate on the arm, which you’ll measure in the next topic.

Why learn this

Knowing how to read training results helps you avoid wasting GPU time: you learn when to stop after the loss levels off, test intermediate checkpoints, and tell the difference between "not enough data" and "not enough training."

Key concepts

ACT
predicts chunks of actions
Loss
error on the examples
Checkpoint
network saved at a point in training
Batch
frames per step
5

🧪 Evaluate the policy on the real arm

Evaluation means letting the policy control the follower, without the leader, and counting how many times it succeeds. In the current version of LeRobot, you do this with lerobot-rollout; earlier versions used lerobot-record itself with the specified policy. Check which one applies to your installation with --help.

Safety before the first test

A newly trained policy can make sudden, unexpected movements. The SO-101 servos are small, but they can trap a finger or knock objects over. Keep your hand on the follower’s power switch, clear the table, keep everyone out of the arm’s range, and make the first test short.

Goal: run the trained policy on the follower for 30 seconds, using the same camera and the same instruction as in the recording.

avaliar.sh
# Run the policy on the real arm (check the flags with: lerobot-rollout --help)
POLITICA=outputs/train/act-<dataset>/checkpoints/last/pretrained_model

lerobot-rollout \
  --strategy.type=base \
  --policy.path=${POLITICA} \
  --robot.type=so101_follower --robot.port=/dev/ttyACM0 --robot.id=seguidor \
  --robot.cameras="{ frente: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}}" \
  --task="Put the red cube in the gray box." \
  --duration=30

How to check

  • ✓The follower moves on its own toward the cube; the leader can remain turned off.
  • ✓After 30 seconds, the command ends and the arm stops.
  • ✗Arm shaking or moving to a fixed corner? Did the camera move since recording, or does the camera name not match the dataset name ("front")?

Evaluation spreadsheet (20 attempts)

Cube positionAttemptsSuccessful attemptsHow it failed
Near the center (as seen in the recording)10recordmissed the grasp, released outside…
At the edges of the recorded area5recordrecord
Outside the recorded area5recordrecord

✓ Honest evaluation

  • ✓Define "success" before you start, and don’t change it afterward.
  • ✓Randomize the cube positions; don’t choose the easy ones.
  • ✓Record video and note the type of failure for each mistake.

✗ Fooling yourself

  • ✗Counting only the attempts you filmed.
  • ✗Pushing the cube "just a little" to help.
  • ✗Drawing a conclusion from 3 attempts.

When a failure pattern appears (for example, "it always misses when the cube is on the left"), record 10 to 20 new episodes in that area and train again. LeRobot also has a mode where you take control with the leader when the policy makes a mistake, and that correction becomes a new episode (--strategy.type=dagger); it’s the most efficient way to improve after the first version.

Why learn this

Without a numerical evaluation, every AI project "almost works." The spreadsheet shows you exactly where you stand, lets you compare versions, and gives you something concrete to present in your final project.

Key concepts

Rollout
policy in control
Distribution
what appeared in the training data
DAgger
correction becomes data
Hands on the source
always have a physical stop
6

🗣️ SmolVLA and pi0: language-based policies

ACT learns a task and ignores text. A VLA (Vision-Language-Action model, introduced in 5.1) also receives the written instruction and can perform different tasks depending on the request: "put the cube in the box" or "put the ball in the box." These models are already pretrained on many robots; you just fine-tune them fine-tune with your episodes.

image "put the ballin the box" state (6) VLASmolVLA, pi0 actions from6 joints ACT receives only images and state: without the cyan box, it’s one task per model

How to read this map: the difference between a VLA and ACT is the cyan box. With the text, the same model chooses which object to pick up. The text doesn’t become code or a list of steps: it directly conditions the joint movements.

PolicyUnderstands textTraining computeWhen to use
ACTisn’tlightweightone task, first project
SmolVLAyesmedium (GPU with plenty of memory)a few tasks with the same arm
pi0 / pi0.5yesheavy (large GPU or cloud)research, varied tasks

Goal: fine-tune SmolVLA from the base model lerobot/smolvla_base using your dataset. First, record episodes with different instructions (for example, half with "cube" and half with "ball").

smolvla.sh
# Install the SmolVLA extra in the same LeRobot environment
pip install "lerobot[smolvla]"

# Fine-tune from the base model (check the current docs for the flags)
lerobot-train \
  --policy.path=lerobot/smolvla_base \
  --dataset.repo_id=<seu_usuario_hf>/<dataset> \
  --policy.device=cuda \
  --output_dir=outputs/train/smolvla-<dataset> \
  --batch_size=16 \
  --steps=20000 \
  --wandb.enable=false \
  --policy.push_to_hub=false

How to check

  • ✓At the start, training downloads the base model weights from the Hub (the first time only), then shows the loss going down, as with ACT.
  • ✓For the evaluation, change only the text for --task and see whether the arm switches objects.
  • ✗Running out of GPU memory? Reduce the batch size or train on Colab. The pi0 / pi0.5 family needs even more; start with ACT or SmolVLA.

💡 See also: simulation data

The INEMA project robotica-real2sim generates episodes in a simulation and exports them in LeRobot format (in the test: 50 episodes with cameras, 4,361 frames, 9.7 MB). Mixing a few real episodes with many simulated ones is the topic of the next module.

Why learn this

The final project (5.6) needs an arm that follows different requests. With ACT, you train one policy per task and the language model chooses which one to call; with a VLA, a single policy receives the request as text. Knowing both approaches lets you choose based on the hardware you have.

Key concepts

VLA
image + text → action
Fine-tuning
base model + your episodes
SmolVLA
LeRobot’s small VLA
pi0 / pi0.5
Larger VLAs

✅ Module summary

✓
Imitation = demonstrate, record, train, evaluate and record again where the policy makes mistakes.
✓
Episode: images + state + action at every frame, along with the task instruction; patience and consistency matter more than quantity.
✓
Hub: record in one place, train in another; private by default.
✓
Start with ACT; a lower loss doesn’t mean success; the success rate over 20 attempts does.
✓
SmolVLA and pi0 receive text and switch tasks based on the request, at the cost of more GPU power.

To go further

Next module

5.5 · Simulate before going real: the SO-101 twin in MuJoCo, real2sim, and the gap between simulation and reality.