Esta página foi traduzida pela API Cloud Translation.
Switch to English

Drivers

Ver em TensorFlow.org Executar no Google Colab Ver fonte no GitHub Download do caderno

Introdução

Um padrão comum no aprendizado por reforço é executar uma política em um ambiente para um número especificado de etapas ou episódios. Isso acontece, por exemplo, durante a coleta de dados, avaliação e geração de um vídeo do agente.

Enquanto isso é relativamente simples escrever em python, é muito mais complexo para escrever e depurar em TensorFlow porque envolve tf.while loops, tf.cond e tf.control_dependencies . Portanto, abstraímos essa noção de loop de execução em uma classe chamada driver e fornecemos implementações bem testadas no Python e no TensorFlow.

Além disso, os dados encontrados pelo driver em cada etapa são salvos em uma tupla nomeada chamada Trajetória e transmitidos para um conjunto de observadores, como buffers de reprodução e métricas. Esses dados incluem a observação do ambiente, a ação recomendada pela política, a recompensa obtida, o tipo de corrente e a próxima etapa, etc.

Configuração

Se você ainda não instalou tf-agents ou gym, execute:

pip install -q --pre tf-agents[reverb]
pip install -q gym
WARNING: You are using pip version 20.1.1; however, version 20.2 is available.
You should consider upgrading via the '/tmpfs/src/tf_docs_env/bin/python -m pip install --upgrade pip' command.
WARNING: You are using pip version 20.1.1; however, version 20.2 is available.
You should consider upgrading via the '/tmpfs/src/tf_docs_env/bin/python -m pip install --upgrade pip' command.

 from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow as tf


from tf_agents.environments import suite_gym
from tf_agents.environments import tf_py_environment
from tf_agents.policies import random_py_policy
from tf_agents.policies import random_tf_policy
from tf_agents.metrics import py_metrics
from tf_agents.metrics import tf_metrics
from tf_agents.drivers import py_driver
from tf_agents.drivers import dynamic_episode_driver

tf.compat.v1.enable_v2_behavior()
 

Drivers Python

A classe PyDriver usa um ambiente python, uma política python e uma lista de observadores para atualizar a cada etapa. O método principal é run() , que run() etapas no ambiente usando ações da política até que pelo menos um dos seguintes critérios de finalização seja atendido: O número de etapas atinge max_steps ou o número de episódios atinge max_episodes .

A implementação é aproximadamente da seguinte maneira:

 class PyDriver(object):

  def __init__(self, env, policy, observers, max_steps=1, max_episodes=1):
    self._env = env
    self._policy = policy
    self._observers = observers or []
    self._max_steps = max_steps or np.inf
    self._max_episodes = max_episodes or np.inf

  def run(self, time_step, policy_state=()):
    num_steps = 0
    num_episodes = 0
    while num_steps < self._max_steps and num_episodes < self._max_episodes:

      # Compute an action using the policy for the given time_step
      action_step = self._policy.action(time_step, policy_state)

      # Apply the action to the environment and get the next step
      next_time_step = self._env.step(action_step.action)

      # Package information into a trajectory
      traj = trajectory.Trajectory(
         time_step.step_type,
         time_step.observation,
         action_step.action,
         action_step.info,
         next_time_step.step_type,
         next_time_step.reward,
         next_time_step.discount)

      for observer in self._observers:
        observer(traj)

      # Update statistics to check termination
      num_episodes += np.sum(traj.is_last())
      num_steps += np.sum(~traj.is_boundary())

      time_step = next_time_step
      policy_state = action_step.state

    return time_step, policy_state

 

Agora, vamos analisar o exemplo de execução de uma política aleatória no ambiente CartPole, salvando os resultados em um buffer de reprodução e computando algumas métricas.

 env = suite_gym.load('CartPole-v0')
policy = random_py_policy.RandomPyPolicy(time_step_spec=env.time_step_spec(), 
                                         action_spec=env.action_spec())
