TF-Agents 0.4 Tutorials : ネットワーク (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/22/2020 (0.4)
* 本ページは、TF Agents の以下のドキュメントを翻訳した上で適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
ネットワーク
イントロダクション
この colab では貴方のエージェントのためにどのようにカスタム・ネットワークを定義するかをカバーします。ネットワークはエージェントにより訓練されるモデルを定義することを手助けします。TF-Agents では幾つかの異なるタイプのネットワークを見つけるでしょう、これらはエージェントに渡り有用です :
主要ネットワーク
- QNetwork: 離散アクションを持つ環境のために Qlearning で使用されます、このネットワークは観測を各々の可能なアクションのための値推定にマップします。
- CriticNetworks: 文献では ValueNetworks としても参照されます、ある状態をポリシーの期待リターンのための推定にマップする価値 (Value) 関数のあるバージョンを推定するために学習します。これらのネットワークはエージェントが現在在る状態がどれほど良いかを推定します。
- ActorNetworks: 観測からアクションへのマッピングを学習します。これらのネットワークは通常はアクションを生成するためにポリシーにより使用されます。
- ActorDistributionNetworks: ActorNetworks に類似していますが、これらはポリシーがアクションを生成するためにサンプリングできる分布を生成します。
Helper ネットワーク
- EncodingNetwork: ネットワークの入力に適用する前処理層のマッピングを容易に定義することをユーザに可能にします。
- DynamicUnrollLayer:それが時間シークエンスに渡り適用されるときエピソード境界上でネットワークの状態を自動的にリセットします。
- ProjectionNetwork: CategoricalProjectionNetwork or NormalProjectionNetwork のようなネットワークは入力を取りカテゴリカル or 正規分布を生成するために必要なパラメータを生成します。
TF-Agents の総てのサンプルは事前構成されたネットワークを装備しています。けれどもこれらのネットワークは複雑な観測を処理するためにセットアップされていません。
一つの観測/アクションより多くを公開する環境を持ちネットワークをカスタマイズする必要がある場合には、このチュートリアルは貴方のためです!
セットアップ
tf-agents をまだインストールしてないのであれば、以下を実行します :
!pip install --upgrade tensorflow_probability !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 tf.compat.v1.enable_v2_behavior()
ネットワークを定義する
Network API
TF-Agents では Keras ネットワーク からサブクラス化します。それで以下が可能です :
- ターゲットネットワークを作成するとき必要な copy 演算を単純化する。
- network.variables() を呼び出すとき自動変数作成を遂行する。
- ネットワーク input_specs に基づいて入力を検証する。
EncodingNetwork
上で言及したように EncodingNetwork はあるエンコーディングを生成するためにネットワークの入力に適用する前処理層のマッピングを容易に定義することを可能にします。
EncodingNetwork は以下の殆どオプションの層から成ります :
- 前処理層
- 前処理 combiner
- Conv2D
- Flatten
- Dense
encoding ネットワークの特別なことは入力前処理が適用されることです。入力前処理は preprocessing_layers と preprocessing_combiner 層を通して可能です。これらの各々はネストされた構造として指定できます。もし preprocessing_layers ネストが input_tensor_spec よりも浅い場合、層はサブネストを得ます。例えば、
if : input_tensor_spec = ([TensorSpec(3)] * 2, [TensorSpec(3)] * 5) preprocessing_layers = (Layer1(), Layer2()) then 前処理は次を呼び出します : preprocessed = [preprocessing_layers[0](observations[0]), preprocessing_layers[1](obsrevations[1])] けれども if preprocessing_layers = ([Layer1() for _ in range(2)], [Layer2() for _ in range(5)]) then 前処理は次を呼び出します : preprocessed = [ layer(obs) for layer, obs in zip(flatten(preprocessing_layers), flatten(observations)) ]
カスタムネットワーク
貴方自身のネットワークを作成するためには __init__ と call メソッドを override しなければならないだけです。画像とベクトルを含む観測を取る ActorNetwork を作成するため EncodingNetworks について学習したことを使用してカスタムネットワークを作成しましょう。
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)
actor ネットワークを持つ今、環境からの観測を処理できます。
time_step = tf_env.reset() actor(time_step.observation, time_step.step_type)
エージェントに使用される任意の主要ネットワークをカスタマイズするために同じストラテジーが使用できます。前処理が何であろうと定義してそれをネットワークの残りに接続できます。貴方自身のカスタムを定義するときネットワークの出力層定義が適合することを確実にしてください。
以上