Sequential

Описание

Контейнер, осуществляющий последовательное соединение модулей.

Инициализация

def __init__(self, name=None):

Параметры

Параметр Возможные типы Описание По умолчанию
name str Имя контейнера None

Пояснения

-

Примеры


Простая последовательность


Простая последовательность:

  1. Паддинг входного тензора снизу и справа 2 дополнительными строками/столбцами
  2. Пулинг по максимальному значению
  3. Уплощение тензора

Необходимые импорты:

import numpy as np
from PuzzleLib.Backend import gpuarray
from PuzzleLib.Containers import Sequential
from PuzzleLib.Modules import Pad2D, MaxPool2D, Flatten

Info

gpuarray необходим для правильного размещения тензора на GPU

Инициализация последовательности и добавление к ней вышеперечисленных операций методом append:

seq = Sequential()
seq.append(Pad2D(pad=(0, 2, 0, 2), fillValue=0, name="pad"))
seq.append(MaxPool2D(name="pool"))
seq.append(Flatten(name="flatten"))

Синтетический тензор:

np.random.seed(123)
data = np.random.randint(0, 127, size=(1, 1, 4, 4)).astype(np.float32)
print(data)
[[[[126. 109. 126.  66.]
   [ 92.  98. 102.  17.]
   [ 83. 106. 123.  57.]
   [ 86.  97.  96. 113.]]]]

Important

Для корректной работы библиотеки с тензорами, имеющими четыре оси (например, картинки с осями NCHW, где N - номер тензора в батче, C - количество каналов (карт), H - высота, W - ширина), должно выполняться два условия:

  • Последовательность осей тензора - (N, C, H, W)
  • Тип данных тензора - float32

Размещение ихсодного тензора на GPU и его прогон через последовательность:

seq(gpuarray.to_gpu(data))

Tip

К любому элементу последовательности можно обратиться либо по его имени, либо по его индексу

Результат:

# 'pad' layer results
print(seq["pad"].data)
[[[[126. 109. 126.  66.   0.   0.]
   [ 92.  98. 102.  17.   0.   0.]
   [ 83. 106. 123.  57.   0.   0.]
   [ 86.  97.  96. 113.   0.   0.]
   [  0.   0.   0.   0.   0.   0.]
   [  0.   0.   0.   0.   0.   0.]]]]
# 'pool' layer results
print(seq["pool"].data)
[[[[126. 126.   0.]
   [106. 123.   0.]
   [  0.   0.   0.]]]]
# 'flatten' layer results
print(seq["flatten"].data)
[[126. 126.   0. 106. 123.   0.   0.   0.   0.]]


Циклическое расширение


Допустим, в сети необходимо несколько раз повторить один и тот же набор блоков, которые состоят, например, из:

  1. Умножение тензора на константу
  2. Активация ("ReLU")

Необходимые импорты:

from PuzzleLib.Modules import MulAddConst, Activation

Функция для создания составных блоков:

def block(numb):
  block = Sequential()

  block.append(MulAddConst(a=2, b=0, name="mul_const_{}".format(numb)))
  block.append(Activation(activation="relu", name="act_{}".format(numb)))

  return block

Расширение базовой последовательности блоками:

seq = Sequential()
for i in range(3):
... seq.extend(block(i))

Синтетический тензор:

np.random.seed(123)
data = np.random.randint(-5, 5, size=(1, 1, 4, 4)).astype(np.float32)
print(data)
[[[[-3. -3.  1. -4.]
   [-2.  4.  1. -4.]
   [-5. -4.  4. -5.]
   [-5.  4. -2. -1.]]]]

Размещение ихсодного тензора на GPU и его прогон через последовательность:

seq(gpuarray.to_gpu(data))

Результат:

# 'mul_const_0' layer results
print(seq["mul_const_0"].data)
[[[[ -6.  -6.   2.  -8.]
   [ -4.   8.   2.  -8.]
   [-10.  -8.   8. -10.]
   [-10.   8.  -4.  -2.]]]]
# 'act_0' layer results
print(seq["act_0"].data)
[[[[0. 0. 2. 0.]
   [0. 8. 2. 0.]
   [0. 0. 8. 0.]
   [0. 8. 0. 0.]]]]