অভিনেতা-সমালোচক পদ্ধতির সাথে CartPole খেলা

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

ওপেন এআই জিম কার্টপোল-ভি0 পরিবেশে একজন এজেন্টকে প্রশিক্ষণ দেওয়ার জন্য টেনসরফ্লো ব্যবহার করে অভিনেতা-সমালোচক পদ্ধতি কীভাবে প্রয়োগ করা যায় এই টিউটোরিয়ালটি দেখায়। পাঠকের শক্তিবৃদ্ধি শেখার নীতি গ্রেডিয়েন্ট পদ্ধতির সাথে কিছু পরিচিতি আছে বলে ধরে নেওয়া হয়।

অভিনেতা-সমালোচক পদ্ধতি

অভিনেতা-সমালোচক পদ্ধতি হল টেম্পোরাল ডিফারেন্স (TD) শেখার পদ্ধতি যা পলিসি ফাংশনকে মান ফাংশন থেকে স্বাধীনভাবে উপস্থাপন করে।

একটি নীতি ফাংশন (বা নীতি) প্রদত্ত অবস্থার উপর ভিত্তি করে এজেন্ট গ্রহণ করতে পারে এমন কর্মের উপর একটি সম্ভাব্যতা বন্টন প্রদান করে। একটি মান ফাংশন একটি এজেন্টের জন্য প্রত্যাশিত রিটার্ন নির্ধারণ করে যা একটি প্রদত্ত অবস্থা থেকে শুরু করে এবং একটি নির্দিষ্ট নীতি অনুসারে কাজ করে।

অভিনেতা-সমালোচক পদ্ধতিতে, নীতিটিকে অভিনেতা হিসাবে উল্লেখ করা হয় যেটি একটি রাষ্ট্রকে দেওয়া সম্ভাব্য ক্রিয়াগুলির একটি সেট প্রস্তাব করে এবং আনুমানিক মান ফাংশনটিকে সমালোচক হিসাবে উল্লেখ করা হয়, যা প্রদত্ত নীতির উপর ভিত্তি করে অভিনেতার গৃহীত পদক্ষেপগুলি মূল্যায়ন করে। .

এই টিউটোরিয়ালে, অভিনেতা এবং সমালোচক উভয়কেই দুটি আউটপুট সহ একটি নিউরাল নেটওয়ার্ক ব্যবহার করে উপস্থাপন করা হবে।

CartPole-v0

CartPole-v0 পরিবেশে , ঘর্ষণহীন ট্র্যাক বরাবর চলমান একটি কার্টের সাথে একটি খুঁটি সংযুক্ত থাকে। মেরুটি সোজা শুরু হয় এবং এজেন্টের লক্ষ্য হল কার্টে -1 বা +1 বল প্রয়োগ করে এটিকে পড়ে যাওয়া থেকে রোধ করা। প্রতিবার মেরুটি সোজা রাখার জন্য +1 এর একটি পুরষ্কার দেওয়া হয়৷ একটি পর্ব শেষ হয় যখন (1) মেরুটি উল্লম্ব থেকে 15 ডিগ্রির বেশি বা (2) কার্টটি কেন্দ্র থেকে 2.4 ইউনিটের বেশি সরে যায়।

Cartpole-v0 পরিবেশে প্রশিক্ষিত অভিনেতা-সমালোচক মডেল

সমস্যাটি "সমাধান" বলে বিবেচিত হয় যখন পর্বের জন্য মোট পুরস্কার 100টি পরপর ট্রায়ালে 195 এ পৌঁছায়।

সেটআপ

প্রয়োজনীয় প্যাকেজ আমদানি করুন এবং বিশ্বব্যাপী সেটিংস কনফিগার করুন।

pip install gym
pip install pyglet
# Install additional packages for visualization
sudo apt-get install -y xvfb python-opengl > /dev/null 2>&1
pip install pyvirtualdisplay > /dev/null 2>&1
pip install git+https://github.com/tensorflow/docs > /dev/null 2>&1
import collections
import gym
import numpy as np
import statistics
import tensorflow as tf
import tqdm

from matplotlib import pyplot as plt
from tensorflow.keras import layers
from typing import Any, List, Sequence, Tuple


# Create the environment
env = gym.make("CartPole-v0")

# Set seed for experiment reproducibility
seed = 42
env.seed(seed)
tf.random.set_seed(seed)
np.random.seed(seed)

# Small epsilon value for stabilizing division operations
eps = np.finfo(np.float32).eps.item()

