Skip to main content

off-policy 정책 경사

자 그러면은 우리가 지금까지 계속 정책 경사를 하고 있는데 다시 히스토리를 조금 읊어보면 정책 경사가 있고 그 다음에 a2c가 있고 그 다음에 ppo가 있고 이렇게 오고 있죠

정책 경사는 파이 정책을 학습을 하는 거다

근데 이왕 학습하는 김에 정책도 학습하고 가치도 학습을 해가지고 같이 학습한 걸 정책 학습하는데 좀 도움을 주면 좋지 않느냐 그게 actor critic 이라는 방법이구요 그 다음에 정책을 업데이트를 하는데 너무 많이 바꾸지 말고 조금 한 바꾸어 조금만 정책을 바꾸때 다음 정책으로 넘어갈 때 너무 많이 바꾸지 말고 한 플러스 마인에서 10% 범위 내에서만 좀 바꾸라 하는게 ppo 이런 식으로 발전을 해오게 됩니다

이건 전부 온폴리시 학습이에요 온폴리시 학습인데 슬슬 이상각도 하게 됩니다

어떻게 정책 경사에다가 오프 폴리시를 할 수 없을까 온폴리시라는 것은 내 정책으로 내 정책을 학습을 시키는 거고 오프 폴리시는 이제 남의 정책으로 내 정책을 학습을 시키는 건데요

Pendulum 환경

그래서 우리가 이제 이거를 해 볼 건데 그러면 이제 연속적인 걸 해 봐야 되는데 그 김나지음에 들어있는 것 중에 펜들럼 이라는 게 있어요

그래서 여기 모터가 여기 달려 있고 이 진자가 이렇게 흔들리는데 여기다가 적당한 토크를 걸어 주면은 얘가 딱 이렇게 바로 서게 됩니다

그래서 뭐 잘 토크를 주면 되겠죠

그래서 모터에 힘을 주면 되는데 이거는 얼마나 힘을 줄 거냐니까 연속적인 행동 공간이 되겠죠

그래서 dqn 으로는 안 돌아갑니다

안 돌아가고 ddpg 로는 되고 이렇게 된 거죠

그래서 한번 보여드리면 ddpg 김나지음 구글에서 이렇게 검색하시면 이제 여기 아 김나지음이 아니라 스테이블 베이스 라인에서 해야 되죠

구글 없던 시절 사람들은 공부를 어떻게 했나 몰라요

이렇게 편한 세상인데 검색하면 ddpg 나오는데 여기 밑에 보시면 액션이 박스인 경우에만 됩니다

그 외에는 다 안되요

그래서 다 안되고 관찰 공간은 뭐여도 상관 없습니다

관찰 공간은 다 상관없는데 액션은 무조건 박스 해야 된다

우리가 아까 했던 ppo 같은 경우는 다 되거든요

액션이 뭐여도 됩니다

딕트만 아니면 다 되는데 용도가 좀 제한적이죠

그래도 한번 해볼 수는 있다

import gymnasium as gym
env = gym.make("Pendulum-v1", render_mode="rgb_array")

DDPG

그래서 이제 ddpg 라는 방법이 나오게 되요

ddpg 는 정책 경사 방법에다가 dqn 을 섞은 겁니다

그래서 약간 혼종인데 dqn 의 아이디어랑 정책 경사의 아이디어를 합쳐 가지고 오프 폴리시로 학습을 할 수 있게 만든 방법이에요

그래서 근데 이 방법은 그 대신에 대가가 있는데 연속적인 행동 공간에서만 쓸 수 있습니다

그냥 모델이 그렇게 생겼어요

그래서 우리가 이제 dqn 은 이산적인 행동 공간을 할 수 있습니다

왜 그런지는 얘기 드렸죠

dqn 이 하는 방식은 q 함수를 학습을 해서 행동마다 q 함수 값이 있어 가지고 q1 q2 q3 이렇게 나오면 이 중에서 q 가 제일 높은 게 뭐냐

q1이 제일 높네?

그럼 이거 해야겠다 이런 식으로 하는 게 dqn 이란 말이에요

dqn 은 연속적인 행동 공간에 적용이 안 됩니다

ddpg 는 반대로 연속적인 공간에만 쓸 수가 있어요

그래서 여러분이 어떤 문제 중에 아 이거는 그 이산적인 문제다 그러면 ddpg 를 쓰시면 안 되고 연속적인 문제다

그럼 dqn 을 쓰시면 안 됩니다

