Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

Netzwerke

Ansicht auf TensorFlow.org In Google Colab ausführen Quelle auf GitHub anzeigen Notizbuch herunterladen

Einführung

In dieser Spalte erfahren Sie, wie Sie benutzerdefinierte Netzwerke für Ihre Agenten definieren. Die Netzwerke helfen uns, das Modell zu definieren, das von Agenten trainiert wird. In TF-Agents finden Sie verschiedene Arten von Netzwerken, die für verschiedene Agenten nützlich sind:

Hauptnetzwerke

  • QNetwork : Dieses Netzwerk wird in Qlearning für Umgebungen mit diskreten Aktionen verwendet und ordnet eine Beobachtung Wertschätzungen für jede mögliche Aktion zu.
  • CriticNetworks : In der Literatur auch als ValueNetworks , lernt man, eine Version einer Value-Funktion zu schätzen, die einen bestimmten Status einer Schätzung für die erwartete Rendite einer Richtlinie ValueNetworks . Diese Netzwerke schätzen, in welchem ​​Zustand sich der Agent derzeit befindet.
  • ActorNetworks : Lernen Sie eine Zuordnung von Beobachtungen zu Aktionen. Diese Netzwerke werden normalerweise von unseren Richtlinien verwendet, um Aktionen zu generieren.
  • ActorDistributionNetworks : Ähnlich wie ActorNetworks aber diese generieren eine Verteilung, die eine Richtlinie dann ActorNetworks kann, um Aktionen zu generieren.

Hilfsnetzwerke

  • EncodingNetwork : Ermöglicht Benutzern das einfache Definieren einer Zuordnung von Vorverarbeitungsebenen, die auf die Eingaben eines Netzwerks angewendet werden sollen.
  • DynamicUnrollLayer : Setzt den Netzwerkstatus an den Episodengrenzen automatisch zurück, wenn er über einen bestimmten Zeitraum angewendet wird.
  • ProjectionNetwork : Netzwerke wie CategoricalProjectionNetwork oder NormalProjectionNetwork nehmen Eingaben entgegen und generieren die erforderlichen Parameter, um kategoriale oder normale Verteilungen zu generieren.

Alle Beispiele in TF-Agents werden mit vorkonfigurierten Netzwerken geliefert. Diese Netzwerke sind jedoch nicht für komplexe Beobachtungen eingerichtet.

Wenn Sie eine Umgebung haben, in der mehr als eine Beobachtung / Aktion verfügbar ist, und Sie Ihre Netzwerke anpassen müssen, ist dieses Tutorial genau das Richtige für Sie!

Installieren

Wenn Sie tf-agent noch nicht installiert haben, führen Sie Folgendes aus:

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()

Netzwerke definieren

Netzwerk-API

In TF-Agenten wird eine Unterklasse von Keras Networks erstellt . Damit können wir:

  • Vereinfachen Sie die beim Erstellen von Zielnetzwerken erforderlichen Kopiervorgänge.
  • Führen Sie beim Aufruf von network.variables() automatische Variablenerstellung durch.
  • Überprüfen Sie Eingaben basierend auf Netzwerkeingabespezifikationen.

EncodingNetwork

Wie oben erwähnt, können wir mit dem EncodingNetwork auf einfache Weise eine Zuordnung von Vorverarbeitungsschichten definieren, die auf die Eingaben eines Netzwerks angewendet werden sollen, um eine Codierung zu generieren.

Das EncodingNetwork besteht aus den folgenden meist optionalen Ebenen:

  • Vorverarbeitungsschichten
  • Vorverarbeitungskombinierer
  • Conv2D
  • Ebnen
  • Dicht

Das Besondere an der Codierung von Netzwerken ist, dass die Eingabevorverarbeitung angewendet wird. Die Eingabevorverarbeitung ist über die Ebenen preprocessing_layers und preprocessing_combiner möglich. Jede dieser Strukturen kann als verschachtelte Struktur angegeben werden. Wenn das Nest der preprocessing_layers flacher als input_tensor_spec , erhalten die Ebenen die Unternester. Zum Beispiel, wenn:

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

dann ruft die Vorverarbeitung auf:

preprocessed = [preprocessing_layers[0](observations[0]),
                preprocessing_layers[1](observations[1])]

Wie auch immer, wenn

preprocessing_layers = ([Layer1() for _ in range(2)],
                        [Layer2() for _ in range(5)])

dann ruft die Vorverarbeitung auf:

preprocessed = [
  layer(obs) for layer, obs in zip(flatten(preprocessing_layers),
                                    flatten(observations))
]

Benutzerdefinierte Netzwerke

Um Ihre eigenen Netzwerke zu erstellen, müssen Sie nur die Methoden __init__ und call überschreiben. Erstellen wir ein benutzerdefiniertes Netzwerk mit den Informationen zu EncodingNetworks , um ein ActorNetwork zu erstellen, das Beobachtungen aufnimmt, die ein Bild und einen Vektor enthalten.

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

Erstellen wir eine RandomPyEnvironment , um strukturierte Beobachtungen zu generieren und unsere Implementierung zu validieren.

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)

Da wir die Beobachtungen als Diktat definiert haben, müssen wir Vorverarbeitungsebenen erstellen, um diese zu verarbeiten.

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)

Jetzt, wo wir das Akteursnetzwerk haben, können wir Beobachtungen aus der Umgebung verarbeiten.

time_step = tf_env.reset()
actor(time_step.observation, time_step.step_type)
(<tf.Tensor: shape=(1, 3), dtype=float32, numpy=array([[5.196383 , 5.20836  , 4.9908404]], dtype=float32)>,
 ())

Dieselbe Strategie kann verwendet werden, um jedes der von den Agenten verwendeten Hauptnetzwerke anzupassen. Sie können die Vorverarbeitung definieren und mit dem Rest des Netzwerks verbinden. Stellen Sie beim Definieren Ihrer eigenen benutzerdefinierten Elemente sicher, dass die Definitionen der Ausgabeschicht des Netzwerks übereinstimmen.