Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

Minitaur SAC

Hak Cipta 2018 Para Agen TF-Penulis.

Lihat di TensorFlow.org Jalankan di Google Colab Lihat sumber di GitHub Unduh buku catatan

pengantar

Contoh ini menunjukkan cara melatih agen Kritik Aktor Lunak pada lingkungan Minitaur menggunakan perpustakaan TF-Agents.

Jika Anda telah bekerja melalui DQN Colab ini seharusnya terasa sangat akrab. Perubahan penting termasuk:

  • Mengubah agen dari DQN ke SAC.
  • Pelatihan tentang Minitaur yang merupakan lingkungan yang jauh lebih kompleks daripada CartPole. Lingkungan Minitaur bertujuan untuk melatih robot berkaki empat untuk bergerak maju.
  • Kami tidak menggunakan kebijakan acak untuk melakukan pengumpulan data awal.

Jika Anda belum menginstal dependensi berikut, jalankan:

sudo apt-get install -y xvfb ffmpeg
pip install -q 'gym==0.10.11'
pip install -q 'imageio==2.4.0'
pip install -q matplotlib
pip install -q PILLOW
pip install -q --pre tf-agents[reverb]
pip install -q 'pybullet==2.4.2'



ffmpeg is already the newest version (7:3.4.8-0ubuntu0.2).
xvfb is already the newest version (2:1.19.6-1ubuntu4.4).
The following packages were automatically installed and are no longer required:
  dconf-gsettings-backend dconf-service dkms freeglut3 freeglut3-dev
  glib-networking glib-networking-common glib-networking-services
  gsettings-desktop-schemas libcairo-gobject2 libcolord2 libdconf1
  libegl1-mesa libepoxy0 libglu1-mesa libglu1-mesa-dev libgtk-3-0
  libgtk-3-common libice-dev libjansson4 libjson-glib-1.0-0
  libjson-glib-1.0-common libproxy1v5 librest-0.7-0 libsm-dev
  libsoup-gnome2.4-1 libsoup2.4-1 libxi-dev libxmu-dev libxmu-headers
  libxnvctrl0 libxt-dev linux-gcp-headers-5.0.0-1026
  linux-headers-5.0.0-1026-gcp linux-image-5.0.0-1026-gcp
  linux-modules-5.0.0-1026-gcp pkg-config policykit-1-gnome python3-xkit
  screen-resolution-extra xserver-xorg-core-hwe-18.04
Use 'sudo apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 90 not upgraded.
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.
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.
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.

Mempersiapkan

Pertama kita akan mengimpor alat-alat yang berbeda yang kita butuhkan dan memastikan kita mengaktifkan perilaku TF-V2 karena lebih mudah untuk beralih dalam mode Eager di seluruh colab.

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

import base64
import imageio
import IPython
import matplotlib
import matplotlib.pyplot as plt
import PIL.Image

import tensorflow as tf
tf.compat.v1.enable_v2_behavior()

from tf_agents.agents.ddpg import critic_network
from tf_agents.agents.sac import sac_agent
from tf_agents.drivers import dynamic_step_driver
from tf_agents.environments import suite_pybullet
from tf_agents.environments import tf_py_environment
from tf_agents.eval import metric_utils
from tf_agents.metrics import tf_metrics
from tf_agents.networks import actor_distribution_network
from tf_agents.networks import normal_projection_network
from tf_agents.policies import greedy_policy
from tf_agents.policies import random_tf_policy
from tf_agents.replay_buffers import tf_uniform_replay_buffer
from tf_agents.trajectories import trajectory
from tf_agents.utils import common

 

Hyperparameter

 env_name = "MinitaurBulletEnv-v0" # @param {type:"string"}

# use "num_iterations = 1e6" for better results,
# 1e5 is just so this doesn't take too long. 
num_iterations = 100000 # @param {type:"integer"}

initial_collect_steps = 10000 # @param {type:"integer"} 
collect_steps_per_iteration = 1 # @param {type:"integer"}
replay_buffer_capacity = 1000000 # @param {type:"integer"}

batch_size = 256 # @param {type:"integer"}

critic_learning_rate = 3e-4 # @param {type:"number"}
actor_learning_rate = 3e-4 # @param {type:"number"}
alpha_learning_rate = 3e-4 # @param {type:"number"}
target_update_tau = 0.005 # @param {type:"number"}
target_update_period = 1 # @param {type:"number"}
gamma = 0.99 # @param {type:"number"}
reward_scale_factor = 1.0 # @param {type:"number"}
gradient_clipping = None # @param

