강화학습

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-스텝 이후의 누적 보상을 기반으로 업데이트 한다.

 

수익에 관한 식 ( 현재 시점의 reward와 t+1시점의 reward의 총합) [식1]
위의 수익 식을 통한 가치 함수 도출. [ 식 2 , 식 3 ]

 

 

V pi ( S )는 정책pi에 따라서 수행한 경우, t시점부터의 reward의 총합이다. V '은 갱신 후의 가치 함수이다. [식4]

몬테가를로법

  • 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에 대한 평가만 했지, 정책 갱신은 안함

정책에 대한 출력