그래서 이제 dqn 하고 차이를 보면 공식을 제가 그냥 그대로 복사해서 논문에 있는 걸 그대로 복사해서 붙여 넣어 가지고 굉장히 정신사나운데 결국에는 이거죠

우리 다시 보면 이게 이제 기본적으로 우리가 이제 시간 착습에서 하는 건데 q러닝은 r 플러스 맥스 q 프레임 이렇게 한단 말이에요

할인도 지읍시다

r 플러스 맥스 q 프레임 이렇게 한단 말이에요

너는 그 보상을 받았는데 그 다음에 뭘 할 거냐에 있어서 나는 제일 좋은 행동을 할 거야

이렇게 하는데 이게 편향되어 있다고 얘기 들었죠 계속 얘기 드리지만 최대화 편향을 일으킵니다

이걸 최대 값으로 하니까 우리가 이 q 를 학습을 할 때 q 를 너무 키운단 말이에요

너무 이제 꿈이 너무 꿈이 큰 거죠

그래서 어 이거를 꿈을 좀 낮춰 주기 위해서 어떻게 하느냐 하면은 맥스 q 프라임을 하지 않고 우리가 이제 q 를 두 개로 나눠 가지고 아금 x q 를 해 가지고 일단 행동을 하나 고른 다음에 그 다음에 여기다 다시 넣어서 가치를 이제 산정을 하게 합니다

그럼 요 q 가 좀 과대 추정을 했다고 하더라도 똑같이 과대 추정하기는 쉽지 않으니까 좀 더 정상적인 숫자가 나올 가능성이 있겠죠

그래서 이런 식으로 하는 게 이제 q 러닝이고 q 러닝을 이제 딥러닝으로 구현한 게 dqn 입니다

그 다음에 ddpg 는 딥 디터미니스틱 폴리시 그래디언트인데 보면은 이제 여기 mu 함수가 그냥 바로 행동을 골라 줘요 다음에 뭘 할지를 다음에 뭘 할지를 바로 골라 주는 이런 방식으로 되어 있고 그러니까 요 q 가 제일 큰 걸 하는 게 아니라 그냥 아 너 그거 했어?

나 이거 할 건데 근데 나 이거 할 건데가 그냥 mu 에서 바로 그냥 툭 튀어나오게 됩니다

그래서 이런 식으로 하면은 우리가 이제 요 mu 자체를 폴리시 그래디언트로 학습을 하면 되겠죠

그 다음에 탐색을 하기 위해서 행동의 노이즈를 여기 추가해 줍니다

액션을 하는데 이 액션이 연속적이란 말이에요

어차피 연속적이니까 여기다가 플러스 노이즈를 섞어 주면은 이 노이즈가 이제 뭐 어떤 정규분포를 따르게 해 가지고 정규분포를 따르게 해 가지고 뭐 플러스 1이 나올 때도 있고 마이너스 0.3이 나올 때도 있고 이러면 액션이 조금씩 다르게 되겠죠

그래서 이렇게 하는 것이 ddpg 의 아이디어 입니다

이런 얘기고 그래서 이걸 한번 실습을 돌려보면 홈페이지에서 새로 고침 하시면 오프폴리시 정책 경사라고 있죠

펜들럼 환경을 진행을 해주시고요

그리고 그 다음에 ddpg를 보면 ddpg가 있고 여기 탐색을 위한 노이즈가 있는데 왜냐하면 랜덤한 노이즈를 섞어 주기 때문에 그렇습니다

탐색을 할 때 ddpg는 그래서 여기 보시면 이제 노멀 액션 노이즈 이렇게 되있는데 노이즈의 평균은 0이고 표준 편차는 한 0.1 정도로 줘라

이런 얘기입니다

그러면 우리가 원래는 토크를 예를 들면 1.5만큼 줘야 되는데 우리 정책에 따르면 플러스 마이너스 한 0.1 정도 표준 편차 내에서 노이즈가 들어가니까 표준 편차가 0.1이면 보통 3표준 편차 까지는 나오는 거거든요

그러면 한 마이너스 0.3에서 한 플러스 0.3 사이에서 노이즈가 들어가겠죠

그런 식으로 생각을 하시면 될 것 같구요 그래서 사용하는 방법은 뭐 우리 맨날 하는 거랑 똑같습니다

그냥 노이즈 정해주는거 제외하면 그냥 돌리시면 돼요

이렇게 맨날 하던 그 방식이죠

