REINFORCE এজেন্ট

TensorFlow.org এ দেখুন Google Colab-এ চালান GitHub-এ উৎস দেখুন নোটবুক ডাউনলোড করুন

ভূমিকা

নিচের উদাহরনের মাধ্যমে দেখানো কিভাবে প্রশিক্ষণের পুনরায় বলবৎ মেমরি-এজেন্ট গ্রন্থাগার, অনুরূপ ব্যবহার Cartpole পরিবেশের উপর এজেন্ট DQN টিউটোরিয়াল

কার্টপোল পরিবেশ

আমরা আপনাকে প্রশিক্ষণ, মূল্যায়ন এবং ডেটা সংগ্রহের জন্য একটি রিইনফোর্সমেন্ট লার্নিং (RL) পাইপলাইনের সমস্ত উপাদানের মধ্য দিয়ে নিয়ে যাব।

সেটআপ

আপনি যদি নিম্নলিখিত নির্ভরতাগুলি ইনস্টল না করে থাকেন তবে চালান:

sudo apt-get update
sudo apt-get install -y xvfb ffmpeg freeglut3-dev
pip install 'imageio==2.4.0'
pip install pyvirtualdisplay
pip install tf-agents[reverb]
pip install pyglet xvfbwrapper
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import base64
import imageio
import IPython
import matplotlib.pyplot as plt
import numpy as np
import PIL.Image
import pyvirtualdisplay
import reverb

import tensorflow as tf

from tf_agents.agents.reinforce import reinforce_agent
from tf_agents.drivers import py_driver
from tf_agents.environments import suite_gym
from tf_agents.environments import tf_py_environment
from tf_agents.networks import actor_distribution_network
from tf_agents.policies import py_tf_eager_policy
from tf_agents.replay_buffers import reverb_replay_buffer
from tf_agents.replay_buffers import reverb_utils
from tf_agents.specs import tensor_spec
from tf_agents.trajectories import trajectory
from tf_agents.utils import common

# Set up a virtual display for rendering OpenAI gym environments.
display = pyvirtualdisplay.Display(visible=0, size=(1400, 900)).start()

হাইপারপ্যারামিটার

env_name = "CartPole-v0" # @param {type:"string"}
num_iterations = 250 # @param {type:"integer"}
collect_episodes_per_iteration = 2 # @param {type:"integer"}
replay_buffer_capacity = 2000 # @param {type:"integer"}

fc_layer_params = (100,)

learning_rate = 1e-3 # @param {type:"number"}
log_interval = 25 # @param {type:"integer"}
num_eval_episodes = 10 # @param {type:"integer"}
eval_interval = 50 # @param {type:"integer"}

পরিবেশ

RL-এর পরিবেশগুলি সেই কাজ বা সমস্যার প্রতিনিধিত্ব করে যা আমরা সমাধান করার চেষ্টা করছি। স্ট্যান্ডার্ড পরিবেশের সহজে ব্যবহার মেমরি-এজেন্ট এবং তৈরি করা যেতে পারে suites । আমরা বিভিন্ন আছে suites যেমন OpenAI জিম, Atari -এ, ডিএম নিয়ন্ত্রণ, ইত্যাদি উৎস থেকে পরিবেশের লোড একটি স্ট্রিং পরিবেশ নাম দেওয়া জন্য।

এখন ওপেনএআই জিম স্যুট থেকে কার্টপোল পরিবেশ লোড করা যাক।

env = suite_gym.load(env_name)

আমরা এই পরিবেশটি দেখতে কেমন তা দেখতে পারি। একটি ফ্রি-সুইংিং খুঁটি একটি কার্টের সাথে সংযুক্ত। লক্ষ্য হল কার্টটিকে ডানে বা বামে সরানো যাতে মেরুটি উপরে থাকে।

env.reset()
PIL.Image.fromarray(env.render())

png