মডেল

অভিনেতা এবং সমালোচককে একটি নিউরাল নেটওয়ার্ক ব্যবহার করে মডেল করা হবে যা যথাক্রমে অ্যাকশন সম্ভাব্যতা এবং সমালোচকের মান তৈরি করে। এই টিউটোরিয়ালটি মডেলকে সংজ্ঞায়িত করতে মডেল সাবক্লাসিং ব্যবহার করে।

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

Cartpole-v0-এর জন্য, রাষ্ট্রের প্রতিনিধিত্বকারী চারটি মান রয়েছে: যথাক্রমে কার্ট অবস্থান, কার্ট-বেগ, মেরু কোণ এবং মেরু বেগ। এজেন্ট কার্টটিকে যথাক্রমে বাম (0) এবং ডানে (1) ঠেলে দুটি পদক্ষেপ নিতে পারে।

আরও তথ্যের জন্য OpenAI Gym-এর CartPole-v0 উইকি পৃষ্ঠা পড়ুন।

class ActorCritic(tf.keras.Model):
  """Combined actor-critic network."""

  def __init__(
      self, 
      num_actions: int, 
      num_hidden_units: int):
    """Initialize."""
    super().__init__()

    self.common = layers.Dense(num_hidden_units, activation="relu")
    self.actor = layers.Dense(num_actions)
    self.critic = layers.Dense(1)

  def call(self, inputs: tf.Tensor) -> Tuple[tf.Tensor, tf.Tensor]:
    x = self.common(inputs)
    return self.actor(x), self.critic(x)
num_actions = env.action_space.n  # 2
num_hidden_units = 128

model = ActorCritic(num_actions, num_hidden_units)

প্রশিক্ষণ

এজেন্টকে প্রশিক্ষণ দিতে, আপনি এই পদক্ষেপগুলি অনুসরণ করবেন:

  1. প্রতি পর্বে প্রশিক্ষণের তথ্য সংগ্রহ করতে পরিবেশে এজেন্ট চালান।
  2. প্রতিটি সময় ধাপে প্রত্যাশিত রিটার্ন গণনা করুন।
  3. সম্মিলিত অভিনেতা-সমালোচক মডেলের জন্য ক্ষতি গণনা করুন।
  4. গ্রেডিয়েন্ট গণনা করুন এবং নেটওয়ার্ক প্যারামিটার আপডেট করুন।
  5. 1-4 পুনরাবৃত্তি করুন যতক্ষণ না হয় সাফল্যের মাপকাঠি বা সর্বোচ্চ পর্বে পৌঁছানো হয়।

1. প্রশিক্ষণের তথ্য সংগ্রহ করা

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

প্রতিটি পর্বের জন্য প্রশিক্ষণের তথ্য সংগ্রহ করা হয়। তারপর প্রতিটি ধাপে, মডেলের ফরোয়ার্ড পাস পরিবেশের অবস্থার উপর চালিত হবে যাতে মডেলের ওজন দ্বারা নির্ধারিত বর্তমান নীতির উপর ভিত্তি করে অ্যাকশন সম্ভাব্যতা এবং সমালোচক মান তৈরি করা হয়।

পরবর্তী ক্রিয়াটি মডেল দ্বারা উত্পন্ন ক্রিয়া সম্ভাব্যতা থেকে নমুনা করা হবে, যা তারপর পরিবেশে প্রয়োগ করা হবে, যার ফলে পরবর্তী অবস্থা এবং পুরষ্কার তৈরি করা হবে।

এই প্রক্রিয়াটি run_episode ফাংশনে প্রয়োগ করা হয়, যা TensorFlow অপারেশন ব্যবহার করে যাতে এটি দ্রুত প্রশিক্ষণের জন্য পরবর্তীতে একটি TensorFlow গ্রাফে কম্পাইল করা যায়। নোট করুন যে tf.TensorArray s পরিবর্তনশীল দৈর্ঘ্যের অ্যারেতে টেনসর পুনরাবৃত্তি সমর্থন করতে ব্যবহৃত হয়েছিল।

# Wrap OpenAI Gym's `env.step` call as an operation in a TensorFlow function.
# This would allow it to be included in a callable TensorFlow graph.

def env_step(action: np.ndarray) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
  """Returns state, reward and done flag given an action."""

  state, reward, done, _ = env.step(action)
  return (state.astype(np.float32), 
          np.array(reward, np.int32), 
          np.array(done, np.int32))


