Skip to main content
Summary

좋은 시연만으로는 부족하다

Behavior Cloning은 단순하고 강력하다. 사람이 보여 준 상태와 행동 쌍을 모아 state → action 함수를 학습하면 된다. 카메라 이미지와 관절 상태를 넣으면 다음에 엔드 이펙터를 어디로 움직일지 예측하고, 그리퍼를 열지 닫을지 결정한다. 처음 보면 거의 마법처럼 느껴진다. 로봇이 사람의 손길을 흉내 내며 컵 쪽으로 다가가고, 그리퍼를 닫고, 물체를 들어 올린다.

하지만 지난 장에서 보았듯이 이 마법은 생각보다 쉽게 깨진다. 시연 데이터는 대체로 잘된 장면으로 채워져 있다. 사람은 컵을 향해 자연스럽게 접근하고, 적당한 위치에서 그리퍼를 닫고, 무리 없이 들어 올린다. 그런데 학습된 정책은 완벽한 사람이 아니다. 처음에는 컵 중심에서 1cm쯤 벗어날 수 있고, 다음 순간에는 그 오차가 2cm가 된다. 카메라에 보이는 컵의 위치가 시연 때와 조금 달라지고, 로봇팔의 자세도 익숙하지 않은 모양이 된다. 그러면 정책은 자신이 거의 본 적 없는 상태에서 행동을 선택해야 한다.

이 문제가 바로 모방학습의 핵심 난관이다. 모델은 사람이 보여 준 길 위에서는 제법 잘 걷지만, 길 밖으로 한 발짝 벗어난 뒤에는 어떻게 돌아와야 하는지 모른다. 좋은 시연을 많이 모으는 것만으로도 성능은 올라가지만, 실제 로봇에서 안정적으로 쓰기에는 부족할 때가 많다.

더 나은 모방학습은 이 질문에서 출발한다.

"로봇이 실제로 흔들리고, 빗나가고, 헷갈리는 순간까지 학습 데이터에 넣을 수는 없을까?"

이번 장에서는 기본 Behavior Cloning을 실제 로봇 정책에 가깝게 만드는 네 가지 아이디어를 살펴본다. 정책이 방문한 상태에서 전문가 행동을 다시 모으는 DAgger, 시각적 다양성을 늘리는 데이터 증강, 여러 작업을 함께 배우는 멀티태스크 학습, 그리고 자연어 명령에 따라 행동을 바꾸는 언어 조건 행동 학습이다.

더 나은 모방학습을 위한 아이디어

DAgger: 로봇이 헤매는 곳에서 다시 가르치기

DAgger는 Dataset Aggregation의 줄임말이다. 말 그대로 데이터셋을 계속 합쳐 가며 키우는 방법이다. 그런데 아무 데이터나 추가하는 것이 아니다. 핵심은 "현재 정책이 실제로 방문한 상태"를 다시 학습 데이터로 넣는 것이다.

일반 Behavior Cloning에서는 사람이 조종한 궤적만 데이터가 된다. 예를 들어 사람이 컵을 정확히 향해 가는 장면이 100개 있다면, 모델은 그 장면들을 보고 "이런 이미지와 이런 관절 상태에서는 이렇게 움직이면 되는구나"를 배운다. 문제는 모델이 실행 중에 컵을 살짝 지나쳤을 때다. 사람 시연에는 그런 상태가 거의 없으므로, 모델은 거기서 어떻게 복구해야 할지 모른다.

DAgger는 이 빈틈을 정면으로 찌른다. 먼저 기본 Behavior Cloning으로 초기 정책을 만든다. 그다음 이 정책을 실제 환경이나 시뮬레이션에서 실행한다. 그러면 로봇은 당연히 여기저기 실수한다. 컵 왼쪽으로 치우치고, 너무 높게 접근하고, 그리퍼를 조금 일찍 닫으려 한다. 바로 그 상태들을 기록한다. 그리고 전문가에게 묻는다.

"이 상태라면 지금 어떤 행동을 해야 하나요?"

전문가는 그 상태에서 올바른 행동 라벨을 달아 준다. 사람이 직접 조이스틱으로 복구 행동을 보여 줄 수도 있고, 원격 조작으로 다음 행동을 지정할 수도 있다. 또는 안전한 시뮬레이션이라면 기존의 규칙 기반 컨트롤러나 계획기가 전문가 역할을 할 수도 있다. 이렇게 새로 얻은 데이터를 기존 시연 데이터에 합치고, 정책을 다시 학습한다. 이 과정을 반복하면 데이터셋에는 점점 "잘된 길"뿐 아니라 "길을 벗어난 뒤 돌아오는 방법"도 쌓인다.