time_step = environment.step(action) বিবৃতি লাগে action পরিবেশে। TimeStep tuple ফিরে পরিবেশ এর পরের পর্যবেক্ষণ ও ক্রিয়াটি জন্য পুরস্কার রয়েছে। time_step_spec() এবং action_spec() পরিবেশে পদ্ধতির উল্লেখ (ধরনের, আকৃতি সীমার) আসতে time_step এবং action যথাক্রমে।

print('Observation Spec:')
print(env.time_step_spec().observation)
print('Action Spec:')
print(env.action_spec())
Observation Spec:
BoundedArraySpec(shape=(4,), dtype=dtype('float32'), name='observation', minimum=[-4.8000002e+00 -3.4028235e+38 -4.1887903e-01 -3.4028235e+38], maximum=[4.8000002e+00 3.4028235e+38 4.1887903e-01 3.4028235e+38])
Action Spec:
BoundedArraySpec(shape=(), dtype=dtype('int64'), name='action', minimum=0, maximum=1)

সুতরাং, আমরা দেখতে পাচ্ছি যে পর্যবেক্ষণ হল 4টি ফ্লোটের একটি অ্যারে: কার্টের অবস্থান এবং বেগ এবং মেরুটির কৌণিক অবস্থান এবং বেগ। যেহেতু মাত্র দুটি ক্রিয়া সম্ভব হয় (পদক্ষেপ বাম বা ডান সরাতে), action_spec স্কেলের যেখানে 0 মানে হলো "পদক্ষেপ left" এবং 1 মানে হল "পদক্ষেপ ঠিক আছে।"

time_step = env.reset()
print('Time step:')
print(time_step)

action = np.array(1, dtype=np.int32)

next_time_step = env.step(action)
print('Next time step:')
print(next_time_step)
Time step:
TimeStep(
{'discount': array(1., dtype=float32),
 'observation': array([ 0.02284177, -0.04785635,  0.04171623,  0.04942273], dtype=float32),
 'reward': array(0., dtype=float32),
 'step_type': array(0, dtype=int32)})
Next time step:
TimeStep(
{'discount': array(1., dtype=float32),
 'observation': array([ 0.02188464,  0.14664337,  0.04270469, -0.22981201], dtype=float32),
 'reward': array(1., dtype=float32),
 'step_type': array(1, dtype=int32)})

সাধারণত আমরা দুটি পরিবেশ তৈরি করি: একটি প্রশিক্ষণের জন্য এবং একটি মূল্যায়নের জন্য। সর্বাধিক পরিবেশের বিশুদ্ধ পাইথন লেখা হয়, কিন্তু তারা সহজে ব্যবহার TensorFlow রূপান্তরিত করা যেতে পারে TFPyEnvironment মোড়কের। মূল পরিবেশ এর API- numpy অ্যারে ব্যবহার করে, TFPyEnvironment এই / থেকে পরিবর্তন করে Tensors আপনাকে জন্য আরও সহজে ইন্টারঅ্যাক্ট TensorFlow নীতি ও এজেন্টদের সঙ্গে।

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

train_env = tf_py_environment.TFPyEnvironment(train_py_env)
eval_env = tf_py_environment.TFPyEnvironment(eval_py_env)

প্রতিনিধি

অ্যালগরিদম যে আমরা একটি আরএল সমস্যা সমাধানের জন্য ব্যবহার একটি হিসাবে প্রতিনিধিত্ব করা হয় Agent । পুনরায় বলবৎ এজেন্ট ছাড়াও, মেমরি-এজেন্ট বিভিন্ন মান বাস্তবায়নের উপলব্ধ Agents যেমন DQN , DDPG , TD3 , PPO এবং এসএসি

একটি শক্তিশালী এজেন্ট তৈরি করতে হলে, আমরা প্রথমে একটি প্রয়োজন Actor Network যে পরিবেশ থেকে একটি পর্যবেক্ষণ দেওয়া কর্ম ভবিষ্যদ্বাণী করা শিখতে পারেন।