익숙한 그 맛 아는 맛 그래서 한 만 번 정도 돌리면 제 기억으로는 됐던 것 같아요

한 만 번 정도 이제 돌려주면 되고요 크 recognise 아 chest 그다음에 이제 팬들 너무 같은 경우는 보상이 어떻게 되냐면 에피소드 길이는 고정인데 각도로 보상을 줍니다.

수직으로 바닥 서 있으면 보상을 주고 밑으로 쳐져 있거나 옆으로 기울어있으면 기운 각도만큼 마이너스를 받아요.

그래서 제한된 시간 동안 계속 서 있어야 됩니다.

이렇게 우리 벌 설 때 손 들고 있었는데 손 기울면 선생님 하듯이.

벌 서는 시간은 정해져 있어요

이거는.

빨리 세운다고 보상을 더 주거나 이런 건 아닙니다.

그래서 보시면 마이너스가 좀 줄었죠.

학습이 잘 되고 있는 것 같습니다.

아주 잘 되는지는 모르겠지만 그리고 이제 이거는 보면 학습 속도가 살짝 느린 느낌이 좀 들죠.

왜 느릴까요?

실제로 시행을 해서 궤적을 만들어야 되는데 앞에 거는 빨리 끝나면 궤적이 짧아지는데 이거는 길이가 고정이기 때문에 무조건 200번 해야 되잖아요.

약간은 좀 궤적을 만드는 데 시간이 많이 걸립니다.

그런 점이 있겠죠.

많이 줄었죠

지금.

지금 아까 마이너스 1000이었는데 마이너스 745, 마이너스 599. 줄어들고 있다는 건 학습이 잘 되고 있다는 겁니다.

그럼 이제 안심하고 기다림되겠죠.

물론 이래

다 성능 붕괴가 일어나서 훅 떨어질 수도 있지만 일단은 별 문제 없이 되고 있는 것 같아요.

그래서 다 돌아갔고 성능을 보면 성능이 많이 올라가는데 이게 지금 시각화하는 코드가 여기 없거든요.

앞에 거에서 갖다 붙이면 됩니다.

우리 앞에 했던 랜더 에피소드 이거를 그대로 갖다 붙입니다.

단축키가 바뀌어가지고 그러면 잘 세워주고 있죠.

한 번 더 해보면 약간 기운 상태로 똑바로 보세요.

지금 약간 좀 더 학습을 해야 될 것 같은데 해보시면 이렇게 하면 되죠.

한 번 더 보면 이렇게 여기 화살표는 걸려있는 토크를 나타냅니다.

조금 더 이쪽으로 기울여 줬으면 좋았을 텐데 그래서 학습이 잘 되는 걸 볼 수 있습니다.

시각화하는 코드는 이거 그대로 쓰시면 돼요.

랜더에 있는 형태로 랜더 에피소드 우리가 만들어 놓은 함수 있죠?

import numpy as np
from stable_baselines3 import DDPG
from stable_baselines3.common.noise import NormalActionNoise, OrnsteinUhlenbeckActionNoise

# 탐색을 위한 노이즈
n_actions = env.action_space.shape[-1]
action_noise = NormalActionNoise(mean=np.zeros(n_actions), sigma=0.1 * np.ones(n_actions))

# 학습
model = DDPG("MlpPolicy", env, action_noise=action_noise, verbose=1)
model.learn(total_timesteps=10000, log_interval=10, progress_bar=True)

TD3

사람들이 계속 뭔가 자꾸 꼬물락 꼬물꼬물 꼬물꼬물 좀륵 좀륵 좀륵 개선을 합니다.

또 생각을 해보면 이게 뭐 세상 완벽한 방법이 어디 있겠어요?

그쵸?

그래서 이렇게 해서 이렇게 해서 이렇게 해서 이렇게 해서 이렇게 해서 이렇게 해서 또 새로운 방법이 어디 있겠어요?

또 뭔가 새로운 방법이 나오는데 이제 ddpg에다가 앞에 뭐가 자꾸 붙어요.

그래서 twind delayed ddpg 이렇게 되는데 그래서 이제 ddpg를 개선한 건데 그래서 실제로는 스테이블 베이스 라인에는 ddpg가 따로 구현이 안 돼 있고 그냥 실제로는 td3라는 이유 왜 d3냐면 d가 3개라서 그래요.

d d d 정말 성의 없는 이름이죠.

그래서 스테이블 베이스 라인 코드를 뜯어보면 실제로는 td3로 만들어져 있고 ddpg를 호출하면 td3에서 그냥 몇 개의 파라미터만 강제로 고정을 하게 되어 있습니다.