actor_fc_layer_params = (256, 256)
critic_joint_fc_layer_params = (256, 256)

log_interval = 5000 # @param {type:"integer"}

num_eval_episodes = 30 # @param {type:"integer"}
eval_interval = 10000 # @param {type:"integer"}
 

Lingkungan Hidup

Lingkungan di RL mewakili tugas atau masalah yang kami coba selesaikan. Lingkungan standar dapat dengan mudah dibuat dalam TF-Agents menggunakan suites . Kami memiliki suites berbeda untuk memuat lingkungan dari sumber seperti OpenAI Gym, Atari, DM Control, dll., Diberi nama lingkungan string.

Sekarang mari kita memuat lingkungan Minituar dari suite Pybullet.

 env = suite_pybullet.load(env_name)
env.reset()
PIL.Image.fromarray(env.render())
 
current_dir=/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/pybullet_envs/bullet
urdf_root=/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/pybullet_data
options= 

/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/gym/logger.py:30: UserWarning: WARN: gym.spaces.Box autodetected dtype as <class 'numpy.float32'>. Please provide explicit dtype.
  warnings.warn(colorize('%s: %s'%('WARN', msg % args), 'yellow'))

png

Dalam lingkungan ini tujuannya adalah agar agen melatih kebijakan yang akan mengendalikan robot Minitaur dan membuatnya bergerak maju secepat mungkin. Episode 1000 langkah terakhir dan pengembalian akan menjadi jumlah hadiah sepanjang episode.

Mari kita lihat informasi yang disediakan oleh lingkungan sebagai observation yang akan digunakan kebijakan untuk menghasilkan actions .

 print('Observation Spec:')
print(env.time_step_spec().observation)
print('Action Spec:')
print(env.action_spec())
 
Observation Spec:
BoundedArraySpec(shape=(28,), dtype=dtype('float32'), name='observation', minimum=[  -3.1515927   -3.1515927   -3.1515927   -3.1515927   -3.1515927
   -3.1515927   -3.1515927   -3.1515927 -167.72488   -167.72488
 -167.72488   -167.72488   -167.72488   -167.72488   -167.72488
 -167.72488     -5.71        -5.71        -5.71        -5.71
   -5.71        -5.71        -5.71        -5.71        -1.01
   -1.01        -1.01        -1.01     ], maximum=[  3.1515927   3.1515927   3.1515927   3.1515927   3.1515927   3.1515927
   3.1515927   3.1515927 167.72488   167.72488   167.72488   167.72488
 167.72488   167.72488   167.72488   167.72488     5.71        5.71
   5.71        5.71        5.71        5.71        5.71        5.71
   1.01        1.01        1.01        1.01     ])
Action Spec:
BoundedArraySpec(shape=(8,), dtype=dtype('float32'), name='action', minimum=-1.0, maximum=1.0)

Seperti yang bisa kita lihat pengamatannya cukup kompleks. Kami menerima 28 nilai yang mewakili sudut, kecepatan, dan torsi untuk semua motor. Sebagai imbalannya lingkungan mengharapkan 8 nilai untuk tindakan antara [-1, 1] . Ini adalah sudut motor yang diinginkan.

Biasanya kami menciptakan dua lingkungan: satu untuk pelatihan dan satu untuk evaluasi. Sebagian besar lingkungan ditulis dalam python murni, tetapi mereka dapat dengan mudah dikonversi ke TensorFlow menggunakan pembungkus TFPyEnvironment . API lingkungan asli menggunakan array numpy, TFPyEnvironment mengonversinya ke / dari Tensors agar Anda lebih mudah berinteraksi dengan kebijakan dan agen TensorFlow.

 train_py_env = suite_pybullet.load(env_name)
eval_py_env = suite_pybullet.load(env_name)

train_env = tf_py_environment.TFPyEnvironment(train_py_env)
eval_env = tf_py_environment.TFPyEnvironment(eval_py_env)
 
urdf_root=/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/pybullet_data
options= 
urdf_root=/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/pybullet_data
options= 

Agen

Untuk membuat Agen SAC, pertama-tama kita perlu membuat jaringan yang akan dilatihnya. SAC adalah agen aktor-kritik, jadi kita akan membutuhkan dua jaringan.

Pengkritik akan memberi kami estimasi nilai untuk Q(s,a) . Artinya, itu akan menerima sebagai masukan pengamatan dan tindakan, dan itu akan memberi kita perkiraan seberapa baik tindakan itu untuk keadaan yang diberikan.

 observation_spec = train_env.observation_spec()
