זכויות יוצרים 2021 מחברי TF-Agents.
הצג באתר TensorFlow.org | הפעל בגוגל קולאב | צפה במקור ב-GitHub | הורד מחברת |
מבוא
בקולאב זה נסקור כיצד להגדיר רשתות מותאמות אישית עבור הסוכנים שלך. הרשתות עוזרות לנו להגדיר את המודל שאומן על ידי סוכנים. ב-TF-Agents תמצאו מספר סוגים שונים של רשתות שימושיות בין סוכנים:
רשתות ראשיות
- QNetwork: משמש Qlearning עבור סביבות עם פעולות נפרדות, רשת זו ממפה תצפית הערכות שווי עבור כל פעולה אפשרית.
- CriticNetworks: המכונה גם
ValueNetworks
בספרות, לומד להעריך גרסה כלשהי של פונקציה ערך מיפוי כמה המדינה לתוך אומדן התשואה הצפויה של מדיניות. רשתות אלו מעריכות עד כמה טוב המצב בו הסוכן נמצא כעת. - ActorNetworks: למד מיפוי מתצפיות לפעולות. רשתות אלו משמשות בדרך כלל את המדיניות שלנו כדי ליצור פעולות.
- ActorDistributionNetworks: בדומה
ActorNetworks
אבל אלה יוצר חלוקה אשר פוליסה יכולה אז מדגם כדי ליצור פעולות.
רשתות עוזרות
- EncodingNetwork: מאפשר למשתמשים להגדיר מיפוי בקלות שכבות טרום עיבוד ליישם לקלט של רשת.
- DynamicUnrollLayer: אוטומטי מאפס את מצב הרשת על גבולות פרק כפי שהוא מוחל על פני רצף זמן.
- ProjectionNetwork: רשתות כמו
CategoricalProjectionNetwork
אוNormalProjectionNetwork
לקחת תשומות וליצור את הפרמטרים הנדרשים כדי ליצור הקטגורי, או הפצות רגילות.
כל הדוגמאות ב-TF-Agents מגיעות עם רשתות מוגדרות מראש. עם זאת, רשתות אלו אינן מוגדרות לטיפול בתצפיות מורכבות.
אם יש לך סביבה שחושפת יותר מתצפית/פעולה אחת ואתה צריך להתאים אישית את הרשתות שלך אז המדריך הזה הוא בשבילך!
להכין
אם עדיין לא התקנת tf-agents, הרץ:
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 random_py_environment
from tf_agents.environments import tf_py_environment
from tf_agents.networks import encoding_network
from tf_agents.networks import network
from tf_agents.networks import utils
from tf_agents.specs import array_spec
from tf_agents.utils import common as common_utils
from tf_agents.utils import nest_utils
הגדרת רשתות
ממשק API של רשת
In-סוכנים TF אנו מכל מחלקה מן Keras נטוורקס . בעזרתו נוכל:
- פשט את פעולות ההעתקה הנדרשות בעת יצירת רשתות יעד.
- בצע יצירה משתנה אוטומטית כאשר אתה מתקשר
network.variables()
. - אמת קלט בהתבסס על מפרט_הקלט של הרשת.
EncodingNetwork
כפי שהוזכר מעל EncodingNetwork
מאפשר לנו להגדיר מיפוי בקלות שכבות טרום עיבוד ליישם לקלט של הרשת כדי ליצור כמה קידוד.
רשת הקידוד מורכבת מהשכבות הבאות בעיקר אופציונליות:
- עיבוד מוקדם של שכבות
- משלב עיבוד מקדים
- Conv2D
- לְשַׁטֵחַ
- צָפוּף
הדבר המיוחד בקידוד רשתות הוא שמופעל עיבוד מקדים של קלט. עיבוד מקדים קלט אפשרי באמצעות preprocessing_layers
ו preprocessing_combiner
שכבות. ניתן לציין כל אחד מאלה כמבנה מקונן. אם preprocessing_layers
הקן הוא רדוד יותר input_tensor_spec
, אז ההשכבות תקבלנה את subnests. לדוגמה, אם:
input_tensor_spec = ([TensorSpec(3)] * 2, [TensorSpec(3)] * 5)
preprocessing_layers = (Layer1(), Layer2())
ואז עיבוד מקדים יקרא:
preprocessed = [preprocessing_layers[0](observations[0]),
preprocessing_layers[1](observations[1])]
לעומת זאת, אם
preprocessing_layers = ([Layer1() for _ in range(2)],
[Layer2() for _ in range(5)])
ואז עיבוד מקדים יקרא:
preprocessed = [
layer(obs) for layer, obs in zip(flatten(preprocessing_layers),
flatten(observations))
]
רשתות מותאמות אישית
כדי ליצור רשתות משלך תצטרך רק כדי לעקוף את __init__
ואת call
שיטות. בואו ליצור רשת מותאמת אישית באמצעות מה למדנו על EncodingNetworks
ליצור ActorNetwork שלוקח תצפיות אשר להכיל תמונת וקטור.
class ActorNetwork(network.Network):
def __init__(self,
observation_spec,
action_spec,
preprocessing_layers=None,
preprocessing_combiner=None,
conv_layer_params=None,
fc_layer_params=(75, 40),
dropout_layer_params=None,
activation_fn=tf.keras.activations.relu,
enable_last_layer_zero_initializer=False,
name='ActorNetwork'):
super(ActorNetwork, self).__init__(
input_tensor_spec=observation_spec, state_spec=(), name=name)
# For simplicity we will only support a single action float output.
self._action_spec = action_spec
flat_action_spec = tf.nest.flatten(action_spec)
if len(flat_action_spec) > 1:
raise ValueError('Only a single action is supported by this network')
self._single_action_spec = flat_action_spec[0]
if self._single_action_spec.dtype not in [tf.float32, tf.float64]:
raise ValueError('Only float actions are supported by this network.')
kernel_initializer = tf.keras.initializers.VarianceScaling(
scale=1. / 3., mode='fan_in', distribution='uniform')
self._encoder = encoding_network.EncodingNetwork(
observation_spec,
preprocessing_layers=preprocessing_layers,
preprocessing_combiner=preprocessing_combiner,
conv_layer_params=conv_layer_params,
fc_layer_params=fc_layer_params,
dropout_layer_params=dropout_layer_params,
activation_fn=activation_fn,
kernel_initializer=kernel_initializer,
batch_squash=False)
initializer = tf.keras.initializers.RandomUniform(
minval=-0.003, maxval=0.003)
self._action_projection_layer = tf.keras.layers.Dense(
flat_action_spec[0].shape.num_elements(),
activation=tf.keras.activations.tanh,
kernel_initializer=initializer,
name='action')
def call(self, observations, step_type=(), network_state=()):
outer_rank = nest_utils.get_outer_rank(observations, self.input_tensor_spec)
# We use batch_squash here in case the observations have a time sequence
# compoment.
batch_squash = utils.BatchSquash(outer_rank)
observations = tf.nest.map_structure(batch_squash.flatten, observations)
state, network_state = self._encoder(
observations, step_type=step_type, network_state=network_state)
actions = self._action_projection_layer(state)
actions = common_utils.scale_to_spec(actions, self._single_action_spec)
actions = batch_squash.unflatten(actions)
return tf.nest.pack_sequence_as(self._action_spec, [actions]), network_state
בואו ליצור RandomPyEnvironment
ליצור תצפיות מובנות ולאמת היישום שלנו.
action_spec = array_spec.BoundedArraySpec((3,), np.float32, minimum=0, maximum=10)
observation_spec = {
'image': array_spec.BoundedArraySpec((16, 16, 3), np.float32, minimum=0,
maximum=255),
'vector': array_spec.BoundedArraySpec((5,), np.float32, minimum=-100,
maximum=100)}
random_env = random_py_environment.RandomPyEnvironment(observation_spec, action_spec=action_spec)
# Convert the environment to a TFEnv to generate tensors.
tf_env = tf_py_environment.TFPyEnvironment(random_env)
מכיוון שהגדרנו את התצפיות ככתבה, עלינו ליצור שכבות עיבוד מקדים כדי לטפל בהן.
preprocessing_layers = {
'image': tf.keras.models.Sequential([tf.keras.layers.Conv2D(8, 4),
tf.keras.layers.Flatten()]),
'vector': tf.keras.layers.Dense(5)
}
preprocessing_combiner = tf.keras.layers.Concatenate(axis=-1)
actor = ActorNetwork(tf_env.observation_spec(),
tf_env.action_spec(),
preprocessing_layers=preprocessing_layers,
preprocessing_combiner=preprocessing_combiner)
עכשיו כשיש לנו את רשת השחקנים אנחנו יכולים לעבד תצפיות מהסביבה.
time_step = tf_env.reset()
actor(time_step.observation, time_step.step_type)
(<tf.Tensor: shape=(1, 3), dtype=float32, numpy=array([[4.5753636, 4.946792 , 4.853481 ]], dtype=float32)>, ())
באותה אסטרטגיה ניתן להשתמש כדי להתאים אישית כל אחת מהרשתות העיקריות שבהן משתמשים הסוכנים. אתה יכול להגדיר כל עיבוד מקדים ולחבר אותו לשאר הרשת. בזמן שאתה מגדיר מותאם אישית משלך ודא שהגדרות שכבת הפלט של הרשת תואמות.