그래서 사실은 ddpg는 쓸 필요가 없다.

그냥 td3이다.

그럼 여기 이름에 보시면 twind이 들어가고 delayed가 들어가는데 이 이름을 보면 우리가 이제 어느 정도 강화학습을 자꾸 보다 보면 맨날 비슷한 아이디어가 또 나오기 때문에 또 저거냐

이런 생각을 하셔야 되는데 twind?

쌍둥이?

두 개라고?

뭐가 두 개일까?

이중학습이죠.

WQ러닝입니다.

이중Q학습.

뭐였지?

이렇게 하시면 우리가 이제 q를 과대추정하는 문제가 있었잖아요.

그래서 이제 q를 두 개 만들어서 한 쪽 q로 다른 쪽 q를 계산을 하는 거예요.

그래서 그렇게 하는데 td3는 여기서 한 가지를 더 집어 넣습니다.

q를 두 개 만드는 것까지는 이전에도 하던 건데 td3는 q를 두 개를 하면서 이걸 하는 목적이 뭐냐면 이쪽 q로 평가를 했을 때 여기서 argmax로 해서 행동을 하면 제가 아까 뭐라고 얘기하셨는데 여기에서 과대평가가 될 수는 있는데 설마 여기에서도 과대평가가 되겠냐

이렇게 얘기했잖아요.

가끔 설마가 사람 잡는단 말이에요.

그래서 어떻게 하냐면 td3에서는 계산을 두 번 해봅니다.

여기서도 계산해보고 여기서도 계산해보고 그래서 만약에 얘는 높게 나왔는데 얘는 작게 나왔다

그럼 이쪽 계산 결과를 쓰고요.

만약에 얘가 높게 나왔는데 얘로 계산해보니까 더 높게 나왔다 설마 사람 잡는 경우죠.

그럼 원래 이런 걸로 합니다.

그래서 하여간 q를 작게 만드는 게 목적이에요.

q가 과대추정되는 것을 최대한 억제를 하려고 하는 거고 그다음에 이거는 뭐 아까 얘기 드렸고요.

노이즈 추가하는 거 그다음에 아 아까 얘기한 거랑 좀 다르구나 아까 얘기한 거는 최종 행동에만 노이즈를 추가하는 건데 td3에서는 노이즈를 여기에도 노이즈를 넣습니다.

마지막 행동에만 노이즈를 넣는 게 아니라 그래서 노이즈를 두 번 넣는다

이런 얘기고 그다음에 지연된 정책 업데이트 이것도 우리가 이미 했던 건데 언제 했냐면 DQN 할 때 했었죠.

DQN 할 때 우리가 q가 두 개가 있는데 하나는 온라인 q고 하나는 타겟 q라서 타겟 q를 바로바로 업데이트하지 않고 목표가 계속 변하면 불안정하다고 했잖아요.

그래서 학습이 불안정하니까 타겟 q는 일단 고정을 해놓고 온라인 q만 계속 업데이트를 하다가 한 번씩 덮어 써준다고 했어요.

그 아이디어를 좀 가져와서 우리가 이제 DDPG도 결국 DDPG도 결국 액터 크리틱이거든요.

액터 크리틱인데 이 크리틱은 자주 업데이트를 합니다.

왜냐하면 어차피 정책은 내가 따로 액터가 하는 거니까 크리틱을 바꾼다고 해서 내 정책이 불안정해지거나 하진 않아요.

그래서 크리틱을 충분히 업데이트를 해가지고 같이 추정이 좀 정확해지면 그때 가서 액터를 업데이트를 합니다.

이름에 딜레이드가 들어가는데 왜 딜레이드냐 하면 액터를 바로바로 업데이트하지 않고 이제 크리틱이 알만하다 싶으면 액터를 한번씩 업데이트를 해 주는 거에요.

그래서 보면 본질적으로 DDPG랑 다른 거는 아니고 약간의 우리가 이미 익숙한 이중학습이라든지 천천히 업데이트를 해 준다든지 이런 우리 다 아는 사실 테크닉들을 다 끼어 넣어 준 거죠.

여러분들이 강학습 연구자다 그러면 이때까지 우리가 배운 것 중에 끼어 넣을 거 없나 이런 거 생각하다가 있으면 여기다 하나 더 끼어 넣는 거죠.