action_spec = train_env.action_spec()
critic_net = critic_network.CriticNetwork(
    (observation_spec, action_spec),
    observation_fc_layer_params=None,
    action_fc_layer_params=None,
    joint_fc_layer_params=critic_joint_fc_layer_params)
 

Kami akan menggunakan kritik ini untuk melatih jaringan actor yang akan memungkinkan kami untuk menghasilkan tindakan yang diberikan pengamatan.

ActorNetwork akan memprediksi parameter untuk distribusi Normal. Distribusi ini kemudian akan dijadikan sampel, dikondisikan pada pengamatan saat ini, setiap kali kita perlu menghasilkan tindakan.

 def normal_projection_net(action_spec,init_means_output_factor=0.1):
  return normal_projection_network.NormalProjectionNetwork(
      action_spec,
      mean_transform=None,
      state_dependent_std=True,
      init_means_output_factor=init_means_output_factor,
      std_transform=sac_agent.std_clip_transform,
      scale_distribution=True)


actor_net = actor_distribution_network.ActorDistributionNetwork(
    observation_spec,
    action_spec,
    fc_layer_params=actor_fc_layer_params,
    continuous_projection_net=normal_projection_net)
 

Dengan jaringan ini, kita sekarang dapat membuat agen.

 global_step = tf.compat.v1.train.get_or_create_global_step()
tf_agent = sac_agent.SacAgent(
    train_env.time_step_spec(),
    action_spec,
    actor_network=actor_net,
    critic_network=critic_net,
    actor_optimizer=tf.compat.v1.train.AdamOptimizer(
        learning_rate=actor_learning_rate),
    critic_optimizer=tf.compat.v1.train.AdamOptimizer(
        learning_rate=critic_learning_rate),
    alpha_optimizer=tf.compat.v1.train.AdamOptimizer(
        learning_rate=alpha_learning_rate),
    target_update_tau=target_update_tau,
    target_update_period=target_update_period,
    td_errors_loss_fn=tf.compat.v1.losses.mean_squared_error,
    gamma=gamma,
    reward_scale_factor=reward_scale_factor,
    gradient_clipping=gradient_clipping,
    train_step_counter=global_step)
tf_agent.initialize()
 

Kebijakan

Dalam TF-Agents, kebijakan mewakili gagasan standar kebijakan dalam RL: diberi time_step menghasilkan suatu tindakan atau distribusi atas tindakan. Metode utama adalah policy_step = policy.step(time_step) mana policy_step adalah nama tuple PolicyStep(action, state, info) . The policy_step.action adalah action diterapkan pada lingkungan, state mewakili status untuk stateful (RNN) kebijakan dan info dapat berisi informasi tambahan seperti probabilitas log dari tindakan.

Agen berisi dua kebijakan: kebijakan utama (agent.policy) dan kebijakan perilaku yang digunakan untuk pengumpulan data (agent.collect_policy). Untuk evaluasi / penyebaran, kami mengambil tindakan rata-rata dengan membungkus kebijakan utama dengan GreedyPolicy ().

 eval_policy = greedy_policy.GreedyPolicy(tf_agent.policy)
collect_policy = tf_agent.collect_policy
 

Metrik dan Evaluasi

Metrik yang paling umum digunakan untuk mengevaluasi suatu kebijakan adalah pengembalian rata-rata. Pengembalian adalah jumlah imbalan yang diperoleh saat menjalankan kebijakan di suatu lingkungan untuk suatu episode, dan kami biasanya merata-ratakan ini dalam beberapa episode. Kami dapat menghitung metrik pengembalian rata-rata sebagai berikut.

 def compute_avg_return(environment, policy, num_episodes=5):

  total_return = 0.0
  for _ in range(num_episodes):

    time_step = environment.reset()
    episode_return = 0.0

    while not time_step.is_last():
      action_step = policy.action(time_step)
      time_step = environment.step(action_step.action)
      episode_return += time_step.reward
    total_return += episode_return

  avg_return = total_return / num_episodes
  return avg_return.numpy()[0]


compute_avg_return(eval_env, eval_policy, num_eval_episodes)

# Please also see the metrics module for standard implementations of different
# metrics.
 
-0.022013525

Putar ulang Buffer