অতি সহজেই একটা তৈরি করতে পারেন Actor Network পর্যবেক্ষণ এবং কর্মের চশমা ব্যবহার করে। আমরা নেটওয়ার্কে যা এই উদাহরণে, হয় স্তর নির্দিষ্ট করতে পারেন fc_layer_params একটি tuple আর্গুমেন্ট প্রাপ্ত করতে সেট ints প্রতিটি গোপন স্তর মাপ (উপরে Hyperparameters অধ্যায় দেখুন) উপস্থাপন করে।

actor_net = actor_distribution_network.ActorDistributionNetwork(
    train_env.observation_spec(),
    train_env.action_spec(),
    fc_layer_params=fc_layer_params)

আমরা একটি প্রয়োজন optimizer নেটওয়ার্কের আমরা শুধু নির্মিত প্রশিক্ষণের, এবং একটি train_step_counter কতবার নেটওয়ার্কের আপডেট করা হয়েছে ট্র্যাক রাখতে পরিবর্তনশীল।

optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)

train_step_counter = tf.Variable(0)

tf_agent = reinforce_agent.ReinforceAgent(
    train_env.time_step_spec(),
    train_env.action_spec(),
    actor_network=actor_net,
    optimizer=optimizer,
    normalize_returns=True,
    train_step_counter=train_step_counter)
tf_agent.initialize()

নীতিমালা

মেমরি-এজেন্ট, নীতি আরএল মধ্যে নীতি মান ধারণা প্রতিনিধিত্ব: একটি প্রদত্ত time_step একটি কর্ম বা কর্মের উপর একটি বিতরণ উত্পাদন। প্রধান পদ্ধতি policy_step = policy.action(time_step) যেখানে policy_step একটি নামাঙ্কিত tuple হয় PolicyStep(action, state, info)policy_step.action হয় action পরিবেশ প্রয়োগ করা, state stateful (RNN) নীতি ও প্রতিমন্ত্রী প্রতিনিধিত্ব করে info যেমন কর্ম লগ সম্ভাব্যতা যেমন অক্জিলিয়ারী তথ্য থাকতে পারে।

এজেন্ট দুটি নীতি ধারণ করে: মূল নীতি যা মূল্যায়ন/নিয়োগের জন্য ব্যবহৃত হয় (agent.policy) এবং আরেকটি নীতি যা ডেটা সংগ্রহের জন্য ব্যবহৃত হয় (agent.collect_policy)।

eval_policy = tf_agent.policy
collect_policy = tf_agent.collect_policy

মেট্রিক্স এবং মূল্যায়ন

একটি নীতি মূল্যায়ন করতে ব্যবহৃত সবচেয়ে সাধারণ মেট্রিক হল গড় রিটার্ন। রিটার্ন হল একটি পর্বের জন্য একটি পরিবেশে একটি নীতি চালানোর সময় প্রাপ্ত পুরষ্কারের সমষ্টি এবং আমরা সাধারণত এটিকে কয়েকটি পর্বে গড় করি। আমরা নিম্নরূপ গড় রিটার্ন মেট্রিক গণনা করতে পারি।

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

  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]


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

রিপ্লে বাফার

অর্ডার পরিবেশ থেকে সংগৃহীত ডেটা ট্র্যাক রাখতে করার জন্য, আমরা ব্যবহার করবে প্রতিধ্বনি , Deepmind দ্বারা একটি, দক্ষ প্রসার্য এবং সহজ-থেকে-ব্যবহার রিপ্লে সিস্টেম। আমরা যখন ট্রাজেক্টোরি সংগ্রহ করি এবং প্রশিক্ষণের সময় ব্যবহার করা হয় তখন এটি অভিজ্ঞতার ডেটা সঞ্চয় করে।

