카테고리 없음

패스트캠퍼스 환급챌린지 44일차 : 스크래치부터 시작하는 강화학습의 모든 것 강의 후기

dev-self 2025. 4. 17. 03:27

*본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.

 

|내용 정리|

<TD(Temporal Difference)  예제 연습_2>

TD 학습을 통한 가치 함수와 행동-가치 함수 분석

환경 설명

 

위의 그리드는 다음과 같은 특징을 가진 강화학습 환경이다:

  • 상태 공간: 3x4 그리드
  • 시작 위치: A (0,0)
  • 목표 위치: G (0,3)
  • 표류 영역(drift area): 첫 번째 행의 가운데 두 칸(///)
  • 행동 공간: 상(0), 우(1), 하(2), 좌(3)
  • 전이 모델:
    1. 에이전트의 행동에 따라 상하좌우 이동 (무작위성 없음)
    2. 표류 영역에 들어가면 시작점(0,0)으로 이동
    3. 목표에 도달하면 에피소드 종료
  • 보상: 목표 도달 시 +10, 그 외에는 0
  • 감가율(γ): 0.9
  • 학습률(α): 2e-3 (Q-함수 학습 시 5배 증가)

정책 설명

코드에서는 두 가지 정책을 사용하여 TD 학습을 진행한다:

  1. 균일 정책(policy1):
    • 모든 상태에서 각 행동의 확률: 상(0.25), 우(0.25), 하(0.25), 좌(0.25)
    • 수학적 표기: π(a|s) = 0.25 (모든 행동 a에 대해)
  2. 불균일 정책(policy2):
    • 모든 상태에서 각 행동의 확률: 상(0.25), 우(0.4), 하(0.25), 좌(0.1)
    • 수학적 표기: π(up|s) = 0.25, π(right|s) = 0.4, π(down|s) = 0.25, π(left|s) = 0.1

TD 학습 코드 실행 프로세스 및 함수 관계 설명

전체 프로그램 실행 흐름

  1. 시작점 (main)
    • 환경 초기화 (Env 클래스 인스턴스 생성)
    • 두 가지 정책 초기화:
      • 정책1: 모든 상태에서 각 행동의 확률이 동일 (0.25, 0.25, 0.25, 0.25)
      • 정책2: 방향 별 확률이 다른 정책 (0.25, 0.4, 0.25, 0.1)
    • 정책 평가 과정 실행
    • 결과 출력 및 비교
  2. 환경 설정 (environment.py)
    • 그리드 월드 환경 구현
    • 유효한 상태 공간 정의
    • 행동 공간 및 전이 모델 정의
  3. TD 학습 알고리즘 구현 (td_prediction.py)
    • 상태 가치 함수(V(s)) 학습 함수
    • 행동-가치 함수(Q(s,a)) 학습 함수
    • 유틸리티 함수 (get_state_index)

주요 함수 역할 및 관계

환경 관련 함수들

  • Env.__init__(): 환경 초기화
    • 3x4 그리드 생성
    • 시작 위치, 목표 위치, 표류 영역 설정
    • 유효한 상태 공간과 행동 공간 정의
  • Env.reset(): 환경 초기화 (에피소드 시작)
    • 에이전트 위치를 시작점으로 되돌림
    • 초기 상태 반환
  • Env.step(action): 행동 실행
    • 주어진 행동에 따라 에이전트 위치 갱신
    • 표류 영역 체크 및 처리
    • 보상, 다음 상태, 종료 여부 반환
  • Env.reward(s, a, s_next): 보상 계산
    • 목표 도달 시 +10, 그 외 0 반환

TD 학습 관련 함수들

  • get_state_index(state_space, state): 상태 인덱스 찾기
    • 주어진 상태가 상태 공간에서 몇 번째 인덱스인지 반환
    • 상태 배열과 상태 인덱스 간 매핑 역할
  • td_value_prediction(env, policy): 상태 가치 함수(V(s)) 학습
    • 가치 벡터 초기화
    • 5000개 에피소드 생성 및 학습
    • 매 스텝마다 TD 오차 계산 및 가치 함수 업데이트
    • 학습된 가치 벡터 반환
  • td_action_value_prediction(env, policy): 행동-가치 함수(Q(s,a)) 학습
    • 행동-가치 행렬 초기화
    • 5000개 에피소드 생성 및 학습
    • 매 스텝마다 TD 오차 계산 및 Q 함수 업데이트
    • 학습된 행동-가치 행렬 반환

데이터 흐름

  1. 정책 정의TD 학습 함수
    • 정책(policy): 각 상태에서 행동 확률 분포
    • TD 학습 함수는 정책을 입력으로 받아 가치 함수 추정
  2. 환경(Env)TD 학습 함수
    • 환경은 상태 공간, 행동 공간, 전이 규칙 제공
    • 환경의 step() 함수는 행동에 따른 다음 상태와 보상 제공
  3. TD 학습 함수메인 프로그램
    • 학습된 가치 함수(V(s) 또는 Q(s,a))를 반환
    • 메인 프로그램에서 결과 비교 및 출력

결과 처리

  1. 가치 벡터가치 테이블
    • 1차원 가치 벡터를 2차원 그리드 형태로 변환
    • 시각화 및 해석에 용이한 형태로 변환
  2. 행동-가치 행렬정책 평가
    • 각 상태에서 정책에 따른 기대 가치 계산
    • 두 정책 간 성능 비교

주요 알고리즘 흐름

  • TD 가치 함수 학습:
초기화: V(s) = 0
For 5000 에피소드:
    s = 초기 상태
    While 에피소드 진행 중:
        a = π(s)에서 행동 선택
        r, s' = 행동 a 실행 결과
        V(s) ← V(s) + α[r + γV(s') - V(s)]
        s = s'
  • TD 행동-가치 함수 학습:
초기화: Q(s,a) = 0
For 5000 에피소드:
    s = 초기 상태
    a = π(s)에서 행동 선택
    While 에피소드 진행 중:
        r, s' = 행동 a 실행 결과
        a' = π(s')에서 행동 선택
        Q(s,a) ← Q(s,a) + 5α[r + γQ(s',a') - Q(s,a)]
        s = s', a = a'

이 코드는 TD 학습의 기본 원리를 잘 보여주며, 서로 다른 정책에 대한 가치 함수와 행동-가치 함수를 학습하고 비교하는 과정을 구현하고 있다.

실행 프로세스

1. 초기화 단계

env = Env()  # 환경 생성
# 정책1: 균일 정책 생성 (모든 행동 확률 0.25)
policy1 = list()
for i_s, s in enumerate(env.state_space):
    pi = np.array([0.25, 0.25, 0.25, 0.25])
    policy1.append(pi)
policy1 = np.array(policy1)  # (|S|, |A|)

# 정책2: 불균일 정책 생성 (행동 확률 0.25, 0.4, 0.25, 0.1)
policy2 = list()
for i_s, s in enumerate(env.state_space):
    pi = np.array([0.25, 0.4, 0.25, 0.1])
    policy2.append(pi)
policy2 = np.array(policy2)

2. TD 학습 실행 프로세스 (V(s) 함수)

  1. 함수 호출: value_vector1 = td_value_prediction(env, policy1)
  2. 초기화: 가치 벡터를 0으로 초기화

에피소드 생성:

for loop_count in range(5000):
    done = False
    s = env.reset()  # 환경 리셋
    while not done:  # 에피소드 진행
        # 행동 선택
        i_s = get_state_index(env.state_space, s)
        pi_s = policy[i_s]
        a = np.random.choice(env.action_space, p=pi_s)
        
        # 행동 실행
        r, s_next, done = env.step(a)
        
        # TD 업데이트
        i_s_next = get_state_index(env.state_space, s_next)
        td = r + gamma * value_vector[i_s_next] - value_vector[i_s]
        value_vector[i_s] = value_vector[i_s] + alpha * td
        
        # 다음 상태로 이동
        s = s_next

3. TD 학습 실행 프로세스 (Q(s,a) 함수)

  1. 함수 호출: action_value_matrix1 = td_action_value_prediction(env, policy1)
  2. 초기화: 행동-가치 행렬을 0으로 초기화
  3. 에피소드 생성:
for loop_count in range(5000):
    done = False
    s = env.reset()
    
    # 첫 행동 선택
    i_s = get_state_index(env.state_space, s)
    pi_s = policy[i_s]
    a = np.random.choice(env.action_space, p=pi_s)
    
    while not done:
        # 행동 실행
        r, s_next, done = env.step(a)
        
        # 다음 행동 선택
        i_s_next = get_state_index(env.state_space, s_next)
        pi_s_next = policy[i_s_next]
        a_next = np.random.choice(env.action_space, p=pi_s_next)
        
        # TD 업데이트
        td = r + gamma * action_value_matrix[i_s_next][a_next] - action_value_matrix[i_s][a]
        action_value_matrix[i_s][a] = action_value_matrix[i_s][a] + 5 * alpha * td
        
        # 다음 상태-행동으로 이동
        s = s_next
        i_s = i_s_next
        a = a_next

4. 결과 처리

# 1차원 가치 벡터를 2차원 가치 테이블로 변환
value_table1 = np.zeros([3, 4])
value_table1[0,0] = value_vector1[0]
value_table1[0,3] = value_vector1[1]
value_table1[1:] = value_vector1[2:6]
value_table1[2:] = value_vector1[6:10]

# 행동-가치 행렬에서 정책에 따른 기대 가치 계산
value_vector_temp1 = np.sum(policy1 * action_value_matrix1, axis=-1)

상태 가치 함수(V(s)) 학습 코드 상세 분석

def td_value_prediction(env, policy):
    value_vector = np.zeros([len(env.state_space)])
  • 먼저 모든 상태의 가치를 0으로 초기화. value_vector는 1차원 배열로, 각 상태의 가치 함수 V(s)를 저장.
    # Repeat policy evaluation
    for loop_count in range(5000):
  • 총 5000번의 에피소드를 실행. 각 에피소드마다 가치 함수를 업데이트.
        done = False
        step_count = 0
        s = env.reset()
  • 에피소드 시작 시 환경을 초기화하고, 종료 여부와 단계 수를 추적.
        # Generate an episode
        while not done:
            i_s = get_state_index(env.state_space, s)
            pi_s = policy[i_s]
            a = np.random.choice(env.action_space, p=pi_s)
  • 현재 상태의 인덱스를 찾고, 그 상태에서의 정책 분포를 가져온 다음, 정책에 따라 확률적으로 행동을 선택.
            r, s_next, done = env.step(a)
  • 선택한 행동을 환경에 적용하고, 보상, 다음 상태, 종료 여부를 리턴 받음.
            i_s_next = get_state_index(env.state_space, s_next)
            td = r + gamma * value_vector[i_s_next] - value_vector[i_s]
            value_vector[i_s] = value_vector[i_s] + alpha * td
  • 여기가 TD 학습의 핵심이다:
  1. r + gamma * value_vector[i_s_next]는 현재 보상과 다음 상태의 할인된 가치를 합한 값으로, 가치 함수의 목표값.
  2. value_vector[i_s]는 현재 추정한 상태의 가치.
  3. td는 목표값과 현재 추정값의 차이, 즉 TD 오차.
  4. 가치 함수를 TD 오차의 방향으로 학습률 alpha만큼 업데이트.
            if done:
                value_vector[i_s_next] = 0
  • 에피소드가 종료되면 종료 상태의 가치를 0으로 설정(목표 상태의 가치는 추가 보상이 없으므로).
            step_count += 1            
            s = s_next
  • 단계 수를 증가시키고 다음 상태로 이동.
        if (loop_count + 1) % 100 == 0:
            print(f"[{loop_count}] value_vector: \n{value_vector}")
  • 100 에피소드마다 현재 가치 함수를 출력.

행동-가치 함수(Q(s,a)) 학습 코드 상세 분석

def td_action_value_prediction(env, policy):
    action_value_matrix = np.zeros([len(env.state_space), len(env.action_space)])
  • 모든 상태-행동 쌍의 가치를 0으로 초기화. action_value_matrix는 2차원 배열로, 각 상태-행동 쌍의 가치 함수 Q(s,a)를 저장.
    # Repeat policy evaluation
    for loop_count in range(5000):
        done = False
        step_count = 0
        s = env.reset()
  • V(s) 학습과 마찬가지로, 5000번의 에피소드를 실행하고 환경을 초기화.
        i_s = get_state_index(env.state_space, s)
        pi_s = policy[i_s]
        a = np.random.choice(env.action_space, p=pi_s)
  • Q 함수 학습에서는 에피소드 시작 전에 첫 행동을 선택. 이는 Q 함수가 상태-행동 쌍의 가치이기 때문에, 첫 업데이트를 위해 초기 행동이 필요하기 때문.
        # Generate an episode
        while not done:
            r, s_next, done = env.step(a)
  • 선택한 행동을 실행하고 결과를 받음.
            i_s_next = get_state_index(env.state_space, s_next)
            pi_s_next = policy[i_s_next]
            a_next = np.random.choice(env.action_space, p=pi_s_next)
  • 다음 상태에서의 정책에 따라 다음 행동을 선택.
            td = r + gamma * action_value_matrix[i_s_next][a_next] - action_value_matrix[i_s][a]
            action_value_matrix[i_s][a] = action_value_matrix[i_s][a] + 5 * alpha * td
  • Q 함수 업데이트의 핵심부분이다:
  1. r + gamma * action_value_matrix[i_s_next][a_next]는 현재 보상과 다음 상태-행동의 할인된 가치를 합한 값으로, Q 함수의 목표값.
  2. action_value_matrix[i_s][a]는 현재 추정한 상태-행동의 가치.
  3. td는 목표값과 현재 추정값의 차이, 즉 TD 오차.
  4. Q 함수를 TD 오차의 방향으로 학습률 5 * alpha만큼 업데이트. 특이한 점은 V 함수보다 5배 큰 학습률을 사용한다는 것.
            if done:
                action_value_matrix[i_s_next] = 0
  • 에피소드가 종료되면 종료 상태의 모든 행동 가치를 0으로 설정.
            step_count += 1            
            s = s_next
            i_s = i_s_next
            a = a_next
  • 다음 상태와 행동으로 이동.

V(s)와 Q(s,a)의 주요 차이점

  1. 표현 차원:
    • V(s)는 상태에 대한 가치만 저장 (상태 수 만큼의 값)
    • Q(s,a)는 상태-행동 쌍에 대한 가치를 저장 (상태 수 × 행동 수 만큼의 값)
  2. 업데이트 방식:
    • V(s) 업데이트: V(s) ← V(s) + α[r + γV(s') - V(s)]
    • Q(s,a) 업데이트: Q(s,a) ← Q(s,a) + α[r + γQ(s',a') - Q(s,a)]
  3. 학습률 차이:
    • 이 코드에서는 Q 함수에 더 큰 학습률(5α)을 사용하여 학습 속도를 높임
  4. 정책과의 관계:
    • V(s)는 정책을 따랐을 때의 기대 가치를 나타냄
    • Q(s,a)는 특정 행동을 선택한 후 정책을 따랐을 때의 기대 가치를 나타냄
    • V(s)는 Q(s,a)를 정책에 따라 가중 평균한 값: V(s) = Σ π(a|s)Q(s,a)

 

|인증|

-------

패스트캠퍼스 링크

https://bit.ly/4hTSJNB