Untuk melacak data yang dikumpulkan dari lingkungan, kami akan menggunakan TFUniformReplayBuffer. Buangan replay ini dibuat menggunakan spesifikasi yang menggambarkan tensor yang akan disimpan, yang dapat diperoleh dari agen menggunakan tf_agent.collect_data_spec .

 replay_buffer = tf_uniform_replay_buffer.TFUniformReplayBuffer(
    data_spec=tf_agent.collect_data_spec,
    batch_size=train_env.batch_size,
    max_length=replay_buffer_capacity)
 

Untuk sebagian besar agen, collect_data_spec adalah Trajectory bernama tuple yang berisi pengamatan, tindakan, hadiah, dll.

Pengumpulan data

Sekarang kita akan membuat driver untuk mengumpulkan pengalaman untuk menyemai buffer replay. Driver memberikan kami cara sederhana untuk collecter n langkah atau episode pada lingkungan menggunakan kebijakan tertentu.

 initial_collect_driver = dynamic_step_driver.DynamicStepDriver(
        train_env,
        collect_policy,
        observers=[replay_buffer.add_batch],
        num_steps=initial_collect_steps)
initial_collect_driver.run()
 
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tf_agents/drivers/dynamic_step_driver.py:203: calling while_loop_v2 (from tensorflow.python.ops.control_flow_ops) with back_prop=False is deprecated and will be removed in a future version.
Instructions for updating:
back_prop=False is deprecated. Consider using tf.stop_gradient instead.
Instead of:
results = tf.while_loop(c, b, vars, back_prop=False)
Use:
results = tf.nest.map_structure(tf.stop_gradient, tf.while_loop(c, b, vars))

(TimeStep(step_type=<tf.Tensor: shape=(1,), dtype=int32, numpy=array([1], dtype=int32)>, reward=<tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.00101085], dtype=float32)>, discount=<tf.Tensor: shape=(1,), dtype=float32, numpy=array([1.], dtype=float32)>, observation=<tf.Tensor: shape=(1, 28), dtype=float32, numpy=
 array([[  1.308478  ,   2.166422  ,   1.5081352 ,   2.0260656 ,
           2.1123457 ,   1.114552  ,   1.5866141 ,   1.524472  ,
           6.9441314 ,   6.6945276 ,  -7.403659  , -20.185253  ,
          -4.8489103 ,  -1.2003611 , -19.449749  , -16.223652  ,
           4.2634044 ,   0.371617  ,  -0.92654324,  -3.8810008 ,
          -5.7       ,   3.10348   ,  -2.9569836 ,   3.916052  ,
           0.0551226 ,   0.10631521,  -0.09753982,   0.9880003 ]],
       dtype=float32)>),
 ())

Untuk mengambil sampel data dari buffer replay, kami akan membuat pipa tf.data yang dapat kami tf.data ke agen untuk pelatihan nanti. Kami dapat menentukan sample_batch_size untuk mengonfigurasi jumlah item yang diambil dari buffer replay. Kami juga dapat mengoptimalkan pipa data menggunakan panggilan paralel dan pengambilan awal.

Untuk menghemat ruang, kami hanya menyimpan pengamatan saat ini di setiap baris buffer replay. Tetapi karena Agen SAC membutuhkan pengamatan saat ini dan selanjutnya untuk menghitung kerugian, kami selalu mencicipi dua baris yang berdekatan untuk setiap item dalam batch dengan menetapkan num_steps=2 .

 # Dataset generates trajectories with shape [Bx2x...]
dataset = replay_buffer.as_dataset(
    num_parallel_calls=3, sample_batch_size=batch_size, num_steps=2).prefetch(3)