DAgger의 흐름은 다음처럼 정리할 수 있다.

  1. 사람 시연 데이터로 초기 정책을 학습한다.

  2. 현재 정책을 환경에서 실행해 로봇이 실제로 방문하는 상태를 기록한다.

  3. 기록된 상태마다 전문가가 올바른 행동을 라벨링한다.

  4. 새 데이터를 기존 데이터셋에 합친다.

  5. 합쳐진 데이터셋으로 정책을 다시 학습하고 이 과정을 반복한다.

여기서 중요한 점은 "정책이 낸 행동"과 "전문가가 알려 준 행동"을 구분하는 것이다. 로봇이 실제로는 잘못된 방향으로 움직였더라도, 학습 라벨은 그 상태에서 복구하기 위한 올바른 행동이어야 한다. 즉 DAgger 데이터는 단순한 실행 로그가 아니다. 현재 정책이 만든 어려운 문제를 전문가가 다시 풀어 준 기록이다.

간단한 의사코드로 쓰면 다음과 같다.

D = load_human_demonstrations()
policy = train_behavior_cloning(D)

for round in range(num_dagger_rounds):
    visited_states = []

    for episode in range(num_episodes):
        state = env.reset()

        while not done:
            action = policy.predict(state)
            next_state, done, info = safe_step(env, action)
            visited_states.append(state)
            state = next_state

    labeled_data = []
    for state in visited_states:
        expert_action = ask_expert(state)
        labeled_data.append((state, expert_action))

    D = D + labeled_data
    policy = train_behavior_cloning(D)

실제 로봇에서는 이 과정을 그대로 적용하면 위험할 수 있다. 초기 정책은 아직 서툴기 때문에 로봇팔이 물체를 밀어 버리거나, 테이블에 가까이 내려가거나, 예상하지 못한 방향으로 움직일 수 있다. 그래서 DAgger를 로봇에 적용할 때는 안전한 실행 장치가 필요하다. 행동 속도를 낮추고, 작업 공간을 제한하고, 충돌 위험이 있으면 즉시 멈추는 안전 필터를 둔다. 사람이 언제든 개입할 수 있는 비상 정지 버튼도 있어야 한다.

현장에서 자주 쓰는 방식은 "사람 개입 기반 DAgger"다. 로봇은 기본적으로 현재 정책대로 움직인다. 사람이 보기에는 괜찮으면 그대로 둔다. 그런데 로봇이 위험한 방향으로 가거나 실패할 것 같으면 사람이 조종권을 가져와 올바른 행동을 수행한다. 이때 개입 직전 상태와 사람이 수행한 회복 행동을 데이터로 저장한다. 이렇게 하면 모든 상태에 전문가 라벨을 다는 수고를 줄이면서도, 정책이 약한 구간을 집중적으로 보강할 수 있다.

{
  "episode_id": "dagger_0031",
  "source": "human_intervention",
  "state": {
    "image": "images/0031_012.png",
    "joint_positions": [0.1, -0.7, 1.2, -1.0, 0.3, 0.2],
    "ee_pose": [0.42, -0.11, 0.18, 0.0, 3.14, 0.0]
  },
  "policy_action": [0.03, -0.02, -0.01, 0.0],
  "expert_action": [-0.01, 0.04, 0.02, 0.0],
  "reason": "approach_offset_too_large"
}

이런 데이터가 쌓이면 모델은 단지 "컵으로 가는 법"이 아니라 "컵을 지나쳤을 때 다시 돌아오는 법"까지 배운다. 로봇에게는 이 차이가 매우 크다. 실제 세계에서 완벽한 첫 행동은 드물다. 좋은 정책은 실수하지 않는 정책이 아니라, 작은 실수를 큰 실패로 키우지 않는 정책이다.

데이터 증강: 같은 장면을 여러 세계로 만들기

모방학습의 또 다른 약점은 데이터가 쉽게 좁아진다는 것이다. 같은 책상, 같은 조명, 같은 컵, 같은 카메라 각도에서 수집한 1,000개의 시연은 생각보다 다양하지 않다. 로봇은 그 환경에서는 잘 움직이지만, 조명이 조금 어두워지거나 컵 색깔이 바뀌면 갑자기 성능이 떨어질 수 있다.

데이터 증강은 기존 데이터를 변형해 더 다양한 상황처럼 보이게 만드는 방법이다. 이미지 분류나 객체 검출에서 많이 쓰는 기법이지만, 로봇 모방학습에서는 조금 더 조심해야 한다. 이미지만 바꾼다고 항상 같은 행동 라벨을 쓸 수 있는 것은 아니기 때문이다.

예를 들어 이미지 밝기를 조금 바꾸거나 색감을 조정하는 것은 대체로 안전하다. 컵이 같은 위치에 있고 로봇 상태도 같다면, 다음 행동은 그대로여도 된다. 반면 이미지를 왼쪽으로 크게 이동시키면 문제가 생긴다. 이미지상 컵 위치가 바뀌었는데 행동 라벨은 여전히 원래 방향을 가리키기 때문이다. 모델 입장에서는 "컵이 왼쪽에 보여도 오른쪽으로 가라"는 이상한 신호를 배우게 된다.