replay_buffer = []
metric = py_metrics.AverageReturnMetric()
observers = [replay_buffer.append, metric]
driver = py_driver.PyDriver(
    env, policy, observers, max_steps=20, max_episodes=1)

initial_time_step = env.reset()
final_time_step, _ = driver.run(initial_time_step)

print('Replay Buffer:')
for traj in replay_buffer:
  print(traj)

print('Average Return: ', metric.result())
 
Replay Buffer:
Trajectory(step_type=array(0, dtype=int32), observation=array([-0.02872566, -0.04710842, -0.00544945, -0.0319142 ], dtype=float32), action=array(1), policy_info=(), next_step_type=array(1, dtype=int32), reward=array(1., dtype=float32), discount=array(1., dtype=float32))
Trajectory(step_type=array(1, dtype=int32), observation=array([-0.02966782,  0.14809126, -0.00608774, -0.3263115 ], dtype=float32), action=array(0), policy_info=(), next_step_type=array(1, dtype=int32), reward=array(1., dtype=float32), discount=array(1., dtype=float32))
Trajectory(step_type=array(1, dtype=int32), observation=array([-0.026706  , -0.0469435 , -0.01261397, -0.03555458], dtype=float32), action=array(0), policy_info=(), next_step_type=array(1, dtype=int32), reward=array(1., dtype=float32), discount=array(1., dtype=float32))
Trajectory(step_type=array(1, dtype=int32), observation=array([-0.02764487, -0.24188231, -0.01332506,  0.25312197], dtype=float32), action=array(1), policy_info=(), next_step_type=array(1, dtype=int32), reward=array(1., dtype=float32), discount=array(1., dtype=float32))
Trajectory(step_type=array(1, dtype=int32), observation=array([-0.03248252, -0.04657265, -0.00826262, -0.04373396], dtype=float32), action=array(1), policy_info=(), next_step_type=array(1, dtype=int32), reward=array(1., dtype=float32), discount=array(1., dtype=float32))
Trajectory(step_type=array(1, dtype=int32), observation=array([-0.03341397,  0.1486668 , -0.0091373 , -0.33901232], dtype=float32), action=array(1), policy_info=(), next_step_type=array(1, dtype=int32), reward=array(1., dtype=float32), discount=array(1., dtype=float32))
Trajectory(step_type=array(1, dtype=int32), observation=array([-0.03044063,  0.34391758, -0.01591755, -0.6345626 ], dtype=float32), action=array(1), policy_info=(), next_step_type=array(1, dtype=int32), reward=array(1., dtype=float32), discount=array(1., dtype=float32))
Trajectory(step_type=array(1, dtype=int32), observation=array([-0.02356228,  0.5392579 , -0.0286088 , -0.9322155 ], dtype=float32), action=array(1), policy_info=(), next_step_type=array(1, dtype=int32), reward=array(1., dtype=float32), discount=array(1., dtype=float32))
Trajectory(step_type=array(1, dtype=int32), observation=array([-0.01277712,  0.73475397, -0.04725311, -1.2337494 ], dtype=float32), action=array(1), policy_info=(), next_step_type=array(1, dtype=int32), reward=array(1., dtype=float32), discount=array(1., dtype=float32))
Trajectory(step_type=array(1, dtype=int32), observation=array([ 0.00191796,  0.9304505 , -0.0719281 , -1.5408539 ], dtype=float32), action=array(0), policy_info=(), next_step_type=array(1, dtype=int32), reward=array(1., dtype=float32), discount=array(1., dtype=float32))
Trajectory(step_type=array(1, dtype=int32), observation=array([ 0.02052697,  0.73626345, -0.10274518, -1.271455  ], dtype=float32), action=array(0), policy_info=(), next_step_type=array(1, dtype=int32), reward=array(1., dtype=float32), discount=array(1., dtype=float32))
Trajectory(step_type=array(1, dtype=int32), observation=array([ 0.03525224,  0.542592  , -0.12817428, -1.0126338 ], dtype=float32), action=array(1), policy_info=(), next_step_type=array(1, dtype=int32), reward=array(1., dtype=float32), discount=array(1., dtype=float32))
Trajectory(step_type=array(1, dtype=int32), observation=array([ 0.04610407,  0.7391692 , -0.14842695, -1.342661  ], dtype=float32), action=array(0), policy_info=(), next_step_type=array(1, dtype=int32), reward=array(1., dtype=float32), discount=array(1., dtype=float32))
Trajectory(step_type=array(1, dtype=int32), observation=array([ 0.06088746,  0.5461935 , -0.17528017, -1.0998576 ], dtype=float32), action=array(1), policy_info=(), next_step_type=array(1, dtype=int32), reward=array(1., dtype=float32), discount=array(1., dtype=float32))
Trajectory(step_type=array(1, dtype=int32), observation=array([ 0.07181133,  0.743134  , -0.19727732, -1.4420109 ], dtype=float32), action=array(0), policy_info=(), next_step_type=array(2, dtype=int32), reward=array(1., dtype=float32), discount=array(0., dtype=float32))
Average Return:  15.0

