보안세상

PPO알고리즘에 대해서 알아보자 본문

내 생각

PPO알고리즘에 대해서 알아보자

똔민 2023. 7. 22. 17:10
반응형

강화학습의 Proximal Policy Optimization (PPO) 알고리즘은 강화학습 분야에서 매우 인기 있는 알고리즘 중 하나입니다. 이 알고리즘은 OpenAI에서 2017년에 소개되었으며, 안정성과 샘플 효율성 측면에서 우수한 성능을 보여줘서 널리 사용되고 있습니다. 이 글에서는 PPO 알고리즘의 개요와 특징, 그리고 구현 방법에 대해 알아보겠습니다.

PPO 알고리즘이란?
PPO 알고리즘은 Proximal Policy Optimization의 약어로, TRPO(Trust Region Policy Optimization) 알고리즘의 발전된 형태입니다. TRPO의 단점을 극복하고 보다 안정적인 학습을 가능하게 만든 알고리즘으로, 샘플 효율성과 안정성 측면에서 뛰어난 성능을 보입니다.

 

PPO알고리즘 코드 예시(파이썬)

import numpy as np
import tensorflow as tf
import gym

class PPOAgent:
    def __init__(self, state_size, action_size):
        self.state_size = state_size
        self.action_size = action_size
        self.gamma = 0.99  # 감가율
        self.actor_learning_rate = 0.0001
        self.critic_learning_rate = 0.001
        self.actor = self.build_actor()
        self.critic = self.build_critic()

    def build_actor(self):
        input_state = tf.keras.layers.Input(shape=(self.state_size,))
        advantages = tf.keras.layers.Input(shape=(1,))
        x = tf.keras.layers.Dense(24, activation='relu')(input_state)
        x = tf.keras.layers.Dense(24, activation='relu')(x)
        output_actions = tf.keras.layers.Dense(self.action_size, activation='softmax')(x)

        def custom_loss(y_true, y_pred):
            log_prob = tf.keras.losses.categorical_crossentropy(y_true, y_pred, from_logits=False)
            return log_prob * advantages

        actor = tf.keras.models.Model(inputs=[input_state, advantages], outputs=output_actions)
        actor.compile(optimizer=tf.keras.optimizers.Adam(lr=self.actor_learning_rate), loss=custom_loss)
        return actor

    def build_critic(self):
        input_state = tf.keras.layers.Input(shape=(self.state_size,))
        x = tf.keras.layers.Dense(24, activation='relu')(input_state)
        x = tf.keras.layers.Dense(24, activation='relu')(x)
        output_value = tf.keras.layers.Dense(1, activation='linear')(x)

        critic = tf.keras.models.Model(inputs=input_state, outputs=output_value)
        critic.compile(optimizer=tf.keras.optimizers.Adam(lr=self.critic_learning_rate), loss='mse')
        return critic

    def get_action(self, state):
        state = np.reshape(state, [1, self.state_size])
        action_probs = self.actor.predict([state, np.zeros((1, 1))])[0]
        action = np.random.choice(self.action_size, p=action_probs)
        return action

if __name__ == "__main__":
    env = gym.make('CartPole-v1')
    state_size = env.observation_space.shape[0]
    action_size = env.action_space.n

    agent = PPOAgent(state_size, action_size)

    episodes = 1000
    batch_size = 32

    for e in range(episodes):
        state = env.reset()
        done = False
        score = 0

        while not done:
            actions = []
            states = []
            rewards = []
            values = []

            for _ in range(batch_size):
                action = agent.get_action(state)
                next_state, reward, done, _ = env.step(action)

                states.append(state)
                actions.append(action)
                rewards.append(reward)

                state = next_state
                score += reward

                if done:
                    break

            next_value = 0
            if not done:
                next_value = agent.critic.predict(np.reshape(next_state, [1, state_size]))

            returns, advantages = [], []
            sum_rewards = 0

            for reward, value, next_value in zip(rewards[::-1], values[::-1], np.vstack((values[1:], next_value[::-1]))):
                sum_rewards = reward + agent.gamma * sum_rewards
                returns.insert(0, sum_rewards)
                advantage = reward + agent.gamma * next_value - value
                advantages.insert(0, advantage)

            advantages = np.vstack(advantages)
            returns = np.vstack(returns)

            agent.actor.fit([states, advantages], actions, epochs=10, verbose=0)
            agent.critic.fit(states, returns, epochs=10, verbose=0)

        print(f"episode: {e}/{episodes}, score: {score}")
반응형

PPO 알고리즘의 주요 특징
1. 안정성
PPO는 TRPO의 수렴 문제를 개선하여 안정적으로 수렴하는 특징을 가지고 있습니다. 기존의 TRPO는 KL(Kullback-Leibler) 제약 조건에 따라 정책을 업데이트하는데, 이는 학습 도중 큰 변화를 일으킬 수 있어 수렴이 불안정할 수 있습니다. PPO는 이러한 KL 제약 대신 보다 안정적인 클리핑(클ipping) 기법을 사용하여 정책을 업데이트합니다.

2. 샘플 효율성
PPO는 TRPO보다 적은 샘플로도 좋은 성능을 얻을 수 있습니다. KL 제약이 없기 때문에 더 많은 샘플을 사용하여 정책을 업데이트할 수 있습니다. 이는 실제 환경에서 정책을 평가하는 비용을 줄이는 데 도움이 됩니다.

3. 간단한 구현
PPO는 구현이 상대적으로 간단하며, TRPO보다 설정이 더 쉽습니다. 이로 인해 초기 구현과 실험이 더 용이합니다.

4. PPO 알고리즘의 핵심 아이디어
PPO 알고리즘은 클리핑 기법과 Surrogate Objective 함수를 사용하여 정책을 업데이트합니다. 이때 Surrogate Objective 함수는 Policy Gradient를 이용하여 정책을 개선하는 방법입니다. 클리핑은 새로운 정책과 이전 정책 사이의 거리를 제한하여 큰 변화를 방지하며, 보다 안정적인 학습을 가능하게 합니다.

5. PPO 알고리즘의 구현
PPO 알고리즘을 구현하기 위해서는 주어진 환경과 상호작용하며 에이전트의 정책을 업데이트하는 과정이 포함됩니다. 먼저, 주어진 환경에서 에이전트가 행동을 선택하고, 환경으로부터 피드백을 받습니다. 이 피드백을 이용하여 Surrogate Objective 함수와 클리핑 기법을 적용하여 정책을 업데이트합니다. 이러한 과정을 여러 번 반복하여 에이전트의 정책을 지속적으로 개선시킵니다.

강화학습의 PPO 알고리즘은 안정성과 샘플 효율성 측면에서 우수한 성능을 보이는 알고리즘으로, 다양한 응용 분야에서 많이 사용되고 있습니다. PPO 알고리즘의 클리핑과 Surrogate Objective 함수를 이용한 정책 업데이트 방법은 안정적이고 쉽게 구현할 수 있어서 초기 학습자에게도 추천할만한 알고리즘이며, 더 나은 강화학습 모델 개발을 위한 기반으로 사용될 수 있습니다.

이제 PPO 알고리즘에 대한 고찰을 담은 블로그를 작성할 준비가 되었습니다. 읽는 이들이 강화학습과 PPO 알고리즘에 대해 더 깊이 이해할 수 있도록 쉽고 명확하게 설명해보시기 바랍니다. 행운을 빕니다!

반응형
Comments