따라서 로봇 데이터 증강은 두 가지로 나누어 생각해야 한다. 첫째는 라벨을 그대로 유지해도 되는 증강이다. 둘째는 이미지나 상태를 바꾸면 행동 라벨도 함께 바꿔야 하는 증강이다.

라벨을 그대로 유지하기 쉬운 증강에는 밝기, 대비, 색온도, 약한 노이즈, 약한 블러가 있다. 이런 변화는 카메라가 보는 분위기를 바꾸지만, 물체의 실제 위치를 크게 바꾸지는 않는다. 로봇이 다양한 조명과 카메라 품질에 덜 민감해지도록 도와준다.

위치나 크기를 바꾸는 증강은 더 신중해야 한다. 이미지를 자르거나 회전하거나 물체 위치를 합성으로 바꾸면, 정책의 출력이 어떤 좌표계를 기준으로 되어 있는지 확인해야 한다. 행동이 "엔드 이펙터를 카메라 화면에서 물체 중심 방향으로 이동"처럼 이미지와 직접 연결되어 있다면, 라벨도 함께 변환해야 한다. 행동이 "로봇 베이스 좌표계에서 x 방향으로 2cm 이동"처럼 3D 좌표 기준이라면, 이미지 변형과 행동 라벨의 관계가 더 복잡해진다.

실전에서 유용한 증강은 다음과 같다.

  • 이미지 밝기와 대비를 바꾸어 조명 변화에 강하게 만든다.

  • 색상과 채도를 바꾸어 물체 색이나 카메라 색감 차이에 덜 흔들리게 만든다.

  • 약한 가우시안 노이즈나 모션 블러를 넣어 센서 노이즈와 흔들림에 대비한다.

  • 배경을 바꾸거나 책상 위 방해물을 추가해 특정 배경을 외우지 않게 만든다.

  • 물체의 종류, 크기, 위치를 바꾸어 다양한 조작 상황을 경험하게 한다.

특히 로봇에서는 "배경 외우기"가 생각보다 자주 발생한다. 모델이 컵을 보고 집는다고 생각했는데, 실제로는 컵 옆에 있던 파란 매트나 책상 모서리를 단서로 삼고 있을 수 있다. 훈련 때 항상 빨간 컵이 같은 위치에 있었다면, 모델은 빨간 컵의 형태보다 화면 중앙의 붉은 얼룩을 더 믿을 수도 있다. 배경과 물체 배치를 다양하게 바꾸면 이런 지름길 학습을 줄일 수 있다.

간단한 이미지 증강 파이프라인은 다음처럼 구성할 수 있다.

image = load_image(sample.image_path)

image = random_brightness(image, min_value=0.7, max_value=1.3)
image = random_contrast(image, min_value=0.8, max_value=1.2)
image = random_color_jitter(image)
image = random_gaussian_noise(image, sigma=0.01)
image = random_blur(image, probability=0.2)

action = sample.action  # 위 증강들은 물체 위치를 크게 바꾸지 않으므로 라벨 유지

하지만 모든 증강이 좋은 것은 아니다. 너무 강한 증강은 오히려 학습을 망친다. 실제 카메라에서 절대 나오지 않을 만큼 색을 뒤틀거나, 물체가 알아볼 수 없을 정도로 흐리게 만들면 모델은 중요한 정보를 잃는다. 증강은 현실을 넓혀야지, 현실과 상관없는 세계를 만들어서는 안 된다.

좋은 기준은 간단하다. 사람이 증강된 이미지를 보고도 "이 상황에서는 같은 행동을 해도 되겠다"고 판단할 수 있어야 한다. 사람이 보기에도 행동이 달라져야 할 것 같다면, 라벨을 함께 바꾸거나 그 증강은 피하는 편이 안전하다.

물체와 환경을 바꾸는 증강

이미지 픽셀을 바꾸는 것보다 더 강력한 증강은 실제 수집 환경 자체를 다양하게 만드는 것이다. 컵 하나로만 학습한 로봇은 컵 하나에 익숙해진다. 컵, 병, 작은 상자, 스펀지 블록, 손잡이 달린 머그컵을 함께 보여 주면 로봇은 "물체를 향해 접근하고, 잡기 좋은 위치를 찾고, 들어 올리는" 더 일반적인 패턴을 배우기 시작한다.

이때 중요한 것은 무작정 물체를 늘리는 것이 아니다. 작업의 핵심 구조는 유지하되, 겉모습을 다양하게 만들어야 한다. 예를 들어 집기 작업이라면 물체마다 모양은 달라도 다음과 같은 공통 흐름이 있다. 물체를 인식하고, 접근 방향을 정하고, 충돌하지 않게 가까이 가고, 그리퍼를 닫고, 들어 올린다. 데이터가 이 공통 흐름을 반복해서 보여 주면 정책은 특정 컵 하나가 아니라 "집을 수 있는 물체"라는 더 넓은 개념을 익힌다.