def tf_env_step(action: tf.Tensor) -> List[tf.Tensor]:
  return tf.numpy_function(env_step, [action], 
                           [tf.float32, tf.int32, tf.int32])
def run_episode(
    initial_state: tf.Tensor,  
    model: tf.keras.Model, 
    max_steps: int) -> Tuple[tf.Tensor, tf.Tensor, tf.Tensor]:
  """Runs a single episode to collect training data."""

  action_probs = tf.TensorArray(dtype=tf.float32, size=0, dynamic_size=True)
  values = tf.TensorArray(dtype=tf.float32, size=0, dynamic_size=True)
  rewards = tf.TensorArray(dtype=tf.int32, size=0, dynamic_size=True)

  initial_state_shape = initial_state.shape
  state = initial_state

  for t in tf.range(max_steps):
    # Convert state into a batched tensor (batch size = 1)
    state = tf.expand_dims(state, 0)

    # Run the model and to get action probabilities and critic value
    action_logits_t, value = model(state)

    # Sample next action from the action probability distribution
    action = tf.random.categorical(action_logits_t, 1)[0, 0]
    action_probs_t = tf.nn.softmax(action_logits_t)

    # Store critic values
    values = values.write(t, tf.squeeze(value))

    # Store log probability of the action chosen
    action_probs = action_probs.write(t, action_probs_t[0, action])

    # Apply action to the environment to get next state and reward
    state, reward, done = tf_env_step(action)
    state.set_shape(initial_state_shape)

    # Store reward
    rewards = rewards.write(t, reward)

    if tf.cast(done, tf.bool):
      break

  action_probs = action_probs.stack()
  values = values.stack()
  rewards = rewards.stack()

  return action_probs, values, rewards

2. প্রত্যাশিত রিটার্ন গণনা করা

প্রতিটি টাইমস্টেপ \(t\), \(\{r_{t}\}^{T}_{t=1}\) এর জন্য পুরস্কারের ক্রম একটি পর্বের সময় সংগৃহীত প্রত্যাশিত রিটার্নের ক্রম \(\{G_{t}\}^{T}_{t=1}\) এ রূপান্তরিত হয় যেখানে পুরষ্কারের যোগফল বর্তমান টাইমস্টেপ \(t\) \(T\) প্রতিটি স্থান থেকে নেওয়া হয় পুরস্কার একটি দ্রুত ক্ষয়প্রাপ্ত ডিসকাউন্ট ফ্যাক্টর \(\gamma\)দিয়ে গুণিত হয়:

