本頁面由 Cloud Translation API 翻譯而成。
Switch to English

網路

在TensorFlow.org上查看 在Google Colab中運行 在GitHub上查看源代碼 下載筆記本

介紹

在本次合作中,我們將介紹如何為您的代理定義自定義網絡。網絡幫助我們定義了由代理商訓練的模型。在TF-Agent中,您會發現幾種不同類型的網絡,這些網絡在代理之間非常有用:

主要網絡

  • QNetwork :在Qlearning中用於具有離散操作的環境,該網絡將觀察結果映射到每個可能操作的值估計。
  • CriticNetworks :在文獻中也稱為ValueNetworks ,學習估計Value函數的某些版本,將某些狀態映射到策略的預期收益的估計中。這些網絡估計代理當前處於何種狀態。
  • ActorNetworks :了解從觀察到動作的映射。我們的政策通常使用這些網絡來生成操作。
  • ActorDistributionNetworks :類似於ActorNetworks但是它們生成一個分發,然後策略可以ActorNetworks分發進行採樣以生成操作。

輔助網絡

  • EncodingNetwork :允許用戶輕鬆定義預處理層的映射以應用於網絡的輸入。
  • DynamicUnrollLayer :在按時間順序應用時,自動在情節邊界上重置網絡狀態。
  • ProjectionNetwork :諸如CategoricalProjectionNetworkNormalProjectionNetwork類的網絡NormalProjectionNetwork接受輸入並生成所需的參數以生成Categorical或正態分佈。

TF-Agents中的所有示例均帶有預配置的網絡。但是,這些網絡未設置為處理複雜的觀測結果。

如果您的環境暴露了多個觀察/操作,並且需要自定義網絡,那麼本教程非常適合您!

建立

如果尚未安裝tf-agent,請運行:

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-Agent中,我們從Keras Networks繼承了子類。有了它,我們可以:

  • 簡化創建目標網絡時所需的複制操作。
  • 調用network.variables()時執行自動變量創建。
  • 根據網絡input_specs驗證輸入。

編碼網絡

如上所述, EncodingNetwork允許我們輕鬆定義預處理層的映射,以應用於網絡輸入以生成某種編碼。

EncodingNetwork由以下主要可選層組成:

  • 預處理層
  • 預處理組合器
  • 轉換2D
  • 展平
  • 稠密

關於編碼網絡的特殊之處在於應用了輸入預處理。可以通過preprocessing_layerspreprocessing_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])]

但是如果

0

然後預處理將調用:

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([[7.026863 , 4.5458393, 4.7681847]], dtype=float32)>,
 ())

可以使用相同的策略來自定義代理使用的任何主要網絡。您可以定義任何預處理並將其連接到網絡的其餘部分。在定義自己的自定義項時,請確保網絡的輸出層定義匹配。