장면 다양화는 실제 로봇보다 시뮬레이션에서 더 쉽게 할 수 있다. 시뮬레이션에서는 조명 방향, 마찰계수, 물체 질량, 카메라 위치, 배경 텍스처를 빠르게 바꿀 수 있다. 이런 방법은 뒤에서 Sim2Real을 다룰 때 다시 등장한다. 지금은 핵심만 기억하면 된다. 모방학습 정책이 현실에서 버티려면, 학습 데이터 안에 현실의 변덕이 어느 정도 들어 있어야 한다.

로봇 데이터셋을 만들 때는 다음과 같은 변화를 의도적으로 넣는 것이 좋다.

  • 같은 작업을 여러 조명 조건에서 기록한다.

  • 물체의 색상, 재질, 크기, 무게를 바꾸어 기록한다.

  • 카메라 각도와 로봇 시작 자세를 조금씩 바꾸어 기록한다.

  • 목표 위치를 고정하지 말고 테이블 위 여러 지점으로 바꾼다.

  • 성공 시연뿐 아니라 실패 직전 상태와 회복 시연도 함께 기록한다.

이렇게 보면 데이터 증강은 단지 코드를 몇 줄 추가하는 기술이 아니다. 좋은 로봇 데이터셋을 설계하는 태도에 가깝다. "모델이 나중에 어떤 상황에서 당황할까?"를 미리 상상하고, 그 상황을 데이터 안에 넣어 주는 과정이다.

멀티태스크 학습: 여러 일을 배우며 공통 감각 만들기

하나의 작업만 배운 정책은 그 작업에는 빠르게 적응할 수 있다. 예를 들어 "빨간 컵을 집어 오른쪽에 놓기" 데이터만 충분히 모으면, 그 작업에 특화된 정책을 만들 수 있다. 하지만 실제 로봇 에이전트는 하나의 일만 하지 않는다. 컵을 집고, 병을 옮기고, 블록을 밀고, 서랍 손잡이를 잡고, 버튼을 누를 수 있어야 한다.

멀티태스크 학습은 여러 작업 데이터를 하나의 정책 또는 하나의 모델 구조로 함께 학습하는 방법이다. 처음에는 어려워 보인다. 서로 다른 작업을 한 모델에 넣으면 헷갈리지 않을까? 실제로 잘못 설계하면 헷갈린다. 하지만 잘 설계하면 오히려 더 강해진다. 여러 작업에는 공통 조작 패턴이 있기 때문이다.

컵을 집는 일과 병을 집는 일은 다르지만, 둘 다 물체로 접근하고 그리퍼를 정렬하고 닫는 과정이 필요하다. 블록을 미는 일과 버튼을 누르는 일은 다르지만, 둘 다 목표 지점까지 엔드 이펙터를 부드럽게 이동해야 한다. 놓기 작업과 정렬 작업도 "목표 위치 근처에서 속도를 줄이고 자세를 맞추는" 공통 감각을 공유한다.

멀티태스크 정책은 이런 공통 패턴을 하나의 표현으로 배운다. 카메라 이미지에서 물체의 위치를 읽는 능력, 로봇팔이 목표에 가까워지는 감각, 그리퍼가 물체와 접촉할 때의 상태 변화 같은 것들이 여러 작업을 통해 강화된다.

기본 데이터 포맷은 다음처럼 확장할 수 있다.

{
  "episode_id": "multi_0142",
  "task": "pick_and_place",
  "instruction": "파란 블록을 왼쪽 바구니에 넣어줘",
  "phase": "approach",
  "observation": {
    "rgb": "images/0142_008.png",
    "depth": "depth/0142_008.npy",
    "joint_positions": [0.0, -0.8, 1.1, -1.2, 0.4, 0.1],
    "gripper_width": 0.07
  },
  "action": {
    "delta_ee_pose": [0.01, 0.02, -0.005, 0.0, 0.0, 0.0],
    "gripper_command": "open"
  },
  "success": true
}

여기서 task는 작업 종류를 알려 주고, instruction은 자연어 목표를 담는다. phase는 현재 행동이 접근, 집기, 들어 올리기, 이동, 놓기 중 어디에 해당하는지 알려 줄 수 있다. 이런 추가 정보는 모델이 같은 이미지에서도 "지금은 접근해야 하는가, 아니면 그리퍼를 닫아야 하는가"를 구분하는 데 도움을 준다.

멀티태스크 학습에서는 데이터 균형이 중요하다. 컵 집기 데이터가 10만 개이고 버튼 누르기 데이터가 1천 개라면, 모델은 대부분의 시간을 컵 집기에 맞춰 학습한다. 그러면 버튼 누르기 성능은 좋아지기 어렵다. 작업별 샘플 수가 다를 때는 학습 배치를 구성할 때 작업을 균형 있게 뽑거나, 부족한 작업에 더 큰 가중치를 줄 수 있다.

모델 구조도 몇 가지 선택지가 있다. 가장 단순한 방식은 모든 작업이 같은 입력과 같은 출력 형식을 쓰게 만드는 것이다. 예를 들어 모든 작업을 "엔드 이펙터의 작은 이동량과 그리퍼 명령 예측"으로 통일하면 하나의 정책으로 여러 작업을 처리할 수 있다. 이 방식은 깔끔하지만, 작업마다 필요한 행동 형태가 너무 다르면 한계가 있다.

다른 방식은 공유 인코더와 작업별 헤드를 두는 것이다. 이미지와 로봇 상태를 읽는 앞부분은 공유하고, 마지막 행동 출력 부분만 작업별로 나눈다. 컵 집기 헤드, 밀기 헤드, 버튼 누르기 헤드가 따로 있는 식이다. 이렇게 하면 공통 시각 표현은 함께 배우면서도, 각 작업의 특수한 행동은 분리할 수 있다.

vision_feature = vision_encoder(rgb, depth)
robot_feature = robot_encoder(joint_positions, gripper_width)
shared_feature = fuse(vision_feature, robot_feature)

if task == "pick":
    action = pick_head(shared_feature)
elif task == "push":
    action = push_head(shared_feature)
elif task == "place":
    action = place_head(shared_feature)

더 발전된 구조에서는 task 대신 자연어 명령을 넣는다. 그러면 작업별 헤드를 사람이 직접 나누지 않아도, 모델이 명령을 조건으로 행동을 선택할 수 있다. 이것이 다음 절에서 다룰 언어 조건 행동 학습으로 이어진다.

언어 조건 행동 학습: 같은 장면에서 다른 행동 선택하기

로봇이 진짜 에이전트처럼 보이기 시작하는 순간은 같은 장면을 보고도 명령에 따라 다르게 행동할 때다. 테이블 위에 빨간 컵과 파란 컵이 함께 있다. 사람이 "빨간 컵을 집어"라고 하면 빨간 컵으로 가야 하고, "파란 컵을 집어"라고 하면 파란 컵으로 가야 한다. 카메라 이미지는 거의 같지만 행동은 달라진다.

기본 Behavior Cloning은 보통 policy(state) → action 형태다. 상태가 같으면 행동도 하나로 정해진다. 하지만 자연어 명령 로봇에서는 이것만으로 부족하다. 정책은 상태뿐 아니라 목표도 알아야 한다. 그래서 언어 조건 정책은 다음과 같은 형태를 갖는다.

policy(state, command) → action

여기서 command는 "빨간 컵을 집어 오른쪽에 놓아줘" 같은 자연어 문장이다. 모델은 이미지, 로봇 상태, 명령 문장을 함께 보고 다음 행동을 예측한다. 같은 이미지라도 명령이 달라지면 주목해야 할 물체와 목표 위치가 바뀐다.

구조는 크게 세 부분으로 나눌 수 있다. 첫째, 비전 인코더가 카메라 이미지에서 물체와 장면 정보를 뽑는다. 둘째, 로봇 상태 인코더가 관절 위치, 엔드 이펙터 자세, 그리퍼 상태를 읽는다. 셋째, 언어 인코더가 명령 문장을 벡터로 바꾼다. 이렇게 얻은 특징들을 결합한 뒤 행동을 예측한다.

image_feature = vision_encoder(rgb)
state_feature = robot_state_encoder(joint_state, ee_pose, gripper_state)
text_feature = language_encoder(command)

feature = concatenate(image_feature, state_feature, text_feature)
action = action_decoder(feature)

언어 조건 학습에서 가장 중요한 것은 "말과 행동의 연결"이다. 단순히 모든 데이터에 같은 문장을 붙여서는 효과가 없다. 모델은 명령이 달라질 때 행동도 어떻게 달라지는지 봐야 한다. 예를 들어 같은 테이블 장면에서 빨간 컵을 집는 데이터, 파란 컵을 집는 데이터, 컵을 집지 않고 상자를 미는 데이터가 함께 있어야 한다. 그래야 언어가 장식이 아니라 실제 조건으로 작동한다.

명령 문장도 다양해야 한다. 사람이 항상 같은 방식으로 말하지 않기 때문이다. "빨간 컵을 집어", "빨간색 컵을 들어 줘", "왼쪽에 있는 빨간 컵 잡아 줘"는 표현은 다르지만 비슷한 목표를 가리킨다. 데이터에 이런 표현 변화를 넣으면 정책은 특정 문장을 외우는 대신 의미를 더 잘 활용할 수 있다.

언어 조건 데이터에는 다음과 같은 요소가 함께 들어가면 좋다.

  • 자연어 명령과 작업 종류를 함께 저장한다.

  • 명령이 가리키는 대상 물체와 목표 위치를 메타데이터로 기록한다.

  • 같은 장면에서 서로 다른 명령을 수행하는 데이터를 포함한다.

  • 같은 목표를 여러 표현으로 바꾼 문장을 함께 넣는다.

  • 애매한 명령이나 수행 불가능한 명령에 대한 거절·질문 데이터를 포함한다.

마지막 항목은 특히 중요하다. 로봇은 물리 세계에서 움직인다. 명령이 애매하거나 위험하면 무조건 행동해서는 안 된다. "저거 치워"라고 했는데 테이블 위에 컵, 칼, 노트북이 함께 있다면 무엇을 치워야 할지 물어봐야 한다. "사람 손 근처의 칼을 집어" 같은 명령은 안전 정책에 따라 거절하거나 사람 확인을 요구해야 한다.

언어 조건 정책은 LLM 로봇 에이전트와도 잘 연결된다. 뒤에서 다룰 LLM 기반 에이전트는 자연어 명령을 작업 순서로 나누고, 로봇 스킬을 호출한다. 이때 각 스킬 내부의 저수준 행동을 언어 조건 정책이 처리할 수 있다. 예를 들어 상위 LLM이 pick(object="red cup")이라는 스킬을 호출하면, 하위 정책은 "빨간 컵을 집어"라는 조건을 받아 실제 접근과 집기 행동을 수행한다. 상위 계획은 언어와 논리를 담당하고, 하위 정책은 시각과 조작을 담당하는 구조다.

언어를 바로 행동에 넣을 때의 주의점

언어 조건 학습은 매력적이지만, 모든 것을 한 번에 해결해 주지는 않는다. 가장 큰 문제는 접지, 즉 grounding이다. 모델이 "빨간 컵"이라는 말을 실제 이미지 속 빨간 컵과 연결해야 한다. 문장 벡터와 이미지 벡터를 단순히 붙이는 것만으로는 부족할 수 있다. 물체가 여러 개 있고 색과 위치가 복잡하면 모델은 엉뚱한 대상을 고를 수 있다.

이를 줄이기 위해 객체 검출이나 세그멘테이션 결과를 함께 사용할 수 있다. 먼저 비전 모듈이 물체 후보를 찾고, 각 후보의 색, 위치, 종류를 추정한다. 언어 명령에서 나온 대상 표현과 후보 물체를 매칭한 뒤, 정책에는 선택된 물체의 위치나 마스크를 함께 제공한다. 이렇게 하면 언어 이해와 물체 조작 사이의 다리가 더 튼튼해진다.

예를 들어 "오른쪽에 있는 파란 컵을 집어"라는 명령이 들어오면 시스템은 다음처럼 처리할 수 있다.

명령: 오른쪽에 있는 파란 컵을 집어
대상 조건: color=blue, category=cup, spatial=right
비전 후보:
  A: red cup, left
  B: blue cup, right
  C: blue bottle, center
선택 대상: B
정책 조건: target_mask=B, command=원문 명령

이 구조에서는 언어 조건 정책이 모든 것을 혼자 알아서 추론하지 않아도 된다. 상위 인식 모듈이 대상 후보를 좁혀 주고, 정책은 그 대상을 어떻게 잡을지에 집중한다. 실제 로봇 시스템에서는 이런 분업이 안정성을 높인다.

또 하나의 주의점은 언어가 행동을 과도하게 지배하지 않게 하는 것이다. 명령이 "빠르게 집어"라고 해도 안전 속도를 넘으면 안 된다. "테이블 아래로 내려가"라는 명령이 들어와도 작업 공간 제한을 벗어나면 안 된다. 언어 조건 정책의 출력은 항상 안전 필터, 충돌 검사, 속도 제한을 통과해야 한다. 자연어는 목표를 말해 줄 수 있지만, 물리적 안전 규칙을 무시할 권한은 없다.

네 가지 아이디어를 하나의 파이프라인으로 묶기

DAgger, 데이터 증강, 멀티태스크 학습, 언어 조건 학습은 서로 따로 노는 기법이 아니다. 실제 프로젝트에서는 이들을 단계적으로 결합하는 것이 좋다.

먼저 작은 범위의 작업을 정한다. 예를 들어 테이블 위 물체 집기와 놓기다. 사람이 기본 시연을 수집하고, Behavior Cloning으로 첫 정책을 만든다. 이때 이미지 밝기, 노이즈, 색상 변화 같은 안전한 데이터 증강을 넣어 시각적 변화에 조금 더 강하게 만든다.

그다음 물체 종류와 목표 위치를 늘린다. 컵 하나에서 블록, 병, 작은 상자로 확장하고, 오른쪽 놓기뿐 아니라 왼쪽 바구니, 중앙 트레이, 지정된 영역으로 놓는 작업을 추가한다. 이 데이터들을 멀티태스크 형태로 묶어 공통 조작 패턴을 배우게 한다.

이후 자연어 명령을 데이터에 붙인다. 처음에는 단순한 명령이면 충분하다. "빨간 컵 집기", "파란 블록 왼쪽에 놓기"처럼 대상과 목표가 분명한 문장을 사용한다. 점차 표현을 다양하게 만들고, 같은 장면에서 다른 명령을 수행하는 데이터를 넣는다. 그러면 정책은 상태만 보는 것이 아니라 목표를 함께 보는 방향으로 발전한다.

마지막으로 DAgger를 사용해 실제 실행 중 약한 부분을 보강한다. 학습된 정책을 안전한 환경에서 실행하고, 실패 직전 상태나 사람 개입 상태를 수집한다. 그 상태에서 전문가 행동을 라벨링해 데이터셋에 추가하고 다시 학습한다. 이 루프가 반복될수록 정책은 실전에서 자주 만나는 흔들림에 강해진다.

전체 흐름은 다음처럼 볼 수 있다.

사람 시연 수집
    ↓
기본 Behavior Cloning 학습
    ↓
이미지·환경 데이터 증강
    ↓
여러 물체와 여러 작업으로 멀티태스크 확장
    ↓
자연어 명령을 조건으로 추가
    ↓
안전한 실행 중 실패·개입 상태 수집
    ↓
DAgger로 데이터셋 보강 후 재학습

이 파이프라인은 한 번에 완성하려고 하면 부담스럽다. 처음부터 범용 로봇 정책을 만들겠다고 달려들면 데이터 설계도, 모델 구조도, 평가 기준도 금방 복잡해진다. 좋은 방식은 작은 성공 범위를 정하고 한 단계씩 넓히는 것이다. 컵 하나를 안정적으로 집는 정책에서 시작해, 여러 물체를 집고, 여러 위치에 놓고, 명령에 따라 대상을 바꾸고, 실패하면 회복하는 식으로 키워 나간다.

무엇을 측정해야 좋아졌다고 말할 수 있을까

기법을 추가하면 모델은 복잡해진다. 복잡해졌다고 반드시 좋아진 것은 아니다. 더 나은 모방학습을 만들려면 평가도 함께 좋아져야 한다.

단순히 학습 손실이 낮아졌다는 것만으로는 부족하다. 행동 예측 오차가 작아도 실제 로봇에서 실패할 수 있다. 예를 들어 사람이 한 행동과 모델 행동이 평균적으로 1cm밖에 차이 나지 않아도, 그 1cm가 그리퍼를 물체 옆으로 빗나가게 만들 수 있다. 로봇에서는 작은 숫자 차이가 큰 물리적 차이로 이어진다.

따라서 정책 평가는 실제 작업 결과 중심으로 해야 한다. 성공률은 가장 기본적인 지표다. 100번 시도했을 때 몇 번 물체를 정확히 집고 목표 위치에 놓았는지 본다. 여기에 실패 원인을 함께 기록하면 더 좋다. 접근 실패인지, grasp 실패인지, lift 실패인지, place 실패인지 구분해야 다음 데이터 수집 방향이 보인다.

모방학습 개선을 평가할 때 유용한 지표는 다음과 같다.

  • 작업 성공률: 전체 시도 중 목표를 완수한 비율이다.

  • 회복 성공률: 일부러 시작 자세나 물체 위치를 흔들었을 때 다시 정상 궤도로 돌아오는 비율이다.

  • 사람 개입 횟수: 안전 실행 중 사람이 조종권을 가져와야 했던 횟수다.

  • 실패 단계 분포: 접근, 집기, 들어 올리기, 놓기 중 어디서 많이 실패하는지 기록한다.

  • 장면 일반화 성능: 새로운 물체, 새로운 배경, 새로운 조명에서의 성공률이다.

특히 DAgger를 적용했다면 사람 개입 횟수가 줄어드는지 보는 것이 중요하다. 데이터 증강을 적용했다면 조명과 배경을 바꿔도 성능이 유지되는지 봐야 한다. 멀티태스크 학습을 적용했다면 특정 작업 성능만 오른 것이 아니라 여러 작업에서 균형 있게 좋아졌는지 확인해야 한다. 언어 조건 학습을 적용했다면 같은 장면에서 명령만 바꾸어도 대상과 행동이 정확히 달라지는지 시험해야 한다.