এই রিপ্লে বাফার tensors এই সঞ্চিত হবে, যা ব্যবহার করে এজেন্ট থেকে প্রাপ্ত করা যাবে বর্ণনা চশমা ব্যবহার করে নির্মিত হয় tf_agent.collect_data_spec

table_name = 'uniform_table'
replay_buffer_signature = tensor_spec.from_spec(
      tf_agent.collect_data_spec)
replay_buffer_signature = tensor_spec.add_outer_dim(
      replay_buffer_signature)
table = reverb.Table(
    table_name,
    max_size=replay_buffer_capacity,
    sampler=reverb.selectors.Uniform(),
    remover=reverb.selectors.Fifo(),
    rate_limiter=reverb.rate_limiters.MinSize(1),
    signature=replay_buffer_signature)

reverb_server = reverb.Server([table])

replay_buffer = reverb_replay_buffer.ReverbReplayBuffer(
    tf_agent.collect_data_spec,
    table_name=table_name,
    sequence_length=None,
    local_server=reverb_server)

rb_observer = reverb_utils.ReverbAddEpisodeObserver(
    replay_buffer.py_client,
    table_name,
    replay_buffer_capacity
)
[reverb/cc/platform/tfrecord_checkpointer.cc:150]  Initializing TFRecordCheckpointer in /tmp/tmpem6la471.
[reverb/cc/platform/tfrecord_checkpointer.cc:385] Loading latest checkpoint from /tmp/tmpem6la471
[reverb/cc/platform/default/server.cc:71] Started replay server on port 19822

সবচেয়ে এজেন্ট জন্য, collect_data_spec একটি হল Trajectory পর্যবেক্ষণ, কর্ম ধারণকারী tuple নামে, পুরস্কৃত ইত্যাদি

তথ্য সংগ্রহ

যেহেতু REINFORCE পুরো পর্বগুলি থেকে শেখে, আমরা প্রদত্ত ডেটা সংগ্রহ নীতি ব্যবহার করে একটি পর্ব সংগ্রহ করার জন্য একটি ফাংশন সংজ্ঞায়িত করি এবং রিপ্লে বাফারে ট্রাজেক্টোরি হিসাবে ডেটা (পর্যবেক্ষণ, ক্রিয়া, পুরষ্কার ইত্যাদি) সংরক্ষণ করি। এখানে আমরা 'PyDriver' ব্যবহার করছি লুপ সংগ্রহ করার অভিজ্ঞতা চালানোর জন্য। আপনি যদি আমাদের মধ্যে মেমরি এজেন্ট চালক সম্পর্কে আরও জানতে পারেন ড্রাইভার টিউটোরিয়াল

def collect_episode(environment, policy, num_episodes):

  driver = py_driver.PyDriver(
    environment,
    py_tf_eager_policy.PyTFEagerPolicy(
      policy, use_tf_function=True),
    [rb_observer],
    max_episodes=num_episodes)
  initial_time_step = environment.reset()
  driver.run(initial_time_step)

এজেন্ট প্রশিক্ষণ

প্রশিক্ষণ লুপে পরিবেশ থেকে তথ্য সংগ্রহ এবং এজেন্টের নেটওয়ার্ক অপ্টিমাইজ করা উভয়ই জড়িত। পথের পাশাপাশি, আমরা কীভাবে কাজ করছি তা দেখতে আমরা মাঝে মাঝে এজেন্টের নীতি মূল্যায়ন করব।

নিম্নলিখিতটি চালাতে ~3 মিনিট সময় লাগবে৷

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)

# 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, tf_agent.policy, num_eval_episodes)
returns = [avg_return]

for _ in range(num_iterations):

  # Collect a few episodes using collect_policy and save to the replay buffer.
  collect_episode(
      train_py_env, tf_agent.collect_policy, collect_episodes_per_iteration)

  # Use data from the buffer and update the agent's network.
  iterator = iter(replay_buffer.as_dataset(sample_batch_size=1))
  trajectories, _ = next(iterator)
  train_loss = tf_agent.train(experience=trajectories)  

  replay_buffer.clear()

  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, tf_agent.policy, num_eval_episodes)
    print('step = {0}: Average Return = {1}'.format(step, avg_return))
    returns.append(avg_return)