예를 들면 우리가 A3C에서 배우면 어신크로노스를 한번 넣어본다든가 아니면 원래 오프폴리시인데 이걸 온폴리시로 바꿀 때도 원래와 똑같죠.

이런 식으로 하나씩 끼어 넣어보는 거예요.

아니면 우리가 정책을 업데이트를 하는데 그냥 업데이트하지 말고 PPO를 가져와서 플러스 마이너스 10% 범위에서만 업데이트를 한다든가 그렇게 할 수도 있고 아니면 우리가 DQN에서 나왔는데 기억나실지 모르지만 폴리학 에버리징이라고 있죠.

원래는 내가 100% 업데이트 해야 되는데 약간 섞어 주는 거예요.

원래 거 정책 반, 새 정책 반 이렇게 섞어 준다든지 근데 실제로 폴리학 에버리징은 이 TD3 구현에 들어가 있습니다.

그 정도 아이디어는 제가 말할 정도면 똑똑하신 분들은 이미 다 해놨고 PPO는 제가 알기로 안 들어가 있는 걸로 알고 있어요.

그걸 또 섞어 주면 되겠죠.

여기다가 PTD3 이런 식으로 자꾸 이름이 붙는 거예요.

한국 사람들 요리 만드는 방식 보면 그렇잖아요.

마카롱을 가져오면 마카롱 가만히 안 있고 마카롱을 뚱카롱으로 만든 다음에 거기다 마라맛을 첨가해서 마라뚱카롱을 만들고 이렇게 하듯이 연구자들도 보면 별 차이는 없어요.

자꾸 집어넣는 거죠

참고한 거를.

그래서 민트초코 마라뚱카롱 이렇게 만들고 코드를 좀 뜯어보면 이건 실습코드인데 실습코드는 보시면 이름만 TD3로 바꾸시면 됩니다.

앞의 거에서 코드를 좀 뜯어보면 트레인함수를 열어보면 어떻게 학습을 하는지를 아는데 목표망에 스무딩 이렇게 있는데 여기 액터 타겟이 있죠.

여기에다가 데이터를 넣어주는데 여기서 바로 넥스트 액션이 나오는 게 아니라 이렇게 노이즈가 섞여있습니다.

노이즈가 섞여있고 클램프는 왜 해주냐면 노이즈를 너무 많이 섞어서 너무 이상한 행동을 하면 곤란하니까 약간 범위를 제한을 해주는 거예요.

그 다음에 큐 값 계산하고 큐 값은 그냥 계산하면 되겠죠.

그런데 여기 앞에 미니 붙어있습니다.

큐 값을 두 번 계산을 해가지고 두 번 중에 더 작은 쪽을 선택을 해줘요.

그래서 맨날 나오는 TD 타겟 계산 보상에다가 값하고 그 다음에 넥스트 큐벨류 큐프라이 이 공식은 슬슬 지겹다

이 얘기 그만했으면 좋겠다

이런 느낌이 드셔야 됩니다.

저런 공식이 있었나?

저거 어디서 넣은 거지?

이러시면 안 돼요.

5일 동안 얘기한 공식 딱 하나밖에 없습니다.

이 공식만 얘기했어요.

그래도 생소하게 들리실 수 있어요.

5일 반복한다고 우리가 다 알 것 같으면 공부 뭐하라 합니까?

그죠?

듣고 듣고 또 듣고 하다보면 언젠가 되겠죠.

그래서 크리틱 손실을 계산하고 MS 2로 계산한다는 거는 우리가 이런 식으로 제곱으로 계산한다는 거죠.

그래서 가치가 이만큼으로 추정되어야 되는데 가치가 이런데로 추정되면 이렇게 줄여주고 이런데로 추정되면 이렇게 늘려주고 그래서 우리가 가치의 오차가 딱 0이 되게 추정을 해 주는 겁니다.

그 다음에 이거 백워드 그래서 우리가 큐가 큐네트워크가 뉴럴렛이니까 계산은 4워드로 하고 최적화할 때는 백워드로 최적화한다 얘기했었고요.

그 다음에 이제 보면은 정책을 업데이트할 때 이런식의 표현을 쓰는데 이 퍼센트는 뭐냐면 나누기를 해서 나머지를 구해라

이런 건데 만약에 딜레이가 100이다

그 얘기는 뭐냐면 100번에 한 번만 나누기에서 나머지가 100으로 나눠 떨어질 때가 100번에 한 번 있겠죠.

왜냐하면 99 이런건 100으로 나누면 99가 남고 199도 100으로 나누면 99가 남죠.

