דף זה תורגם על ידי Cloud Translation API.
Switch to English

רשתות

צפה ב TensorFlow.org הפעל ב- Google Colab צפה במקור ב- GitHub הורד מחברת

מבוא

במכלאה זו נסקור כיצד להגדיר רשתות מותאמות אישית לסוכנים שלך. הרשתות עוזרות לנו להגדיר את המודל שמוכשר על ידי סוכנים. ב- TF-Agents תמצאו מספר סוגים שונים של רשתות שימושיות עבור סוכנים:

רשתות עיקריות

  • QNetwork : משמש ב- Qlearning לסביבות עם פעולות נפרדות, רשת זו ממפה הערכות תצפית לערך עבור כל פעולה אפשרית.
  • CriticNetworks : מכונה גם ValueNetworks בספרות, לומדת להעריך גרסה מסוימת של פונקציית Value הממפה מצב כלשהו לאומדן להחזר הצפוי של מדיניות. רשתות אלה מעריכות כמה טוב המדינה בה נמצא הסוכן כרגע.
  • ActorNetworks : למד מיפוי מתצפיות לפעולות. בדרך כלל משתמשים ברשתות אלה על ידי המדיניות שלנו ליצירת פעולות.
  • ActorDistributionNetworks : דומה ל- ActorNetworks אך אלה מייצרים תפוצה שמדיניות יכולה אז לדגום כדי ליצור פעולות.

Helper Networks

  • EncodingNetwork : מאפשר למשתמשים להגדיר בקלות מיפוי של שכבות העיבוד המוקדם ליישום קלט רשת.
  • DynamicUnrollLayer : מאופס אוטומטית את מצב הרשת בגבולות הפרק כשהוא מיושם ברצף זמן.
  • ProjectionNetwork : רשתות כמו CategoricalProjectionNetwork או NormalProjectionNetwork לוקחות תשומות NormalProjectionNetwork את הפרמטרים הדרושים ליצירת הפצות קטגוריות או רגילות.

כל הדוגמאות ב- TF-Agents מגיעות עם רשתות מוגדרות מראש. עם זאת רשתות אלה אינן מוגדרות לטיפול בתצפיות מורכבות.

אם יש לך סביבה שחושפת יותר מתצפית / פעולה אחת ואתה צריך להתאים אישית את הרשתות שלך אז הדרכה זו היא בשבילך!

להכין

אם טרם התקנת סוכני tf, הפעל:

pip install -q 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

tf.compat.v1.enable_v2_behavior()

הגדרת רשתות

ממשק API

ב- TF-Agents אנו משנים תת-תחום מ- Keras Networks . בעזרתו אנו יכולים:

  • פשט את פעולות ההעתקה הנדרשות בעת יצירת רשתות יעד.
  • בצע יצירה משתנה אוטומטית כשאתה מתקשר ל- network.variables() .
  • אמת את התשומות על סמך input_specs ברשת.

קידוד נטוורק

כפי שהוזכר לעיל EncodingNetwork מאפשר לנו להגדיר בקלות מיפוי של שכבות עיבוד מוקדם כדי להחיל על קלט הרשת כדי ליצור קידוד כלשהו.

EncodingNetwork מורכב משכבות אופציונליות הבאות:

  • עיבוד שכבות מראש
  • קומבינר מעבד מראש
  • Conv2D
  • לְשַׁטֵחַ
  • צָפוּף

הדבר המיוחד בקידוד רשתות הוא שמעבדים מראש עיבוד קלט. עיבוד מקדים קלט אפשרי באמצעות preprocessing_layers ו preprocessing_combiner שכבות. ניתן לציין כל אחד מהם כמבנה מקונן. אם הקן preprocessing_layers הוא רדוד יותר מאשר input_tensor_spec , אז השכבות יקבלו את תת-הקנים. לדוגמה, אם:

input_tensor_spec = ([TensorSpec(3)] * 2, [TensorSpec(3)] * 5)
preprocessing_layers = (Layer1(), Layer2())

אז עיבוד מוקדם יתקשר:

preprocessed = [preprocessing_layers[0](observations[0]),
                preprocessing_layers[1](obsrevations[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 - 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([[7.026863 , 4.5458393, 4.7681847]], dtype=float32)>,
 ())

ניתן להשתמש באותה אסטרטגיה להתאמה אישית של כל אחת מהרשתות העיקריות בהן משתמשים הסוכנים. אתה יכול להגדיר עיבוד מראש כלשהו ולחבר אותו לשאר הרשת. כשאתה מגדיר מנהג משלך וודא שהגדרות שכבת הפלט של הרשת תואמות.