[reverb/cc/client.cc:163] Sampler and server are owned by the same process (20164) so Table uniform_table is accessed directly without gRPC.
[reverb/cc/client.cc:163] Sampler and server are owned by the same process (20164) so Table uniform_table is accessed directly without gRPC.
[reverb/cc/client.cc:163] Sampler and server are owned by the same process (20164) so Table uniform_table is accessed directly without gRPC.
[reverb/cc/client.cc:163] Sampler and server are owned by the same process (20164) so Table uniform_table is accessed directly without gRPC.
[reverb/cc/client.cc:163] Sampler and server are owned by the same process (20164) so Table uniform_table is accessed directly without gRPC.
step = 25: loss = 0.8549901247024536
[reverb/cc/client.cc:163] Sampler and server are owned by the same process (20164) so Table uniform_table is accessed directly without gRPC.
step = 50: loss = 1.0025296211242676
step = 50: Average Return = 23.200000762939453
[reverb/cc/client.cc:163] Sampler and server are owned by the same process (20164) so Table uniform_table is accessed directly without gRPC.
step = 75: loss = 1.1377763748168945
step = 100: loss = 1.318871021270752
step = 100: Average Return = 159.89999389648438
step = 125: loss = 1.5053682327270508
[reverb/cc/client.cc:163] Sampler and server are owned by the same process (20164) so Table uniform_table is accessed directly without gRPC.
step = 150: loss = 0.8051948547363281
step = 150: Average Return = 184.89999389648438
step = 175: loss = 0.6872963905334473
step = 200: loss = 2.7238712310791016
step = 200: Average Return = 186.8000030517578
step = 225: loss = 0.7495002746582031
step = 250: loss = -0.3333401679992676
step = 250: Average Return = 200.0

ভিজ্যুয়ালাইজেশন

প্লট

আমাদের এজেন্টের পারফরম্যান্স দেখার জন্য আমরা রিটার্ন বনাম বিশ্বব্যাপী পদক্ষেপের পরিকল্পনা করতে পারি। ইন Cartpole-v0 , পরিবেশ +1 টি একটি পুরস্কার প্রত্যেক সময় ধাপের জন্য মেরু থাকার বিষয়টি মতেই মানেনা এবং যেহেতু ধাপের সর্বোচ্চ সংখ্যক 200, সর্বোচ্চ সম্ভব আগমন এছাড়াও 200 হয়।

steps = range(0, num_iterations + 1, eval_interval)
plt.plot(steps, returns)
plt.ylabel('Average Return')
plt.xlabel('Step')
plt.ylim(top=250)
(-0.2349997997283939, 250.0)

png

ভিডিও

প্রতিটি ধাপে পরিবেশ রেন্ডার করে একটি এজেন্টের কর্মক্ষমতা কল্পনা করা সহায়ক। এটি করার আগে, আসুন প্রথমে এই কোল্যাবে ভিডিও এম্বেড করার জন্য একটি ফাংশন তৈরি করি।

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)

নিম্নলিখিত কোডটি কয়েকটি পর্বের জন্য এজেন্টের নীতিকে কল্পনা করে:

num_episodes = 3
video_filename = 'imageio.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)
WARNING:root:IMAGEIO FFMPEG_WRITER WARNING: input image is not divisible by macro_block_size=16, resizing from (400, 600) to (400, 608) to ensure video compatibility with most codecs and players. To prevent resizing, make your input image divisible by the macro_block_size or set the macro_block_size to None (risking incompatibility). You may also see a FFMPEG warning concerning speedloss due to data not being aligned.
[swscaler @ 0x5604d224f3c0] Warning: data is not aligned! This can lead to a speed loss