เครือข่าย

บทนำ

ใน colab นี้ เราจะพูดถึงวิธีกำหนดเครือข่ายที่กำหนดเองสำหรับตัวแทนของคุณ เครือข่ายช่วยเรากำหนดรูปแบบที่ได้รับการฝึกอบรมโดยตัวแทน ใน 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

ในตัวแทน TF เราประเภทรองจาก Keras เครือข่าย ด้วยสิ่งนี้ เราสามารถ:

  • ลดความซับซ้อนของการดำเนินการคัดลอกที่จำเป็นเมื่อสร้างเครือข่ายเป้าหมาย
  • ดำเนินการสร้างตัวแปรอัตโนมัติเมื่อโทร network.variables()
  • ตรวจสอบอินพุตตามเครือข่าย input_specs

การเข้ารหัสเครือข่าย

ดังที่ได้กล่าวข้างต้น 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)>,
 ())

กลยุทธ์เดียวกันนี้สามารถใช้เพื่อปรับแต่งเครือข่ายหลักที่ตัวแทนใช้ คุณสามารถกำหนดการประมวลผลล่วงหน้าใดๆ และเชื่อมต่อกับส่วนที่เหลือของเครือข่าย ในขณะที่คุณกำหนดแบบกำหนดเองของคุณ ตรวจสอบให้แน่ใจว่าคำจำกัดความของเลเยอร์เอาต์พุตของเครือข่ายตรงกัน