Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

Autisti

Visualizza su TensorFlow.org Esegui in Google Colab Visualizza sorgente su GitHub Scarica notebook

introduzione

Un modello comune nell'apprendimento per rinforzo consiste nell'eseguire una politica in un ambiente per un numero specificato di passaggi o episodi. Ciò accade, ad esempio, durante la raccolta dei dati, la valutazione e la generazione di un video dell'agente.

Anche se questo è relativamente semplice di scrivere in python, è molto più complessa di scrivere ed eseguire il debug in tensorflow perché coinvolge tf.while loop, tf.cond e tf.control_dependencies . Pertanto astraggiamo questa nozione di ciclo di esecuzione in una classe chiamata driver e forniamo implementazioni ben testate sia in Python che in TensorFlow.

Inoltre, i dati incontrati dal driver in ogni passaggio vengono salvati in una tupla denominata denominata Trajectory e trasmessi a una serie di osservatori come buffer di riproduzione e metriche. Questi dati includono l'osservazione dall'ambiente, l'azione raccomandata dalla politica, la ricompensa ottenuta, il tipo di passaggio corrente e successivo, ecc.

Impostare

Se non hai ancora installato tf-agent o gym, esegui:

pip install -q tf-agents
pip install -q gym
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()

Driver Python

La classe PyDriver accetta un ambiente python, una politica python e un elenco di osservatori da aggiornare ad ogni passaggio. Il metodo principale è run() , che run() passaggio dell'ambiente utilizzando le azioni della policy finché non viene soddisfatto almeno uno dei seguenti criteri di terminazione: il numero di passaggi raggiunge max_steps o il numero di episodi raggiunge max_episodes .

L'implementazione è approssimativamente la seguente:

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

Ora, esaminiamo l'esempio di eseguire una politica casuale sull'ambiente CartPole, salvare i risultati in un buffer di riproduzione e calcolare alcune metriche.

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.04572451,  0.02109156, -0.03040793, -0.03130549], 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.04614634, -0.17358142, -0.03103404,  0.25163046], 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.04267471, -0.3682468 , -0.02600143,  0.53436536], 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.03530978, -0.56299365, -0.01531413,  0.8187433 ], 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.0240499 , -0.36766544,  0.00106074,  0.5212832 ], 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.0166966, -0.5628023,  0.0114864,  0.8143002], 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.00544055, -0.36783955,  0.02777241,  0.5252522 ], 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.00191624, -0.5633411 ,  0.03827745,  0.8265555 ], 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.01318306, -0.75896496,  0.05480856,  1.1310272 ], 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.02836236, -0.5646018 ,  0.07742911,  0.85602593], 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.0396544 , -0.7606886 ,  0.09454963,  1.1720163 ], 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.05486817, -0.956904  ,  0.11798995,  1.4927809 ], 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.07400625, -1.1532475 ,  0.14784557,  1.819857  ], 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.0970712 , -1.3496711 ,  0.18424271,  2.1545868 ], dtype=float32), action=array(1), policy_info=(), next_step_type=array(2, dtype=int32), reward=array(1., dtype=float32), discount=array(0., dtype=float32))
Average Return:  14.0

Driver TensorFlow

Abbiamo anche driver in TensorFlow che sono funzionalmente simili ai driver Python, ma utilizzano ambienti TF, policy TF, osservatori TF ecc. Attualmente abbiamo 2 driver TensorFlow: DynamicStepDriver , che termina dopo un determinato numero di passaggi ambientali (validi) e DynamicEpisodeDriver , che termina dopo un determinato numero di episodi. Vediamo un esempio del DynamicEpisode in azione.

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.04983833,  0.00221694, -0.04754572,  0.03050179]],
      dtype=float32)>)
Number of Steps:  46
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.01266267, -0.01962714, -0.03140591, -0.04742253]],
      dtype=float32)>)
Number of Steps:  82
Number of Episodes:  4