Занятие №9:

Инструменты обучения с подкреплением. TensorFlow

Основные понятия

Основные понятия

Основные инструменты

  • NumPy - библиотека для научных вычислений и реализации матричных операций и общих функций;

  • Gym - фреймворк для ОП, который имеет различные среды, с которыми можно взаимодействовать унифицированным способом;

  • Google Collab - сервис, позволяющий писать и выполнять код Python в браузере;

  • TensorFlow - это фреймворк с открытым исходным кодом, созданный Google. С помощью него можно работать с нейронными сетями и алгоритмами машинного обучения на языке Python;

  • OpenCV Python: это библиотека компьютерного зрения, которая предоставляет множество функций для обработки изображений.

Основные понятия

OpenAI Gym API

  • Набор действий, которые разрешено выполнять в среде. Gym поддерживает как дискретные, так и непрерывные действия, а также их сочетание.
  • Форма и границы наблюдений, которые среда предоставляет агенту;
  • Метод, называемый step, для выполнения действия, которое возвращает текущее наблюдение, награду и указание на то, что эпизод окончен;

  • Метод под названием reset, который возвращает среду в исходное состояние и получает первое наблюдение;

OpenAI Gym API

Основные понятия

Основные понятия ОП

  • Действия;

  • Наблюдения;

  • Среда.

Иерархия класса Space в Gym

Space

Discrete

Tuple

Box

sample()
contains()

low
high
shape

n

spaces

Класс Space

  • sample (): возвращает случайную выборку из пространства;
  • contains (x): проверяет, принадлежит ли аргумент x домену пространства.

Базовый абстрактный класс Space включает в себя два актуальных для нас метода:

Среда

Как упоминалось ранее, среда представлена в Gym классом Env, который имеет следующие члены:

  • action_space: это поле класса Space, содержащее спецификацию разрешенных действий в среде;
  • observation_space: это поле имеет тот же класс пространства, но определяет наблюдения, предоставляемые средой;
  • reset(): сбрасывает среду в исходное состояние, возвращая начальный вектор наблюдения;
  • step(): этот метод позволяет агенту выполнить действие и возвращает информацию о результате действия - следующем наблюдении, локальной награде и флаге конца эпизода.

Метод step

  • Сообщаем среде, какое действие мы выполним на следующем шаге;
  • Получение нового наблюдения из окружающей среды после этого действия;
  • Получение награды, полученной агентом на этом шаге;
  • Получение индикации того, что серия окончена.

Первый элемент (действие) передается этому методу как единственный аргумент, а остальные возвращаются методом step(). Точнее, это кортеж из четырех элементов (наблюдение, награда, выполнение и информация). У них есть следующие типы и значения:

  • observation - это вектор NumPy или матрица с данными наблюдения;
  • reward - это стоимость вознаграждения;
  • done - это логический индикатор, который принимает значение True, когда эпизод окончен;
  • info - это может быть что угодно, относящееся к среде, с дополнительной информацией об окружающей среде. Обычно это значение игнорируется в общих методах RL.
  1. Заходим в Google Collab через почту exampleacc427@gmail.com;
  2. Переходим по ссылке
    https://colab.research.google.com/notebooks/intro.ipynb#recent=true

Google Collab

import gym

e = gym.make('CartPole-v0')
obs = e.reset()
obs

e.action_space
e.observation_space
e.step(0)
e.action_space.sample()
e.observation_space.sample()

Пример 1

Пример 1

array([-0.00633125, -0.01298565, -0.0023605 ,  0.0295462 ])
Discrete(2)
Box(-3.4028234663852886e+38, 3.4028234663852886e+38, (4,), float32)
(array([-0.01075244, -0.40317037,  0.0046601 ,  0.61360778]), 1.0, False, {})
0
array([ 4.2740717e+00,  3.4415352e+37,  1.4436652e-01, -3.2048665e+38],
      dtype=float32)

Пример 2

from pyvirtualdisplay import Display
from gym.wrappers.monitoring.video_recorder import VideoRecorder
import gym

display = Display(visible=0, size=(400, 300))
display.start()

env = gym.make("CartPole-v0")
env = gym.wrappers.Monitor(env, "recording")

video = VideoRecorder(env, "CartPole.mp4")

for i in range(1000):
  
  done = False
  reward = 0
  env.reset()
  
  while not done:
    env.render()

Пример 2

    video.capture_frame()
  
    # выбрать случайное действие
    action = env.action_space.sample()
  
    # выполнить один шаг взаимодействия с окружающей средой
    new_obs, rew, done, info = env.step(action)
    reward += rew
    # если завершено, напечатать полное 
    # вознаграждение в игре и сбросить среду
    if done:
      print('Эпизод %d завершен, Вознаграждение:%d' (i, reward)
      env.reset()
      
video.close()
env.close()

Пример 2

Эпизод 0 завершен; Вознаграждение:40
Эпизод 1 завершен; Вознаграждение:14
Эпизод 2 завершен; Вознаграждение:11
Эпизод 3 завершен; Вознаграждение:10
Эпизод 4 завершен; Вознаграждение:24
Эпизод 5 завершен; Вознаграждение:11
Эпизод 6 завершен; Вознаграждение:9
Эпизод 7 завершен; Вознаграждение:15
Эпизод 8 завершен; Вознаграждение:15
Эпизод 9 завершен; Вознаграждение:13
Эпизод 10 завершен; Вознаграждение:18
Эпизод 11 завершен; Вознаграждение:13
Эпизод 12 завершен; Вознаграждение:11
Эпизод 13 завершен; Вознаграждение:25
Эпизод 14 завершен; Вознаграждение:14
Эпизод 15 завершен; Вознаграждение:19

Пример работы

TensorFlow

Особенности

  • Библиотека с открытым исходным кодом;

  • Кроссплатформенность;

  • Быстрая отладка;

  • Эффективность;

  • Масштабируемость;

  • Легко проводить эксперименты;

  • Абстракция;

  • Гибкость.

Тензоры

import tensorflow as tf

c = tf.constant([[1.0, 2.0], [3.0, 4.0]])
d = tf.constant([[1.0, 1.0], [0.0, 1.0]])
e = tf.add(c, d)
print(e)

tf_var = tf.Variable([1, 2])
tf_const = tf.constant([1, 2])
tf_ph = tf.keras.Input(shape=(), dtype=tf.dtypes.float32)
tf_spts = tf.SparseTensor(indices=[[0, 0], [1, 2]], \
                          values=[1, 2], dense_shape=[3, 4])

print('Type of tf.Variable is: ', type(tf_var))
print('Type of tf.constant is: ', type(tf_const))
print('Type of tf.placeholder is: ', type(tf_ph))
print('Type of tf.SparseTensor is: ', type(tf_spts))

Тензоры

tf.Tensor(
[[2. 3.]
 [3. 5.]], shape=(2, 2), dtype=float32)

Type of tf.Variable is:  <class 'tensorflow.python.ops.
  resource_variable_ops.ResourceVariable'>
Type of tf.constant is:  <class 'tensorflow.python.framework.
  ops.EagerTensor'>
Type of tf.placeholder is:  <class 'tensorflow.python.keras.
  engine.keras_tensor.KerasTensor'>
Type of tf.SparseTensor is:  <class 'tensorflow.python.framework.
  sparse_tensor.SparseTensor'>

Тензоры

import tensorflow as tf
import numpy as np

tf.zeros([3, 4], tf.int32)
tf_var1 = tf.Variable(np.zeros((2,2)))
print(tf_var1)
print(tf_var1.shape)
<tf.Tensor: shape=(3, 4), dtype=int32, numpy=
array([[0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]], dtype=int32)>

<tf.Variable 'Variable:0' shape=(2, 2) dtype=float64, numpy=
array([[0., 0.],
       [0., 0.]])>
(2, 2)

Нейронные сети

import tensorflow as tf
import numpy as np

data = np.arange(32).reshape(16, 2).astype(np.float32)
y = np.random.randint(0, 2, (16, ))
print(y)
print(data)

Нейронные сети

array([1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1])

[[ 0.  1.]
 [ 2.  3.]
 [ 4.  5.]
 [ 6.  7.]
 [ 8.  9.]
 [10. 11.]
 [12. 13.]
 [14. 15.]
 [16. 17.]
 [18. 19.]
 [20. 21.]
 [22. 23.]
 [24. 25.]
 [26. 27.]
 [28. 29.]
 [30. 31.]]

Нейронные сети

model = tf.keras.Sequential()
model.add(tf.keras.Input(shape=(16,2)))
model.add(tf.keras.layers.Dense(8))
model.add(tf.keras.layers.ReLU())
model.add(tf.keras.layers.Dense(1))
model.compile(optimizer="Adam", loss="mse", metrics=["mae"])
model.fit(data, y)

test = np.arange(2).reshape(1, 2).astype(np.float32)

model.predict(test)

Нейронные сети

WARNING:tensorflow:Please add `keras.layers.InputLayer` instead of `keras.Input` to Sequential model. `keras.Input` is 
  intended to be used by Functional model.
WARNING:tensorflow:Model was constructed with shape (None, 16, 2) for input KerasTensor(type_spec=TensorSpec(shape=(None, 16, 2), 
  dtype=tf.float32, name='input_5'), name='input_5', description="created by layer 'input_5'"), but it was called on an input with 
  incompatible shape (None, 2).
WARNING:tensorflow:Model was constructed with shape (None, 16, 2) for input KerasTensor(type_spec=TensorSpec(shape=(None, 16, 2), 
  dtype=tf.float32, name='input_5'), name='input_5', description="created by layer 'input_5'"), but it was called on an input with 
  incompatible shape (None, 2).
1/1 [==============================] - 0s 369ms/step - loss: 342.8323 - mae: 15.8921
<tensorflow.python.keras.callbacks.History at 0x7f9037170690>

WARNING:tensorflow:Model was constructed with shape (None, 16, 2) for input KerasTensor(type_spec=TensorSpec(shape=(None, 16, 2), 
  dtype=tf.float32, name='input_7'), name='input_7', description="created by layer 'input_7'"), but it was called on an input with 
  incompatible shape (None, 2).
WARNING:tensorflow:6 out of the last 7 calls to <function Model.make_predict_function.<locals>.predict_function at 0x7f9034621290> 
  triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) 
  creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects 
  instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has 
  experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), 
  please refer to https://www.tensorflow.org/guide/function
  #controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for  more details.
array([[0.04830413]], dtype=float32)

Собственные слои

class CustomLayer(tf.keras.layers.Layer):
  def __init__(self, num_inputs, num_classes):
    super(CustomLayer, self).__init__()
    self.pipe = tf.keras.Sequential([
      tf.keras.Input
      (shape=(num_inputs,2)),
      tf.keras.layers.Dense(8),
      tf.keras.layers.ReLU(),
      tf.keras.layers.Dense(2)])
    
    
  def call(self, x):
    return self.pipe(x)

Собственные слои

x = tf.constant([[1,2], [3,4], [5,6], 
                 [7,8], [9,10], [11,12],
                 [13,14], [15,16], [17,18],
                 [19,20], [21,22], [23,24],
                 [25,26], [27,28], [29,30],
                 [31,32]])
net = CustomLayer(num_inputs=16, num_classes=2)
y = net(x)
print(y)

Собственные слои

tf.Tensor(
[[0.9619826  0.56262267]
 [1.1019492  0.9236295 ]
 [1.4762537  1.3264978 ]
 [1.8505583  1.729366  ]
 [2.2248626  2.132234  ]
 [2.599167   2.5351024 ]
 [2.973472   2.9379709 ]
 [3.3477762  3.3408387 ]
 [3.7220812  3.7437074 ]
 [4.096385   4.146575  ]
 [4.4706903  4.5494437 ]
 [4.8449945  4.9523115 ]
 [5.2192993  5.35518   ]
 [5.593604   5.75805   ]
 [5.967908   6.1609163 ]
 [6.3422127  6.5637846 ]], shape=(16, 2), dtype=float32)

Сверточные нейронные сети

import numpy as np
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt

(train_images, train_labels), (test_images, test_labels) 
= datasets.cifar10.load_data()

train_images, test_images = train_images / 255.0, 
test_images / 255.0

class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
               'dog', 'frog', 'horse', 'ship', 'truck']

Сверточные нейронные сети

plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5,5,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i])
    # Метки датасета CIFAR оказываются массивами, 
    # вот почему нам нужен дополнительный индекс
    plt.xlabel(class_names[train_labels[i][0]])
plt.show()

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), 
           activation='relu', input_shape=(32, 32, 3)))
model.add(layers.Flatten())
model.add(layers.Dense(10))

Сверточные нейронные сети

model.summary()
model.compile(optimizer='adam',
 loss=tf.keras.losses.SparseCategoricalCrossentropy
              (from_logits=True),
 metrics=['accuracy'])
history = model.fit(train_images, train_labels, epochs=10, 
  validation_data=(test_images, test_labels))
Epoch 1/10
1563/1563 [==============================] - 36s 23ms/step - loss: 1.4428 - accuracy: 0.4953 - val_loss: 1.2616 - val_accuracy: 0.5508
Epoch 2/10
1563/1563 [==============================] - 35s 22ms/step - loss: 1.1537 - accuracy: 0.6007 - val_loss: 1.2462 - val_accuracy: 0.5737
Epoch 3/10
1563/1563 [==============================] - 35s 22ms/step - loss: 1.0325 - accuracy: 0.6434 - val_loss: 1.2243 - val_accuracy: 0.5757
Epoch 4/10
1563/1563 [==============================] - 35s 23ms/step - loss: 0.9388 - accuracy: 0.6776 - val_loss: 1.1702 - val_accuracy: 0.6041
Epoch 5/10
1563/1563 [==============================] - 35s 22ms/step - loss: 0.8599 - accuracy: 0.7037 - val_loss: 1.1698 - val_accuracy: 0.6102
Epoch 6/10
1563/1563 [==============================] - 35s 23ms/step - loss: 0.7840 - accuracy: 0.7331 - val_loss: 1.1931 - val_accuracy: 0.6112
Epoch 7/10
1563/1563 [==============================] - 35s 22ms/step - loss: 0.7230 - accuracy: 0.7510 - val_loss: 1.1658 - val_accuracy: 0.6174
Epoch 8/10
1563/1563 [==============================] - 35s 23ms/step - loss: 0.6655 - accuracy: 0.7730 - val_loss: 1.2132 - val_accuracy: 0.6026
Epoch 9/10
1563/1563 [==============================] - 35s 22ms/step - loss: 0.6199 - accuracy: 0.7875 - val_loss: 1.3312 - val_accuracy: 0.5802
Epoch 10/10
1563/1563 [==============================] - 35s 22ms/step - loss: 0.5729 - accuracy: 0.8051 - val_loss: 1.3603 - val_accuracy: 0.5877

Спасибо за понимание!

Занятие 9. Инструменты обучения с подкреплением. TensorFlow

By Astro Group

Занятие 9. Инструменты обучения с подкреплением. TensorFlow

  • 36