\[G_{t} = \sum^{T}_{t'=t} \gamma^{t'-t}r_{t'}\]

যেহেতু \(\gamma\in(0,1)\), বর্তমান টাইমস্টেপ থেকে পুরষ্কারগুলি কম ওজন দেওয়া হয়েছে৷

স্বজ্ঞাতভাবে, প্রত্যাশিত রিটার্ন সহজভাবে বোঝায় যে এখন পুরষ্কারগুলি পরে পুরষ্কারের চেয়ে ভাল৷ গাণিতিক অর্থে, এটি নিশ্চিত করা হয় যে পুরষ্কারের যোগফল একত্রিত হয়।

প্রশিক্ষণ স্থিতিশীল করার জন্য, ফলাফলের ক্রমটিও প্রমিত করা হয় (অর্থাৎ শূন্য গড় এবং একক মান বিচ্যুতি)।

def get_expected_return(
    rewards: tf.Tensor, 
    gamma: float, 
    standardize: bool = True) -> tf.Tensor:
  """Compute expected returns per timestep."""

  n = tf.shape(rewards)[0]
  returns = tf.TensorArray(dtype=tf.float32, size=n)

  # Start from the end of `rewards` and accumulate reward sums
  # into the `returns` array
  rewards = tf.cast(rewards[::-1], dtype=tf.float32)
  discounted_sum = tf.constant(0.0)
  discounted_sum_shape = discounted_sum.shape
  for i in tf.range(n):
    reward = rewards[i]
    discounted_sum = reward + gamma * discounted_sum
    discounted_sum.set_shape(discounted_sum_shape)
    returns = returns.write(i, discounted_sum)
  returns = returns.stack()[::-1]

  if standardize:
    returns = ((returns - tf.math.reduce_mean(returns)) / 
               (tf.math.reduce_std(returns) + eps))

  return returns

3. অভিনেতা-সমালোচক ক্ষতি

যেহেতু একটি হাইব্রিড অভিনেতা-সমালোচক মডেল ব্যবহার করা হয়, নির্বাচিত ক্ষতি ফাংশন হল অভিনেতা এবং প্রশিক্ষণের জন্য সমালোচকের ক্ষতির সংমিশ্রণ, যা নীচে দেখানো হয়েছে:

\[L = L_{actor} + L_{critic}\]

অভিনেতার ক্ষতি

অভিনেতা ক্ষতি রাষ্ট্র নির্ভর বেসলাইন হিসাবে সমালোচক সহ নীতি গ্রেডিয়েন্টের উপর ভিত্তি করে এবং একক-নমুনা (প্রতি-পর্ব) অনুমানের সাথে গণনা করা হয়।

\[L_{actor} = -\sum^{T}_{t=1} \log\pi_{\theta}(a_{t} | s_{t})[G(s_{t}, a_{t}) - V^{\pi}_{\theta}(s_{t})]\]

কোথায়:

  • \(T\): প্রতি পর্বের টাইমস্টেপের সংখ্যা, যা প্রতি পর্বে পরিবর্তিত হতে পারে
  • \(s_{t}\): টাইমস্টেপ \(t\)
  • \(a_{t}\): টাইমস্টেপে নির্বাচিত ক্রিয়া \(t\) প্রদত্ত অবস্থায় \(s\)
  • \(\pi_{\theta}\): হল নীতি (অভিনেতা) যা \(\theta\)দ্বারা প্যারামিটারাইজ করা হয়েছে
  • \(V^{\pi}_{\theta}\): মান ফাংশন (সমালোচক) এছাড়াও \(\theta\)দ্বারা প্যারামিটারাইজ করা হয়
  • \(G = G_{t}\): প্রদত্ত অবস্থার জন্য প্রত্যাশিত রিটার্ন, টাইমস্টেপে অ্যাকশন জুটি \(t\)

যোগফলের সাথে একটি নেতিবাচক শব্দ যোগ করা হয় কারণ ধারণাটি হল সম্মিলিত ক্ষতি কমিয়ে উচ্চ পুরষ্কার প্রদানকারী ক্রিয়াকলাপের সম্ভাবনাকে সর্বাধিক করা।


সুবিধা

আমাদের \(L_{actor}\) ফর্মুলেশনে \(G - V\) শব্দটিকে সুবিধা বলা হয়, যা নির্দেশ করে যে সেই রাজ্যের জন্য নীতি \(\pi\) অনুযায়ী নির্বাচিত একটি র্যান্ডম অ্যাকশনের উপর একটি ক্রিয়াকে কতটা ভালো দেওয়া হয়েছে।

যদিও এটি একটি বেসলাইন বাদ দেওয়া সম্ভব, এটি প্রশিক্ষণের সময় উচ্চ পার্থক্য হতে পারে। এবং একটি বেসলাইন হিসাবে সমালোচক \(V\) বেছে নেওয়ার বিষয়ে চমৎকার জিনিস হল যে এটি \(G\)এর যতটা সম্ভব কাছাকাছি থাকার জন্য প্রশিক্ষিত হয়েছে, যার ফলে একটি নিম্ন বৈচিত্র্য দেখা দিয়েছে।

উপরন্তু, সমালোচক ব্যতীত, অ্যালগরিদম প্রত্যাশিত রিটার্নের উপর ভিত্তি করে একটি নির্দিষ্ট অবস্থার উপর গৃহীত ক্রিয়াকলাপের সম্ভাবনা বাড়ানোর চেষ্টা করবে, যা কর্মের মধ্যে আপেক্ষিক সম্ভাবনা একই থাকলে তা খুব একটা পার্থক্য করতে পারে না।

উদাহরণস্বরূপ, ধরুন যে একটি প্রদত্ত রাষ্ট্রের জন্য দুটি কর্ম একই প্রত্যাশিত রিটার্ন প্রদান করবে। সমালোচক ছাড়া, অ্যালগরিদম উদ্দেশ্য \(J\)এর উপর ভিত্তি করে এই ক্রিয়াগুলির সম্ভাবনা বাড়ানোর চেষ্টা করবে। সমালোচকের সাথে, এটি চালু হতে পারে যে কোনও সুবিধা নেই (\(G - V = 0\)) এবং এইভাবে অ্যাকশনের সম্ভাব্যতা বাড়ানোর ক্ষেত্রে কোনও সুবিধা অর্জিত হয়নি এবং অ্যালগরিদম গ্রেডিয়েন্টগুলিকে শূন্যে সেট করবে।


সমালোচক ক্ষতি

\(V\) \(G\) যতটা সম্ভব কাছাকাছি হতে প্রশিক্ষণ দেওয়া নিম্নোক্ত ক্ষতি ফাংশনের সাথে রিগ্রেশন সমস্যা হিসাবে সেট আপ করা যেতে পারে:

\[L_{critic} = L_{\delta}(G, V^{\pi}_{\theta})\]

যেখানে \(L_{\delta}\) হল Huber লস , যা স্কোয়ার-এরর লসের তুলনায় ডেটার আউটলায়ারদের প্রতি কম সংবেদনশীল।

huber_loss = tf.keras.losses.Huber(reduction=tf.keras.losses.Reduction.SUM)

def compute_loss(
    action_probs: tf.Tensor,  
    values: tf.Tensor,  
    returns: tf.Tensor) -> tf.Tensor:
  """Computes the combined actor-critic loss."""

  advantage = returns - values

  action_log_probs = tf.math.log(action_probs)
  actor_loss = -tf.math.reduce_sum(action_log_probs * advantage)

  critic_loss = huber_loss(values, returns)

  return actor_loss + critic_loss

4. পরামিতি আপডেট করার জন্য প্রশিক্ষণের ধাপ সংজ্ঞায়িত করা

উপরের সমস্ত ধাপগুলিকে একটি প্রশিক্ষণের ধাপে একত্রিত করা হয়েছে যা প্রতিটি পর্বে চালানো হয়। স্বয়ংক্রিয় পার্থক্য সক্ষম করতে লস ফাংশন পর্যন্ত অগ্রণী সমস্ত পদক্ষেপগুলি tf. tf.GradientTape প্রসঙ্গের সাথে সম্পাদিত হয়।

মডেল প্যারামিটারে গ্রেডিয়েন্ট প্রয়োগ করতে এই টিউটোরিয়াল অ্যাডাম অপ্টিমাইজার ব্যবহার করে।

ছাড়বিহীন পুরষ্কারের যোগফল, episode_reward এই ধাপে গণনা করা হয়। সাফল্যের মাপকাঠি পূরণ হলে মূল্যায়ন করার জন্য এই মানটি পরে ব্যবহার করা হবে।

tf.function প্রসঙ্গটি train_step ফাংশনে প্রয়োগ করা হয়েছে যাতে এটি একটি কলযোগ্য TensorFlow গ্রাফে কম্পাইল করা যায়, যা প্রশিক্ষণে 10x গতি বাড়াতে পারে।

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


@tf.function
def train_step(
    initial_state: tf.Tensor, 
    model: tf.keras.Model, 
    optimizer: tf.keras.optimizers.Optimizer, 
    gamma: float, 
    max_steps_per_episode: int) -> tf.Tensor:
  """Runs a model training step."""

  with tf.GradientTape() as tape:

    # Run the model for one episode to collect training data
    action_probs, values, rewards = run_episode(
        initial_state, model, max_steps_per_episode) 

    # Calculate expected returns
    returns = get_expected_return(rewards, gamma)

    # Convert training data to appropriate TF tensor shapes
    action_probs, values, returns = [
        tf.expand_dims(x, 1) for x in [action_probs, values, returns]] 

    # Calculating loss values to update our network
    loss = compute_loss(action_probs, values, returns)

  # Compute the gradients from the loss
  grads = tape.gradient(loss, model.trainable_variables)

  # Apply the gradients to the model's parameters
  optimizer.apply_gradients(zip(grads, model.trainable_variables))

  episode_reward = tf.math.reduce_sum(rewards)

  return episode_reward

5. প্রশিক্ষণ লুপ চালান

সাফল্যের মাপকাঠি বা পর্বের সর্বোচ্চ সংখ্যায় না পৌঁছানো পর্যন্ত প্রশিক্ষণের ধাপটি চালানোর মাধ্যমে প্রশিক্ষণ কার্যকর করা হয়।

পর্বের পুরস্কারের একটি চলমান রেকর্ড একটি সারিতে রাখা হয়। একবার 100টি ট্রায়ালে পৌঁছে গেলে, সারির বাঁদিকে (টেইল) শেষে সবচেয়ে পুরনো পুরস্কারটি সরানো হয় এবং নতুনটি মাথায় (ডানদিকে) যোগ করা হয়। কম্পিউটেশনাল দক্ষতার জন্য পুরস্কারের একটি চলমান সমষ্টিও বজায় রাখা হয়।

আপনার রানটাইমের উপর নির্ভর করে, প্রশিক্ষণ এক মিনিটেরও কম সময়ে শেষ হতে পারে।

%%time

min_episodes_criterion = 100
max_episodes = 10000
max_steps_per_episode = 1000

# Cartpole-v0 is considered solved if average reward is >= 195 over 100 
# consecutive trials
reward_threshold = 195
running_reward = 0

# Discount factor for future rewards
gamma = 0.99

# Keep last episodes reward
episodes_reward: collections.deque = collections.deque(maxlen=min_episodes_criterion)

with tqdm.trange(max_episodes) as t:
  for i in t:
    initial_state = tf.constant(env.reset(), dtype=tf.float32)
    episode_reward = int(train_step(
        initial_state, model, optimizer, gamma, max_steps_per_episode))

    episodes_reward.append(episode_reward)
    running_reward = statistics.mean(episodes_reward)

    t.set_description(f'Episode {i}')
    t.set_postfix(
        episode_reward=episode_reward, running_reward=running_reward)

    # Show average episode reward every 10 episodes
    if i % 10 == 0:
      pass # print(f'Episode {i}: average reward: {avg_reward}')

    if running_reward > reward_threshold and i >= min_episodes_criterion:  
        break

print(f'\nSolved at episode {i}: average reward: {running_reward:.2f}!')
Episode 361:   4%|▎         | 361/10000 [01:13<32:33,  4.93it/s, episode_reward=182, running_reward=195]
Solved at episode 361: average reward: 195.14!
CPU times: user 2min 46s, sys: 35.4 s, total: 3min 21s
Wall time: 1min 13s

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

প্রশিক্ষণের পরে, পরিবেশে মডেলটি কীভাবে কাজ করে তা কল্পনা করা ভাল। আপনি মডেলটির একটি পর্বের একটি GIF অ্যানিমেশন তৈরি করতে নীচের ঘরগুলি চালাতে পারেন৷ মনে রাখবেন যে Colab-এ পরিবেশের ছবি সঠিকভাবে রেন্ডার করতে OpenAI জিমের জন্য অতিরিক্ত প্যাকেজ ইনস্টল করতে হবে।

# Render an episode and save as a GIF file

from IPython import display as ipythondisplay
from PIL import Image
from pyvirtualdisplay import Display


display = Display(visible=0, size=(400, 300))
display.start()


def render_episode(env: gym.Env, model: tf.keras.Model, max_steps: int): 
  screen = env.render(mode='rgb_array')
  im = Image.fromarray(screen)

  images = [im]

  state = tf.constant(env.reset(), dtype=tf.float32)
  for i in range(1, max_steps + 1):
    state = tf.expand_dims(state, 0)
    action_probs, _ = model(state)
    action = np.argmax(np.squeeze(action_probs))

    state, _, done, _ = env.step(action)
    state = tf.constant(state, dtype=tf.float32)

    # Render screen every 10 steps
    if i % 10 == 0:
      screen = env.render(mode='rgb_array')
      images.append(Image.fromarray(screen))

    if done:
      break

  return images


# Save GIF image
images = render_episode(env, model, max_steps_per_episode)
image_file = 'cartpole-v0.gif'
# loop=0: loop forever, duration=1: play each frame for 1ms
images[0].save(
    image_file, save_all=True, append_images=images[1:], loop=0, duration=1)
import tensorflow_docs.vis.embed as embed
embed.embed_file(image_file)

gif

পরবর্তী পদক্ষেপ

এই টিউটোরিয়ালটি দেখানো হয়েছে কিভাবে Tensorflow ব্যবহার করে অভিনেতা-সমালোচক পদ্ধতি বাস্তবায়ন করতে হয়।

পরবর্তী পদক্ষেপ হিসাবে, আপনি OpenAI জিমে একটি ভিন্ন পরিবেশে একটি মডেল প্রশিক্ষণের চেষ্টা করতে পারেন।

অভিনেতা-সমালোচক পদ্ধতি এবং Cartpole-v0 সমস্যা সম্পর্কিত অতিরিক্ত তথ্যের জন্য, আপনি নিম্নলিখিত সংস্থানগুলি উল্লেখ করতে পারেন:

TensorFlow-এ আরও শক্তিবৃদ্ধি শেখার উদাহরণের জন্য, আপনি নিম্নলিখিত সংস্থানগুলি পরীক্ষা করতে পারেন: