สิ่งแวดล้อม

ดูบน TensorFlow.org ทำงานใน Google Colab ดูแหล่งที่มาบน GitHub ดาวน์โหลดโน๊ตบุ๊ค

บทนำ

เป้าหมายของ Reinforcement Learning (RL) คือการออกแบบตัวแทนที่เรียนรู้โดยการโต้ตอบกับสภาพแวดล้อม ในการตั้งค่า RL มาตรฐาน เอเจนต์จะได้รับการสังเกตในทุกขั้นตอนและเลือกการดำเนินการ การกระทำถูกนำไปใช้กับสิ่งแวดล้อมและสิ่งแวดล้อมจะได้รับรางวัลและการสังเกตใหม่ ตัวแทนฝึกนโยบายเพื่อเลือกการกระทำเพื่อเพิ่มผลรวมของรางวัลสูงสุดหรือที่เรียกว่าผลตอบแทน

ใน TF-Agents สภาพแวดล้อมสามารถใช้งานได้ทั้งใน Python หรือ TensorFlow สภาพแวดล้อม Python มักจะใช้งาน ทำความเข้าใจ และดีบักได้ง่ายกว่า แต่สภาพแวดล้อม TensorFlow นั้นมีประสิทธิภาพมากกว่าและอนุญาตให้มีการขนานกันอย่างเป็นธรรมชาติ เวิร์กโฟลว์ที่พบบ่อยที่สุดคือการนำสภาพแวดล้อมไปใช้ใน Python และใช้หนึ่งในโปรแกรมห่อหุ้มของเราเพื่อแปลงเป็น TensorFlow โดยอัตโนมัติ

ให้เราดูสภาพแวดล้อมของ Python ก่อน สภาพแวดล้อม TensorFlow เป็นไปตาม API ที่คล้ายกันมาก

ติดตั้ง

หากคุณยังไม่ได้ติดตั้ง tf-agents หรือ gym ให้รัน:

pip install "gym>=0.21.0"
pip install tf-agents
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import abc
import tensorflow as tf
import numpy as np

from tf_agents.environments import py_environment
from tf_agents.environments import tf_environment
from tf_agents.environments import tf_py_environment
from tf_agents.environments import utils
from tf_agents.specs import array_spec
from tf_agents.environments import wrappers
from tf_agents.environments import suite_gym
from tf_agents.trajectories import time_step as ts

สภาพแวดล้อม Python

สภาพแวดล้อมหลามมี step(action) -> next_time_step วิธีการที่จะนำไปใช้ดำเนินการเพื่อสิ่งแวดล้อมและส่งกลับข้อมูลเกี่ยวกับขั้นตอนต่อไปนี้:

  1. observation : นี่คือส่วนหนึ่งของรัฐสภาพแวดล้อมที่ตัวแทนสามารถสังเกตในการเลือกการกระทำของตนในขั้นตอนต่อไป
  2. reward : ตัวแทนคือการเรียนรู้เพื่อเพิ่มผลตอบแทนรวมของเหล่านี้ในหลายขั้นตอน
  3. step_type : ปฏิสัมพันธ์กับสภาพแวดล้อมที่มักจะมีส่วนหนึ่งของลำดับ / ตอน เช่นหลายการเคลื่อนไหวในเกมหมากรุก step_type สามารถเป็นได้ทั้ง FIRST , MID หรือ LAST เพื่อบ่งชี้ว่าขั้นตอนเวลานี้เป็นครั้งแรก, กลางหรือที่ผ่านมาขั้นตอนในลำดับ
  4. discount : นี่คือตัวแทนของลอยเท่าใดน้ำหนักรางวัลที่ครั้งต่อไปขั้นตอนเทียบกับรางวัลที่ขั้นตอนเวลาปัจจุบัน

เหล่านี้จะถูกจัดกลุ่มเป็น tuple ชื่อ TimeStep(step_type, reward, discount, observation)

อินเตอร์เฟซที่ว่าทุกสภาพแวดล้อมหลามจะต้องดำเนินการอยู่ใน environments/py_environment.PyEnvironment วิธีการหลักคือ:

class PyEnvironment(object):

  def reset(self):
    """Return initial_time_step."""
    self._current_time_step = self._reset()
    return self._current_time_step

  def step(self, action):
    """Apply action and return new time_step."""
    if self._current_time_step is None:
        return self.reset()
    self._current_time_step = self._step(action)
    return self._current_time_step

  def current_time_step(self):
    return self._current_time_step

  def time_step_spec(self):
    """Return time_step_spec."""

  @abc.abstractmethod
  def observation_spec(self):
    """Return observation_spec."""

  @abc.abstractmethod
  def action_spec(self):
    """Return action_spec."""

  @abc.abstractmethod
  def _reset(self):
    """Return initial_time_step."""

  @abc.abstractmethod
  def _step(self, action):
    """Apply action and return new time_step."""

นอกจากนี้ยังมี step() วิธีการสภาพแวดล้อมยังให้ reset() วิธีการที่จะเริ่มต้นลำดับใหม่และให้เริ่มต้น TimeStep มันไม่จำเป็นที่จะเรียก reset วิธีการอย่างชัดเจน เราถือว่าสภาพแวดล้อมถูกรีเซ็ตโดยอัตโนมัติ ไม่ว่าจะเป็นเมื่อไปถึงตอนจบของตอนหรือเมื่อมีการเรียก step() ในครั้งแรก

โปรดทราบว่า subclasses ไม่ใช้ step() หรือ reset() โดยตรง แทนพวกเขาแทนที่ _step() และ _reset() วิธีการ ขั้นตอนและเวลาในกลับมาจากวิธีการเหล่านี้จะถูกเก็บไว้และสัมผัสผ่าน current_time_step()

observation_spec และ action_spec วิธีการกลับรังของ (Bounded)ArraySpecs ที่อธิบายชื่อรูปร่างประเภทข้อมูลและช่วงของการสังเกตและการดำเนินการตามลำดับ

ใน TF-Agents เราอ้างถึง nest ซ้ำๆ ซึ่งถูกกำหนดให้เป็นโครงสร้างแบบต้นไม้ใดๆ ก็ตามที่ประกอบด้วยรายการ ทูเปิล ทูเพิลที่มีชื่อ หรือพจนานุกรม สิ่งเหล่านี้สามารถสร้างขึ้นได้ตามอำเภอใจเพื่อรักษาโครงสร้างการสังเกตและการกระทำ เราพบว่าสิ่งนี้มีประโยชน์มากสำหรับสภาพแวดล้อมที่ซับซ้อนมากขึ้น ซึ่งคุณมีข้อสังเกตและการกระทำมากมาย

การใช้สภาพแวดล้อมมาตรฐาน

ตัวแทน TF มีในตัวห่อสำหรับสภาพแวดล้อมหลายมาตรฐานเช่น OpenAI ยิม, DeepMind ควบคุมและ Atari เพื่อให้พวกเขาทำตามเรา py_environment.PyEnvironment อินเตอร์เฟซ สภาพแวดล้อมที่ห่อหุ้มเหล่านี้สามารถโหลดได้อย่างง่ายดายโดยใช้ชุดสภาพแวดล้อมของเรา โหลดสภาพแวดล้อม CartPole จากยิม OpenAI และดูการกระทำและ time_step_spec

environment = suite_gym.load('CartPole-v0')
print('action_spec:', environment.action_spec())
print('time_step_spec.observation:', environment.time_step_spec().observation)
print('time_step_spec.step_type:', environment.time_step_spec().step_type)
print('time_step_spec.discount:', environment.time_step_spec().discount)
print('time_step_spec.reward:', environment.time_step_spec().reward)
action_spec: BoundedArraySpec(shape=(), dtype=dtype('int64'), name='action', minimum=0, maximum=1)
time_step_spec.observation: 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])
time_step_spec.step_type: ArraySpec(shape=(), dtype=dtype('int32'), name='step_type')
time_step_spec.discount: BoundedArraySpec(shape=(), dtype=dtype('float32'), name='discount', minimum=0.0, maximum=1.0)
time_step_spec.reward: ArraySpec(shape=(), dtype=dtype('float32'), name='reward')

ดังนั้นเราจะเห็นว่าสภาพแวดล้อมที่คาดว่าการกระทำของชนิด int64 ใน [0, 1] และผลตอบแทน TimeSteps ที่สังเกตเป็น float32 เวกเตอร์ของความยาว 4 และปัจจัยส่วนลดเป็น float32 ใน [0.0, 1.0] ตอนนี้ขอพยายามที่จะใช้การกระทำที่คงที่ (1,) สำหรับเรื่องราวทั้งหมด

action = np.array(1, dtype=np.int32)
time_step = environment.reset()
print(time_step)
while not time_step.is_last():
  time_step = environment.step(action)
  print(time_step)
TimeStep(
{'discount': array(1., dtype=float32),
 'observation': array([ 0.0138565 , -0.03582913,  0.04861612, -0.03755046], dtype=float32),
 'reward': array(0., dtype=float32),
 'step_type': array(0, dtype=int32)})
TimeStep(
{'discount': array(1., dtype=float32),
 'observation': array([ 0.01313992,  0.15856317,  0.0478651 , -0.3145069 ], dtype=float32),
 'reward': array(1., dtype=float32),
 'step_type': array(1, dtype=int32)})
TimeStep(
{'discount': array(1., dtype=float32),
 'observation': array([ 0.01631118,  0.35297176,  0.04157497, -0.5917188 ], dtype=float32),
 'reward': array(1., dtype=float32),
 'step_type': array(1, dtype=int32)})
TimeStep(
{'discount': array(1., dtype=float32),
 'observation': array([ 0.02337062,  0.54748774,  0.02974059, -0.87102115], dtype=float32),
 'reward': array(1., dtype=float32),
 'step_type': array(1, dtype=int32)})
TimeStep(
{'discount': array(1., dtype=float32),
 'observation': array([ 0.03432037,  0.74219286,  0.01232017, -1.1542072 ], dtype=float32),
 'reward': array(1., dtype=float32),
 'step_type': array(1, dtype=int32)})
TimeStep(
{'discount': array(1., dtype=float32),
 'observation': array([ 0.04916423,  0.93715197, -0.01076398, -1.4430016 ], dtype=float32),
 'reward': array(1., dtype=float32),
 'step_type': array(1, dtype=int32)})
TimeStep(
{'discount': array(1., dtype=float32),
 'observation': array([ 0.06790727,  1.1324048 , -0.03962401, -1.7390285 ], dtype=float32),
 'reward': array(1., dtype=float32),
 'step_type': array(1, dtype=int32)})
TimeStep(
{'discount': array(1., dtype=float32),
 'observation': array([ 0.09055536,  1.327955  , -0.07440457, -2.04377   ], dtype=float32),
 'reward': array(1., dtype=float32),
 'step_type': array(1, dtype=int32)})
TimeStep(
{'discount': array(1., dtype=float32),
 'observation': array([ 0.11711447,  1.523758  , -0.11527998, -2.3585167 ], dtype=float32),
 'reward': array(1., dtype=float32),
 'step_type': array(1, dtype=int32)})
TimeStep(
{'discount': array(1., dtype=float32),
 'observation': array([ 0.14758962,  1.7197047 , -0.16245031, -2.6843033 ], dtype=float32),
 'reward': array(1., dtype=float32),
 'step_type': array(1, dtype=int32)})
TimeStep(
{'discount': array(0., dtype=float32),
 'observation': array([ 0.18198372,  1.9156038 , -0.21613638, -3.0218334 ], dtype=float32),
 'reward': array(1., dtype=float32),
 'step_type': array(2, dtype=int32)})

สร้าง Python Environment ของคุณเอง

สำหรับลูกค้าจำนวนมาก กรณีการใช้งานทั่วไปคือการใช้หนึ่งในตัวแทนมาตรฐาน (ดูตัวแทน/) ใน TF-Agents กับปัญหาของพวกเขา ในการทำเช่นนี้ พวกเขาต้องวางกรอบปัญหาของตนให้เป็นสภาพแวดล้อม ให้เรามาดูวิธีการใช้สภาพแวดล้อมใน Python

สมมติว่าเราต้องการฝึกตัวแทนให้เล่นเกมไพ่ (ที่ได้รับแรงบันดาลใจจากแบล็คแจ็ค):

  1. เกมนี้เล่นโดยใช้สำรับไพ่ที่ไม่มีที่สิ้นสุดที่มีหมายเลข 1...10
  2. ทุกๆ เทิร์น เอเย่นต์สามารถทำ 2 สิ่งได้: รับการ์ดสุ่มใหม่ หรือหยุดรอบปัจจุบัน
  3. เป้าหมายคือเพื่อให้ได้ผลรวมของไพ่ของคุณใกล้เคียงกับ 21 มากที่สุดเมื่อสิ้นสุดรอบ โดยไม่ต้องผ่าน

สภาพแวดล้อมที่แสดงถึงเกมอาจมีลักษณะดังนี้:

  1. การกระทำ: เรามี 2 การกระทำ Action 0: รับการ์ดใหม่และ Action 1: ยุติรอบปัจจุบัน
  2. การสังเกต: ผลรวมของไพ่ในรอบปัจจุบัน
  3. รางวัล: เป้าหมายคือการเข้าใกล้ 21 ให้มากที่สุดโดยไม่ต้องข้าม ดังนั้นเราสามารถบรรลุสิ่งนี้โดยใช้รางวัลต่อไปนี้เมื่อสิ้นสุดรอบ: sum_of_cards - 21 ถ้า sum_of_cards <= 21, อื่น -21
class CardGameEnv(py_environment.PyEnvironment):

  def __init__(self):
    self._action_spec = array_spec.BoundedArraySpec(
        shape=(), dtype=np.int32, minimum=0, maximum=1, name='action')
    self._observation_spec = array_spec.BoundedArraySpec(
        shape=(1,), dtype=np.int32, minimum=0, name='observation')
    self._state = 0
    self._episode_ended = False

  def action_spec(self):
    return self._action_spec

  def observation_spec(self):
    return self._observation_spec

  def _reset(self):
    self._state = 0
    self._episode_ended = False
    return ts.restart(np.array([self._state], dtype=np.int32))

  def _step(self, action):

    if self._episode_ended:
      # The last action ended the episode. Ignore the current action and start
      # a new episode.
      return self.reset()

    # Make sure episodes don't go on forever.
    if action == 1:
      self._episode_ended = True
    elif action == 0:
      new_card = np.random.randint(1, 11)
      self._state += new_card
    else:
      raise ValueError('`action` should be 0 or 1.')

    if self._episode_ended or self._state >= 21:
      reward = self._state - 21 if self._state <= 21 else -21
      return ts.termination(np.array([self._state], dtype=np.int32), reward)
    else:
      return ts.transition(
          np.array([self._state], dtype=np.int32), reward=0.0, discount=1.0)

ตรวจสอบให้แน่ใจว่าเราได้ทำทุกอย่างอย่างถูกต้องที่กำหนดสภาพแวดล้อมข้างต้น เมื่อสร้างสภาพแวดล้อมของคุณเอง คุณต้องตรวจสอบให้แน่ใจว่าการสังเกตและ time_steps ที่สร้างขึ้นนั้นมีรูปร่างและประเภทที่ถูกต้องตามที่กำหนดไว้ในข้อกำหนดของคุณ สิ่งเหล่านี้ใช้เพื่อสร้างกราฟ TensorFlow และด้วยเหตุนี้จึงสามารถสร้างปัญหาที่ยากต่อการแก้จุดบกพร่องได้ หากเราเข้าใจผิด

ในการตรวจสอบสภาพแวดล้อมของเรา เราจะใช้นโยบายแบบสุ่มเพื่อสร้างการดำเนินการ และเราจะทำซ้ำมากกว่า 5 ตอนเพื่อให้แน่ใจว่าสิ่งต่างๆ ทำงานตามที่ตั้งใจไว้ เกิดข้อผิดพลาดหากเราได้รับ time_step ที่ไม่เป็นไปตามข้อกำหนดสภาพแวดล้อม

environment = CardGameEnv()
utils.validate_py_environment(environment, episodes=5)

ตอนนี้เราทราบแล้วว่าสภาพแวดล้อมทำงานตามที่ตั้งใจไว้ เรามาเรียกใช้สภาพแวดล้อมนี้โดยใช้นโยบายคงที่กัน: ขอไพ่ 3 ใบแล้วจบรอบ

get_new_card_action = np.array(0, dtype=np.int32)
end_round_action = np.array(1, dtype=np.int32)

environment = CardGameEnv()
time_step = environment.reset()
print(time_step)
cumulative_reward = time_step.reward

for _ in range(3):
  time_step = environment.step(get_new_card_action)
  print(time_step)
  cumulative_reward += time_step.reward

time_step = environment.step(end_round_action)
print(time_step)
cumulative_reward += time_step.reward
print('Final Reward = ', cumulative_reward)
TimeStep(
{'discount': array(1., dtype=float32),
 'observation': array([0], dtype=int32),
 'reward': array(0., dtype=float32),
 'step_type': array(0, dtype=int32)})
TimeStep(
{'discount': array(1., dtype=float32),
 'observation': array([9], dtype=int32),
 'reward': array(0., dtype=float32),
 'step_type': array(1, dtype=int32)})
TimeStep(
{'discount': array(1., dtype=float32),
 'observation': array([12], dtype=int32),
 'reward': array(0., dtype=float32),
 'step_type': array(1, dtype=int32)})
TimeStep(
{'discount': array(0., dtype=float32),
 'observation': array([21], dtype=int32),
 'reward': array(0., dtype=float32),
 'step_type': array(2, dtype=int32)})
TimeStep(
{'discount': array(0., dtype=float32),
 'observation': array([21], dtype=int32),
 'reward': array(0., dtype=float32),
 'step_type': array(2, dtype=int32)})
Final Reward =  0.0

เครื่องห่อสิ่งแวดล้อม

Wrapper สภาพแวดล้อมใช้สภาพแวดล้อม Python และส่งคืนสภาพแวดล้อมเวอร์ชันที่แก้ไข ทั้งสภาพแวดล้อมเดิมและสภาพแวดล้อมในการแก้ไขเป็นกรณีของ py_environment.PyEnvironment และห่อหลาย ๆ สามารถถูกล่ามโซ่ไว้ด้วยกัน

บางห่อทั่วไปสามารถพบได้ใน environments/wrappers.py ตัวอย่างเช่น:

  1. ActionDiscretizeWrapper : แปลงพื้นที่ดำเนินการอย่างต่อเนื่องเพื่อเป็นพื้นที่ดำเนินการต่อเนื่อง
  2. RunStats : จับรันสถิติของสภาพแวดล้อมเช่นจำนวนของขั้นตอนการดำเนินการจำนวนตอนเสร็จสมบูรณ์ ฯลฯ
  3. TimeLimit : ยุติเหตุการณ์ที่เกิดขึ้นหลังจากที่มีจำนวนคงที่ของขั้นตอน

ตัวอย่างที่ 1: การกระทำ Discretize Wrapper

InvertedPendulum เป็นสภาพแวดล้อมที่ PyBullet ที่ยอมรับการดำเนินการอย่างต่อเนื่องในช่วง [-2, 2] หากเราต้องการฝึกอบรมตัวแทนการดำเนินการที่ไม่ต่อเนื่องเช่น DQN ในสภาพแวดล้อมนี้ เราต้องแยก (quantize) พื้นที่ดำเนินการ ตรงนี้เป็นสิ่งที่ผู้ ActionDiscretizeWrapper ไม่ เปรียบเทียบ action_spec ก่อนและหลังการวางรูปภาพ:

env = suite_gym.load('Pendulum-v1')
print('Action Spec:', env.action_spec())

discrete_action_env = wrappers.ActionDiscretizeWrapper(env, num_actions=5)
print('Discretized Action Spec:', discrete_action_env.action_spec())
Action Spec: BoundedArraySpec(shape=(1,), dtype=dtype('float32'), name='action', minimum=-2.0, maximum=2.0)
Discretized Action Spec: BoundedArraySpec(shape=(), dtype=dtype('int32'), name='action', minimum=0, maximum=4)

ห่อ discrete_action_env เป็นตัวอย่างของ py_environment.PyEnvironment และสามารถรักษาได้เช่นสภาพแวดล้อมหลามปกติ

สภาพแวดล้อม TensorFlow

อินเตอร์เฟซสำหรับสภาพแวดล้อม TF ถูกกำหนดไว้ใน environments/tf_environment.TFEnvironment และรูปลักษณ์ที่คล้ายกันมากกับสภาพแวดล้อมหลาม TF Environments แตกต่างจาก Python env ในสองวิธี:

  • พวกเขาสร้างวัตถุเทนเซอร์แทนอาร์เรย์
  • สภาพแวดล้อม TF เพิ่มมิติแบทช์ให้กับเทนเซอร์ที่สร้างขึ้นเมื่อเปรียบเทียบกับข้อกำหนด

การแปลงสภาพแวดล้อม Python เป็น TFEnvs ทำให้เทนเซอร์โฟลว์สามารถดำเนินการขนานกันได้ ตัวอย่างเช่นหนึ่งสามารถกำหนด collect_experience_op ว่าข้อมูลเก็บรวบรวมจากสภาพแวดล้อมและเพิ่มไปยัง replay_buffer และ train_op ที่อ่านจาก replay_buffer และรถไฟตัวแทนและเรียกพวกเขาในแบบคู่ขนานตามธรรมชาติใน TensorFlow

class TFEnvironment(object):

  def time_step_spec(self):
    """Describes the `TimeStep` tensors returned by `step()`."""

  def observation_spec(self):
    """Defines the `TensorSpec` of observations provided by the environment."""

  def action_spec(self):
    """Describes the TensorSpecs of the action expected by `step(action)`."""

  def reset(self):
    """Returns the current `TimeStep` after resetting the Environment."""
    return self._reset()

  def current_time_step(self):
    """Returns the current `TimeStep`."""
    return self._current_time_step()

  def step(self, action):
    """Applies the action and returns the new `TimeStep`."""
    return self._step(action)

  @abc.abstractmethod
  def _reset(self):
    """Returns the current `TimeStep` after resetting the Environment."""

  @abc.abstractmethod
  def _current_time_step(self):
    """Returns the current `TimeStep`."""

  @abc.abstractmethod
  def _step(self, action):
    """Applies the action and returns the new `TimeStep`."""

current_time_step() วิธีการส่งกลับ time_step ปัจจุบันและเริ่มต้นสภาพแวดล้อมนั้นถ้าจำเป็น

reset() วิธีการกองการตั้งค่าในสภาพแวดล้อมและผลตอบแทน CURRENT_STEP

ถ้า action ไม่ขึ้นอยู่กับก่อนหน้านี้ time_step tf.control_dependency เป็นสิ่งจำเป็นใน Graph โหมด

สำหรับตอนนี้ให้เราดูที่วิธีการ TFEnvironments จะถูกสร้างขึ้น

การสร้างสภาพแวดล้อม TensorFlow ของคุณเอง

สิ่งนี้ซับซ้อนกว่าการสร้างสภาพแวดล้อมใน Python ดังนั้นเราจะไม่พูดถึงมันใน colab นี้ ตัวอย่างมีให้บริการ ที่นี่ กรณีการใช้งานร่วมกันมากขึ้นคือการใช้สภาพแวดล้อมของคุณในหลามและห่อใน TensorFlow ใช้ของเรา TFPyEnvironment เสื้อคลุม (ดูด้านล่าง)

การห่อสภาพแวดล้อม Python ใน TensorFlow

เราสามารถห่อสภาพแวดล้อมหลามใด ๆ ในสภาพแวดล้อม TensorFlow โดยใช้ TFPyEnvironment เสื้อคลุม

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

print(isinstance(tf_env, tf_environment.TFEnvironment))
print("TimeStep Specs:", tf_env.time_step_spec())
print("Action Specs:", tf_env.action_spec())
True
TimeStep Specs: TimeStep(
{'discount': BoundedTensorSpec(shape=(), dtype=tf.float32, name='discount', minimum=array(0., dtype=float32), maximum=array(1., dtype=float32)),
 'observation': BoundedTensorSpec(shape=(4,), dtype=tf.float32, name='observation', minimum=array([-4.8000002e+00, -3.4028235e+38, -4.1887903e-01, -3.4028235e+38],
      dtype=float32), maximum=array([4.8000002e+00, 3.4028235e+38, 4.1887903e-01, 3.4028235e+38],
      dtype=float32)),
 'reward': TensorSpec(shape=(), dtype=tf.float32, name='reward'),
 'step_type': TensorSpec(shape=(), dtype=tf.int32, name='step_type')})
Action Specs: BoundedTensorSpec(shape=(), dtype=tf.int64, name='action', minimum=array(0), maximum=array(1))

หมายเหตุ: รายละเอียดอยู่ในขณะนี้จากประเภทนี้: (Bounded)TensorSpec

ตัวอย่างการใช้งาน

ตัวอย่างง่ายๆ

env = suite_gym.load('CartPole-v0')

tf_env = tf_py_environment.TFPyEnvironment(env)
# reset() creates the initial time_step after resetting the environment.
time_step = tf_env.reset()
num_steps = 3
transitions = []
reward = 0
for i in range(num_steps):
  action = tf.constant([i % 2])
  # applies the action and returns the new TimeStep.
  next_time_step = tf_env.step(action)
  transitions.append([time_step, action, next_time_step])
  reward += next_time_step.reward
  time_step = next_time_step

np_transitions = tf.nest.map_structure(lambda x: x.numpy(), transitions)
print('\n'.join(map(str, np_transitions)))
print('Total reward:', reward.numpy())
[TimeStep(
{'discount': array([1.], dtype=float32),
 'observation': array([[-0.0078796 , -0.04736348, -0.04966116,  0.04563603]],
      dtype=float32),
 'reward': array([0.], dtype=float32),
 'step_type': array([0], dtype=int32)}), array([0], dtype=int32), TimeStep(
{'discount': array([1.], dtype=float32),
 'observation': array([[-0.00882687, -0.24173944, -0.04874843,  0.32224613]],
      dtype=float32),
 'reward': array([1.], dtype=float32),
 'step_type': array([1], dtype=int32)})]
[TimeStep(
{'discount': array([1.], dtype=float32),
 'observation': array([[-0.00882687, -0.24173944, -0.04874843,  0.32224613]],
      dtype=float32),
 'reward': array([1.], dtype=float32),
 'step_type': array([1], dtype=int32)}), array([1], dtype=int32), TimeStep(
{'discount': array([1.], dtype=float32),
 'observation': array([[-0.01366166, -0.04595843, -0.04230351,  0.01459712]],
      dtype=float32),
 'reward': array([1.], dtype=float32),
 'step_type': array([1], dtype=int32)})]
[TimeStep(
{'discount': array([1.], dtype=float32),
 'observation': array([[-0.01366166, -0.04595843, -0.04230351,  0.01459712]],
      dtype=float32),
 'reward': array([1.], dtype=float32),
 'step_type': array([1], dtype=int32)}), array([0], dtype=int32), TimeStep(
{'discount': array([1.], dtype=float32),
 'observation': array([[-0.01458083, -0.24044897, -0.04201157,  0.2936384 ]],
      dtype=float32),
 'reward': array([1.], dtype=float32),
 'step_type': array([1], dtype=int32)})]
Total reward: [3.]

ทั้งตอน

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

time_step = tf_env.reset()
rewards = []
steps = []
num_episodes = 5

for _ in range(num_episodes):
  episode_reward = 0
  episode_steps = 0
  while not time_step.is_last():
    action = tf.random.uniform([1], 0, 2, dtype=tf.int32)
    time_step = tf_env.step(action)
    episode_steps += 1
    episode_reward += time_step.reward.numpy()
  rewards.append(episode_reward)
  steps.append(episode_steps)
  time_step = tf_env.reset()

num_steps = np.sum(steps)
avg_length = np.mean(steps)
avg_reward = np.mean(rewards)

print('num_episodes:', num_episodes, 'num_steps:', num_steps)
print('avg_length', avg_length, 'avg_reward:', avg_reward)
num_episodes: 5 num_steps: 131
avg_length 26.2 avg_reward: 26.2