강의자료 · 전기공학을 위한 강화학습

Sim-to-Real: Model Uncertainty와 Action Delay · 학습

실행 조건

필요한 패키지가 없으면 Colab·Jupyter 코드 셀에서 %pip install control==0.10.2 gymnasium==1.3.0 stable-baselines3==2.9.2를 실행하세요.

이번에 배울 내용

시뮬레이터에서 좋은 정책도 물리 계수와 지연이 달라지면 실패할 수 있습니다. 실제 장치로 옮기기 전에 이 차이를 수치로 확인합니다.

Reality gap

물리 계수·센서 잡음·Action 지연·Normalization 차이 때문에 Simulator 정책이 실제 장치에서 달라질 수 있습니다. 한 번에 한 요인을 바꾸어 취약점을 찾습니다.

식별과 Randomization

System identification은 관측으로 모델을 추정하고, Domain randomization은 가능한 변화 범위에서 학습합니다. 평가 범위는 학습 범위와 구분해 설계합니다.

풀이 예제

Motor 기준 모델과 P 제어입니다. Reference Angular Velocity 0.5·1·1.5를 비교합니다.

"""Synthetic motor; not a hardware interface. dt=0.1 s, scalar speed and bounded input."""
import numpy as np
class Motor:
    def reset(self, seed=0, reference=1., noise=.01):
        self.rng = np.random.default_rng(seed)
        self.omega, self.t = 0., 0
        self.reference, self.noise = reference, noise
        return np.array([self.omega / 5, reference / 2], dtype=np.float32)
    def step(self, action):
        u = 2 * float(np.clip(np.asarray(action).item(), -1, 1))
        self.omega += .1 * (-.4 * self.omega + .8 * u + self.rng.uniform(-self.noise, self.noise))
        self.t += 1; error = self.reference - self.omega
        reward = -(error**2 + .05 * u**2)
        return np.array([self.omega / 5, self.reference / 2], dtype=np.float32), reward, abs(self.omega) > 5, self.t >= 100, {'error': error, 'u': u}

def motor_evaluate(policy, references=(.5, 1., 1.5)):
    rows=[]
    for reference in references:
        env=Motor(); obs=env.reset(100, reference)
        errors=[]; inputs=[]; total=0.
        while True:
            obs,r,terminated,truncated,info=env.step(policy(obs))
            errors.append(info['error']);inputs.append(info['u']);total+=r
            if terminated or truncated:break
        rows.append([reference, np.sqrt(np.mean(np.square(errors))),np.mean(np.square(inputs)),int(terminated),total])
    return np.array(rows)

def proportional(obs):return np.clip((2 * obs[1] - 5 * obs[0]), -1, 1)
print('reference / RMSE / mean u² / safety termination / Return')
print(motor_evaluate(proportional))
reference / RMSE / mean u² / safety termination / Return
[[  0.5          0.12626501   0.07338515   0.          -1.96121101]
 [  1.           0.25292968   0.29432127   0.          -7.86894852]
 [  1.5          0.3970162    0.6158097    0.         -18.84123509]]

공식 문서·데이터