iterator = iter(dataset)
 
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/autograph/operators/control_flow.py:1004: ReplayBuffer.get_next (from tf_agents.replay_buffers.replay_buffer) is deprecated and will be removed in a future version.
Instructions for updating:
Use `as_dataset(..., single_deterministic_pass=False) instead.

Melatih agen

Lingkaran pelatihan melibatkan pengumpulan data dari lingkungan dan mengoptimalkan jaringan agen. Sepanjang jalan, kami sesekali akan mengevaluasi kebijakan agen untuk melihat apa yang kami lakukan.

 collect_driver = dynamic_step_driver.DynamicStepDriver(
    train_env,
    collect_policy,
    observers=[replay_buffer.add_batch],
    num_steps=collect_steps_per_iteration)
 
 
try:
  %%time
except:
  pass

# (Optional) Optimize by wrapping some of the code in a graph using TF function.
tf_agent.train = common.function(tf_agent.train)
collect_driver.run = common.function(collect_driver.run)

# Reset the train step
tf_agent.train_step_counter.assign(0)

# Evaluate the agent's policy once before training.
avg_return = compute_avg_return(eval_env, eval_policy, num_eval_episodes)
returns = [avg_return]

for _ in range(num_iterations):

  # Collect a few steps using collect_policy and save to the replay buffer.
  collect_driver.run()

  # Sample a batch of data from the buffer and update the agent's network.
  experience, unused_info = next(iterator)
  train_loss = tf_agent.train(experience)

  step = tf_agent.train_step_counter.numpy()

  if step % log_interval == 0:
    print('step = {0}: loss = {1}'.format(step, train_loss.loss))

  if step % eval_interval == 0:
    avg_return = compute_avg_return(eval_env, eval_policy, num_eval_episodes)
    print('step = {0}: Average Return = {1}'.format(step, avg_return))
    returns.append(avg_return)
 
WARNING:absl:Need to use a loss function that computes losses per sample, ex: replace losses.mean_squared_error with tf.math.squared_difference. Invalid value passed for `per_example_loss`. Expected a tensor tensor with at least rank 1, received: Tensor("critic_loss/add_1:0", shape=(), dtype=float32)
WARNING:absl:Need to use a loss function that computes losses per sample, ex: replace losses.mean_squared_error with tf.math.squared_difference. Invalid value passed for `per_example_loss`. Expected a tensor tensor with at least rank 1, received: Tensor("critic_loss/add_1:0", shape=(), dtype=float32)

step = 5000: loss = -63.16588592529297
step = 10000: loss = -61.471351623535156
step = 10000: Average Return = 0.07441557198762894
step = 15000: loss = -31.185678482055664
step = 20000: loss = -18.064279556274414
step = 20000: Average Return = -0.12959735095500946
step = 25000: loss = -15.05502986907959
step = 30000: loss = -12.023421287536621
step = 30000: Average Return = -1.4209648370742798
step = 35000: loss = -5.994253635406494
step = 40000: loss = -3.944823741912842
step = 40000: Average Return = -0.6664859652519226
step = 45000: loss = 0.3637888431549072
step = 50000: loss = -3.2982077598571777
step = 50000: Average Return = 0.0521695651113987
step = 55000: loss = -2.7744715213775635
step = 60000: loss = 1.7074693441390991
step = 60000: Average Return = -0.3222312033176422
step = 65000: loss = -1.8334136009216309
step = 70000: loss = -1.4784929752349854
step = 70000: Average Return = 0.6373701095581055
step = 75000: loss = 0.48983949422836304
step = 80000: loss = 1.5974589586257935
step = 80000: Average Return = 0.1859637051820755
step = 85000: loss = -5.309885501861572
step = 90000: loss = 0.42465153336524963
step = 90000: Average Return = 0.8508636951446533
step = 95000: loss = -6.7512335777282715
step = 100000: loss = 1.8088481426239014
step = 100000: Average Return = 0.24124357104301453

Visualisasi

Plot

Kami dapat merencanakan pengembalian rata-rata vs langkah-langkah global untuk melihat kinerja agen kami. Di Minitaur , fungsi hadiah didasarkan pada seberapa jauh minitaur berjalan dalam 1000 langkah dan menghukum pengeluaran energi.

 

steps = range(0, num_iterations + 1, eval_interval)
plt.plot(steps, returns)
plt.ylabel('Average Return')
plt.xlabel('Step')
plt.ylim()
 
(-1.5345562636852264, 0.9644551217556)

png

Video

Akan sangat membantu untuk memvisualisasikan kinerja agen dengan memberikan lingkungan pada setiap langkah. Sebelum kita melakukannya, mari kita membuat fungsi untuk menanamkan video di colab ini.

 def embed_mp4(filename):
  """Embeds an mp4 file in the notebook."""
  video = open(filename,'rb').read()
  b64 = base64.b64encode(video)
  tag = '''
  <video width="640" height="480" controls>
    <source src="data:video/mp4;base64,{0}" type="video/mp4">
  Your browser does not support the video tag.
  </video>'''.format(b64.decode())

  return IPython.display.HTML(tag)
 

Kode berikut memvisualisasikan kebijakan agen untuk beberapa episode:

 num_episodes = 3
video_filename = 'sac_minitaur.mp4'
with imageio.get_writer(video_filename, fps=60) as video:
  for _ in range(num_episodes):
    time_step = eval_env.reset()
    video.append_data(eval_py_env.render())
    while not time_step.is_last():
      action_step = tf_agent.policy.action(time_step)
      time_step = eval_env.step(action_step.action)
      video.append_data(eval_py_env.render())

embed_mp4(video_filename)