강화학습
TD법
정지홍
2024. 12. 13. 07:38
TD법 ( Temporal Difference , 시간차 )
- 강화학습에서 사용되는 방법이며, 시간차를 이용하여 상태-가치 함수 or 행동-가치 함수를 업데이트 하는 기법
- 이는 dynamic programming과 몬테카를로 방법의 장점을 결합한 방식이다.
- 몬테카를로법처럼 환경 모델을 사용안하며, 한번의 action마다 가치함수를 갱신한다.
- 특징
- 샘플 기반 학습: 환경과의 상호작용을 통해서 실제 얻은 데이터를 사용하며 학습
- 부트스트래핑: 이전 추정값을 사용하여, 현재 추정값을 업데이트 한다. ( DP의 특징)
- 이로 인해서 효율적인 학습 가능
- 점진적 업데이트: 데이터를 수집할 때마다 점진적으로 상태의 값을 업데이트하니, episode의 종료를 기다릴 필요없음.
- 에피소드 종료가 필요하지않다. 즉, episode의 중간 단계에서도 업데이트 가능
- 실시간 학습이 가능
- 단점
- 노이즈에 민감: 업데이트 과정에서의 추정값 사용 때문에 노이즈가 발생할 수 있음.
- 성능 의존성: 할인률과 학습률에 따라서 성능이 크게 달라짐
- TD학습의 종류
- TD(0): 가장 기본적인 형태이며, 한 스텝 앞으로 예측하며 학습한다.
- SARSA: 행동-가치 함수를 업데이트하며, agent가 선택한 행동을 기준으로 학습함.
- Q-Learning: 행동-가치 함수를 학습하지만, 다음 상태에서 가장 최적의 행동을 선택하는 값을 기준으로 업데이트함.
- n-step TD: 한 스텝이 아니라 n-스텝 이후의 누적 보상을 기반으로 업데이트 한다.



몬테가를로법
- G t 는 실제 관찰된 누적 보장이다. 즉, 정책이 실제로 실행된 결과로 나타나는 값
- V pi ( S t )는 예측된 미래의 보상이다.
- 위의 두 값의 차의는 예측 오차를 의미한다. 즉, '실제로 관측된 보상의 합' - '모델이 예측한 보상'을 의미한다.
- V' pi 는 갱신 후의 가치 함수이다.
- 여기서는 기대값을 계산하는 대신에 실제 수익의 샘플 데이터를 평균하여 [식2]의 기대값을 근사한다.
- 평균에는 표본 평균 , 지수 이동평균이 존재하며, [식4]는 지수 이동평균이다.
- G는 실제 수익을 의미하며, S는 추정 수익을 의미
TD법
- DP처럼 부트스트랩으로 가치 함수를 순차적으로 갱신
- 몬테카를로처럼 환경에 대한 정보 없이 샘플링된 데이터 만으로 가치함수를 갱신
- ==> 환경에 대한 정보 없이 샘플링된 데이터로 가치함수를 순차적으로 계산

- 위의 식을 보면 알수있듯이, TD법은 '추정치로 추정치를 갱신'하는 방법이다.
- 이로 인해서 정확한 값이 아니지만, 갱신이 반복되면 점점 정확해진다.
( 이를 편향이 있다고 하며, 편향은 점점 0으로 수렴한다. )
- 이로 인해서 정확한 값이 아니지만, 갱신이 반복되면 점점 정확해진다.
- 아래는 TD법을 코드로 나타낸것.
class TdAgent:
def __init__( self ):
self.gamma = 0.9
self.alpha = 0.01
self.action_size = 4
random_actions = { 0:0.25 , 1:0.25 , 2:0.25 , 3:0.25 }
self.pi = defaultdict( lambda: random_actions ) # pi는 정책. ( 행동을 결정하는 방식, 마르코프 성질에 의해서 현재 상태만 고려). 기본적으로 random_actions로 설정한다.
self.V = defaultdict( lambda: 0 )
def get_action( self , state ):
action_probabilities = self.pi[ state ] # 현재 state에 대한 정책을 뽑아냅니다.
actions = list( action_probabilities.keys() )
probabilities = list( action_probabilities.values() )
return np.random.choice( actions , p=probabilities )
def eval( self , state , reward , next_state , done ):
next_V = 0 if done else self.V[ next_state ] # 목적지인 경우에 가치함수를 0으로 하고, 나머지는 그냥 흘려보낸다.
target = reward + self.gamma * next_V # TD법 식 계산과정 1. 우선 Rt + V pi ( S t+1 )을 한다.
self.V[ state ] += ( target - self.V[ state ] ) * self.alpha # TD법 식 계산과정 2. 추정치로 추정치를 갱신한다.
env = GridWorld()
agent = TdAgent()
episodes = 1000
for episode in range ( episodes ):
state = env.reset() # agent위치를 초기 상태로 셋팅
print(agent.pi) # agent의 정책 출력
while True:
action = agent.get_action( state ) # agent로부터 어떠한 행동을 할지 뽑아냄니다.
next_state , reward , done = env.step( action ) # 위에서 랜덤하게 결정한 action을 수행할 경우의 다음 state,보상을 가져옵니다.
agent.eval( state , reward , next_state , done ) # 매번 갱신을 수행. 이 점이 몬테카를로와의 차이점이다.
if done:
break
state = next_state

각 state에 대한 평가만 했지, 정책 갱신은 안함