검증 데이터도 조심해서 나누어야 한다. 같은 에피소드에서 나온 연속 프레임을 일부는 학습, 일부는 검증에 넣으면 검증이 너무 쉬워진다. 바로 직전 프레임과 거의 같은 장면을 맞히는 것이기 때문이다. 가능하면 에피소드 단위, 물체 단위, 장면 단위로 나누는 편이 좋다. 예를 들어 학습에는 빨간 컵과 파란 컵을 넣고, 검증에는 초록 컵이나 다른 모양의 컵을 넣으면 일반화 능력을 더 제대로 볼 수 있다.

실전 설계 예: 집기 정책을 키워 가기

작은 로봇팔 프로젝트를 예로 들어 보자. 목표는 자연어 명령을 받아 테이블 위 물체를 집는 정책을 만드는 것이다. 처음부터 모든 기능을 넣지 않는다. 먼저 사람이 조이스틱으로 빨간 컵을 집는 시연 100개를 수집한다. 카메라 이미지, 깊이 정보, 관절 상태, 엔드 이펙터 자세, 그리퍼 명령을 저장한다. 이 데이터로 기본 Behavior Cloning 정책을 학습한다.

첫 정책은 시연과 비슷한 환경에서는 어느 정도 작동한다. 하지만 컵 위치가 조금만 달라져도 접근이 흔들린다. 여기서 이미지 밝기와 색상 증강을 추가하고, 컵 위치를 여러 곳으로 바꾸어 시연을 더 모은다. 정책은 조명과 위치 변화에 조금 더 강해진다.

다음으로 물체를 늘린다. 빨간 컵뿐 아니라 파란 컵, 작은 상자, 원통형 블록을 추가한다. 작업 이름을 pick으로 통일하되, 물체 종류와 위치를 메타데이터로 저장한다. 모델은 여러 물체에서 공통 집기 패턴을 배운다.

이제 자연어 명령을 붙인다. "빨간 컵을 집어", "파란 컵을 들어", "상자를 잡아" 같은 문장을 각 에피소드에 연결한다. 같은 장면에 물체 두 개를 두고, 명령에 따라 다른 물체를 집는 데이터도 수집한다. 정책 입력은 image + robot_state에서 image + robot_state + command로 바뀐다.

마지막으로 안전한 DAgger 루프를 돈다. 정책을 느린 속도로 실행하고, 사람이 옆에서 지켜본다. 로봇이 물체 옆으로 빗나가면 사람이 개입해 올바른 방향으로 수정한다. 그 개입 데이터를 저장한다. 다시 학습한다. 몇 라운드가 지나면 정책은 처음보다 덜 흔들리고, 흔들려도 더 자주 복구한다.

이 과정에서 로봇은 갑자기 천재가 되지 않는다. 그러나 중요한 변화가 생긴다. 처음에는 깨끗한 시연 경로만 따라가던 로봇이, 점차 실제 실행 중 생기는 어긋남을 견디기 시작한다. 이것이 실용적인 모방학습의 방향이다.

모방학습의 다음 단계

모방학습은 로봇에게 좋은 출발점을 준다. 사람의 행동을 보며 안전하고 자연스러운 움직임을 빠르게 배울 수 있다. DAgger는 정책이 실제로 방문하는 상태를 데이터에 넣어 분포 이탈을 줄이고, 데이터 증강은 조명과 배경 변화에 대한 내성을 높인다. 멀티태스크 학습은 여러 작업 사이의 공통 조작 패턴을 배우게 하며, 언어 조건 학습은 같은 장면에서도 명령에 따라 다른 행동을 선택하게 만든다.

하지만 여전히 남는 문제가 있다. 어떤 행동은 사람이 일일이 시연하기 어렵다. 아주 미세한 힘 조절, 복잡한 접촉 조작, 긴 시간에 걸친 시행착오가 필요한 작업은 시연 데이터만으로 충분하지 않을 수 있다. 또한 "어떤 행동이 더 좋은가"를 사람이 매 순간 라벨링하기보다, 성공했는지 실패했는지 결과로 알려 주는 편이 쉬운 경우도 있다.

바로 여기서 강화학습이 등장한다. 강화학습은 정답 행동을 직접 주기보다, 행동의 결과에 보상을 주고 정책이 스스로 더 나은 행동을 찾게 한다. 모방학습이 사람의 길을 따라 걷는 방법이라면, 강화학습은 넘어지고 보상받으며 자기 발걸음을 조정하는 방법이다.

현대 로봇 학습에서는 둘 중 하나만 고르는 경우보다 함께 쓰는 경우가 많다. 모방학습으로 안전한 초기 정책을 만들고, 강화학습으로 성능을 더 밀어 올린다. 또는 강화학습이 무작정 탐험하지 않도록 사람 시연을 출발점으로 삼는다. 다음 부에서는 이 강화학습의 기본 구조를 살펴보고, 로봇이 보상과 시행착오를 통해 행동을 개선하는 방식을 배운다.

책 목록

AI 로봇 에이전트 만들기: 비전·로봇팔·학습·LLM으로 자연어 명령을 실행하는 로봇

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기