Drivers para TensorFlow

Também temos drivers no TensorFlow que são funcionalmente semelhantes aos drivers Python, mas usam ambientes TF, políticas de TF, observadores de TF etc. Atualmente, temos 2 drivers TensorFlow: DynamicStepDriver , que termina após um determinado número de etapas (válidas) do ambiente e DynamicEpisodeDriver , que termina após um determinado número de episódios. Vejamos um exemplo do DynamicEpisode em ação.

 env = suite_gym.load('CartPole-v0')
tf_env = tf_py_environment.TFPyEnvironment(env)

tf_policy = random_tf_policy.RandomTFPolicy(action_spec=tf_env.action_spec(),
                                            time_step_spec=tf_env.time_step_spec())


num_episodes = tf_metrics.NumberOfEpisodes()
env_steps = tf_metrics.EnvironmentSteps()
observers = [num_episodes, env_steps]
driver = dynamic_episode_driver.DynamicEpisodeDriver(
    tf_env, tf_policy, observers, num_episodes=2)

# Initial driver.run will reset the environment and initialize the policy.
final_time_step, policy_state = driver.run()

print('final_time_step', final_time_step)
print('Number of Steps: ', env_steps.result().numpy())
print('Number of Episodes: ', num_episodes.result().numpy())
 
final_time_step TimeStep(step_type=<tf.Tensor: shape=(1,), dtype=int32, numpy=array([0], dtype=int32)>, reward=<tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.], dtype=float32)>, discount=<tf.Tensor: shape=(1,), dtype=float32, numpy=array([1.], dtype=float32)>, observation=<tf.Tensor: shape=(1, 4), dtype=float32, numpy=
array([[-0.02959541, -0.02209792,  0.01046155,  0.01981805]],
      dtype=float32)>)
Number of Steps:  34
Number of Episodes:  2

 # Continue running from previous state
final_time_step, _ = driver.run(final_time_step, policy_state)

print('final_time_step', final_time_step)
print('Number of Steps: ', env_steps.result().numpy())
print('Number of Episodes: ', num_episodes.result().numpy())
 
final_time_step TimeStep(step_type=<tf.Tensor: shape=(1,), dtype=int32, numpy=array([0], dtype=int32)>, reward=<tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.], dtype=float32)>, discount=<tf.Tensor: shape=(1,), dtype=float32, numpy=array([1.], dtype=float32)>, observation=<tf.Tensor: shape=(1, 4), dtype=float32, numpy=
array([[-0.00525741,  0.00929421, -0.03492192,  0.0023589 ]],
      dtype=float32)>)
Number of Steps:  91
Number of Episodes:  4