정확히 100이나 200이나 300이나 이때만 0이 되니까 몇번에 한 번씩만 업데이트를 해라

그래서 크리틱은 계속 업데이트를 하는데 매 단계 단계마다 업데이트 하는데 정책은 뜸은 뜸은 업데이트를 합니다.

그래서 이 액터 손실을 계산을 하고 그래서 여기도 백워드로 최적화를 해 주는 거죠.

그 다음에 정책이랑 크리틱이랑 다 업데이트를 할 때 한 번에 업데이트 하는 게 아니라 우리가 했던 폴리학 에버리징

그래서 새 정책이 있고 기존 정책이 있으면 기존 정책은 새 정책으로 바로 바꿔도 되는데 폴리학 에버리징이라는 건 예를 들면은 타우를 10%를 했다

그럼 기존 정책이랑 새 정책이랑 9대1로 섞어주는 거에요.

그리고 이거는 별로 중요한 거 아니고 이런 식으로 하게 됩니다.

그래서 보면은 전체적으로 보면은 얘기하면 복잡하지만 부분부분 개념들은 우리가 다 다루는 내용들입니다.

그래서 이제 이 부분부분 개념들에 익숙해지면 새로운 방법이 나와도 논문을 다 읽어보지 않아도 이름만 보고 조금 보면 대충 이런 얘기구나 코드 어디 있어?

논문을 안 읽어요.

내가 읽어서 뭐 하겠고 빨리 코드 가져와 해서 코드만 싹 돌려보면 되죠.

그래서 이 Td3도 해보면 Td3 하는 거는 쉽습니다.

어떻게 하면 되냐면 여기 ddpg에서 이거를 dd3 이렇게 바꿔주면 돼요.

dd3 어차피 ddpg랑 Td3는 똑같은 거니까 이렇게 학습을 시키시면 되겠죠.

이렇게 하면 되죠.

자, 그래서 이것도 학습이 잘 끝났고요.

이것도 한번 그려보면 네.

균형을 잘 맞추고 있는 걸 볼 수 있죠.

그래서 잘 학습을 한다.

당연히 잘 학습을 하겠죠.

어차피 ddpg가 Td3의 한 부분 집합이니까.

Td3에서 딜레이 피해가 Td3에서 딜레이 빼고 트윈 빼고 이러면 ddpg가 되고 반대로 넣어주면 Td3가 되고 이런 겁니다.

import numpy as np
from stable_baselines3 import TD3
from stable_baselines3.common.noise import NormalActionNoise, OrnsteinUhlenbeckActionNoise

# 탐색을 위한 노이즈
n_actions = env.action_space.shape[-1]
action_noise = NormalActionNoise(mean=np.zeros(n_actions), sigma=0.1 * np.ones(n_actions))

# 학습
model = TD3("MlpPolicy", env, action_noise=action_noise, verbose=1)
model.learn(total_timesteps=10000, log_interval=10, progress_bar=True)

SAC

그 다음에 한 가지 모델만 더 소개해드리면 이제 우리가 sac까지 하면 스테이블 베이스 라인에 있는 모든 알고리즘을 다 배우는 거거든요.

그래서 현재 강화학습에서 어쨌든 이름이 있는 이름 값을 좀 하는 모델, 알고리즘은 우리가 다 배운 겁니다.

놀랍게도 물론 뭘 배웠는지는 잘 모르겠다

이런 생각이 드시겠지만 어쨌든 한번 본 게 어딥니까?

그죠?

알파고 만든 사람이 데이비드 실버라고 있어요.

데이비드 실버.

이 사람이 엄청 유명한 사람인데 이 사람이 서튼 제자거든요.

서튼 제자고 아까 교과서 하나밖에 없다고 했잖아요.

서튼 앤 바토 이 두 사람이 쓴 교과서가 정말 말 그대로 수학의 정석처럼 강학습의 정석 같은 건데 서튼 제자입니다.

정말 대가의 제자고 이 사람이 알파고 만든 사람이에요.

알파고 만든 딥마인드 사장 친구입니다.

대학교 때 같이 게임해서 차렸다 말아 먹은 사람이에요.

약간 인생욕쟁이인데 이 사람이 영국에 UCL이라고 좋은 학교에 있거든요.

거기서 강학습 강의를 10주동안 한 게 있어요.

유튜브에 영상 다 올라와 있습니다.

근데 재밌는 게 1주차 영상은 조회수가 수십만 회거든요.

근데 10주 차로 가면 한 천회인가?

끝까지 다 본 사람 별로 없어요.

그 10주짜리 강의를 사실 저도 중간부터는 2배속으로 이렇게 보고 아 힘들다.

10주 보고 있기가 되게 힘들더라고요.

그래서 무슨 얘기냐면 처음부터 끝까지 뭔가

하나를 대충이라도 다 보면 사실 이게 완강률이 1%밖에 안되기 때문에 상위 1%는 된다.

애초에 보기 시작한 사람도 전세계 몇 프로는 되겠습니까?

일단 보기 시작했다는 것도 유튜브에서 강의를 본다는 것도 상위 1%인데 끝까지 다 보면 진짜 상위 1%야

1%입니다.

그러니까 여러분들이 굉장히 우리가 어려운 수업부인데 사실 이거를 끝까지 한번 계속 들어보셨으면 어디 가서 강학습 정말 전공자 제외하면 알 만큼은 안다.

이렇게 하실 수 있어요.

그래서 이제 SAC는 별건 아니고 이것도 DDPG의 후속인데 DDPG에서 TD3도 나오고 SAC도 나오고 이렇게 서로 다른 아이디어를 가지고 DDPG를 개선한거에요.

그래서 SAC의 개선은 뭐냐면 정책을 아예 노이즈를 따로 섞지 말고 정책 자체를 확률적으로 하는 그런 모델을 쓰자 라고 하는거고 그러면 이제 우리가 A2C에도 들어가 있지만 엔트로피를 집어넣자

이거죠.

그래서 DDPG나 TD3는 엔트로피가 없는데 얘네는 엔트로피를 넣어가지고 탐색을 좀 하게 하자 엔트로피를 넣으면 다시 한번 얘기 드리면 엔트로피는 방이 어질러져 있는 그런게 엔트로피가 높은 상태입니다.

이것저것 다양하게 하는 거를 선호하게 이렇게 해주는거고 그 다음에 당연히 강학습 그런 사람들이 뻔하게 할 수 있는 생각이 이중학습이기 때문에 SAC 만든 사람들도 TD3를 보고 만든건 아니에요.

이중학습을 넣었는데 조금 구현 방식이 달라요.

그래서 별도로 스무딩을 하거나 아니면은 두개 중에 더 작은 값을 취하거나 이런건 안들어있습니다.

그러면 우리가 연구자다 귀신같이 얘는 이렇게하고 얘는 이렇게해서 둘 다 섞으면 되겠네

이렇게 하면 논문 하나가 나오겠지만 우리는 연구자는 아닌 관계로 그런 아이디어도 있구나 그리고 넘어가면 되겠죠.

그 다음에 SAC가 좀 재미있는 아이디어를 추가를 했는데 어떤 아이디어냐면 이건 GSDE라고 다른 사람들이 개발한 방법인데 이거를 갖다가 자기네꺼에 집어넣었어요.

이게 이제 재미있는 아이디어인데 지금 TD3는 기본적으로 노이즈를 외부에서 섞어주는데 아까 제가 어떻게 했냐면 정규분포로 해가지고 평균이 0이고 평균평차가 0.1 정도 되는 정규분포에서 노이즈를 섞겠거든요.

그럼 노이즈가 정규분포를 따른다는 거는 이 안에서는 자유롭게 나온다는 거잖아요.

그럼 문제가 뭐냐면 이걸 로봇에다 적용을 해보면 로봇이 팔을 덜덜덜 떠는 현상이 생깁니다.

왜냐하면 팔을 이렇게 있다가 팔을 휙 돌려야 되는데 노이즈가 랜덤하게 끼니까 나는 분명히 이쪽으로 돌리려고 하는데 노이즈가 들어가서 이쪽으로 갔다가 다시 이쪽으로 더 갔다가 이러면서 팔을 덜덜덜덜 떠면서 가는 이런게 생겨.

그래서 이 쓸데없는 노이즈라는 거죠.

그래서 탐색을 하는 건 좋은데 예를 들면 내가 팔을 이쪽으로 돌리고 있으면 이쪽 방향으로 더 돌리면 더 돌렸지.

가다가 왜 다시 돌아오냐

이거야.

가고 있으면 가는 방향으로 더 가야지.

팔을 이렇게 하는데 아니면 위아래로 왔다갔다 한다든가 이렇게 돌린다든가 이렇게 해야 노이즈가 자연스럽게 탐색을 하는거지.

팔을 이렇게 떨면 이게 무슨 의미가 있냐

이거야.

그냥 손떳 수전증이지.

그래서 이 GSD는 여기 보시면 위에 있는 식에서는 노이즈가 그냥 고정이 되어 있는데 이 노이즈도 상태에 따라 달라지게 S에 따라 달라지게 학습을 시킵니다.

그러면 노이즈도 적절하게 학습을 하는 거죠.

그래서 지금 이게 그래프가 가려서 잘 안보이는데 그래프를 떨리로 그렸나 몰라요?

여기 뭐냐면 그냥 멀쩡하게 노이즈를 먹인거고 원래는 파란색 선을 따라가게 했습니다.

파란색 선이 이렇게 되어 있어요.

지금 보시면 초록색 선이 미친듯이 노이즈를 섞어놔가지고 원래는 그냥 이렇게 가야 되는데 이런 느낌으로 간단 말이에요.

그래서 지금 주황색 선은 이 뒤에 가려져서 잘 안보이는데 조금 더 매끄럽게 움직입니다.

잘 안보이는데 마음의 눈으로 보세요.

이런식으로 하는거가 SAC에 추가되어 있습니다.

계속 뭔가 아이디어가 더 들어가는 거죠.

우리가 탐색을 할 때도 마구잡이로 하지 말고 좀 필요하게 학습을 해서 하자.

그래서 이것도 내부 코드를 보면, 코드 보실 필요는 없지만 어떻게 돌아가는지 한번 보면 리플레이 버프 오프 폴리시니까 리플레이 버프 이 얘기 보면 아 이거 오프 폴리시지 이게 생각이 나셔야 됩니다.

리플레이 버프에서 데이터를 샘플링을 하고 그 다음에 SD를 이용해서 노이즈를 만들건데 일단 노이즈를 리셋을 해줍니다.

그 다음에 우리가 액터에서 이거는 정책 자체가 확률론적 정책을 쓴다고 했죠.

그래서 정책의 확률을 뽑아내요.

그 다음에 엔트로피를 곱해줄건데 개수를 초기화를 하고 이 엔트로피 개수를 학습을 합니다.

엔트로피를 얼마나 넣어줄건지 이전에는 엔트로피가 고정으로 들어가는데 여기서는 엔트로피가 얼마나 들어갈지도 학습을 해요.

그 다음에 확률에 따라서 다음 행동을 선택을 하고 그 다음에 어?

이게 또 들어가네?

이거 들어가는군요.

잘 안들어간 줄 알았는데 Q값 계산해서 Q값 작게 하는거 이건 TDSR이랑 똑같죠.

Q를 두번 계산해서 그 다음에 엔트로피 항을 추가를 해주고 그 다음에 요공식 맨날 나오는 R 플러스 값마 곱하기 Q프라임.

요거를 해서 해줍니다.

그 다음에 이제 크리틱 손실을 계산을 해가지고 크리틱 최적화를 해주고요.

그리고 엑터 손실을 계산을 해가지고 엑터도 최적화를 해준거죠.

그 다음에 여기서도 바로바로 업데이트 하는게 아니라 일정 주기마다 정책을 업데이트를 해줍니다.

이런거는 비슷하죠.

그리고 폴리학 업데이트 이것도 똑같고 그래서 요런식으로 비슷비슷한 아이디어들이 계속 나와요.

그럼 이제 새로운 방법이 나오도 여러분들이 이런 어떤 핵심 개념들 맨날 나오는 개념들 있죠.

그것만 아시면 어차피 다 조합이기 때문에 완전 새로운 개념이 나오기 전에는 아 이제 한번 익숙해 지시면 대충 딱 보면은 아 요 알고리즘은 이런 특성이 있구만.

이런거를 아실 수 있습니다.

이것도 돌리는건 간단한데 이름만 바꿔주시면 돼요.

여기 지금 td3 이렇게 되있는데 sac로 바꿔주시면 되겠죠.

그리고 sac는 노이즈를 따로 안넣어줘도 됩니다.

자기가 넣으니까.

sac는 그냥 돌리면 돌리면 된다.

그래서 보면 노이즈가 외부에서 들어간게 없죠.

자기가 확률적 정책을 쓰기 때문에 노이즈를 따로 넣어주실 필요가 없습니다.

import gymnasium as gym
from stable_baselines3 import SAC

env = gym.make("Pendulum-v1", render_mode="rgb_array")

model = SAC("MlpPolicy", env, verbose=1)
model.learn(total_timesteps=10000, log_interval=4)

퀴즈