Parallel¶
Описание¶
Контейнер, осуществляющий параллельное соединение (ветвление) модулей.
Инициализация¶
def __init__(self, name=None)
Параметры
Параметр | Возможные типы | Описание | По умолчанию |
---|---|---|---|
name | str | Имя контейнера | None |
Пояснения
-
Примеры¶
Простое распараллеливание¶
Нужно реализовать следующую сеть:
-
Ветвь, состоящая из двух модулей:
1.1 Умножение тензора на константу
1.2 Активация ("ReLU") -
Параллельно первой ветви модуль транспонирования
- Суммирование результатов с двух ветвей
Необходимые импорты:
import numpy as np
from PuzzleLib.Backend import gpuarray
from PuzzleLib.Containers import Sequential, Parallel
from PuzzleLib.Modules import MulAddConst, Activation, Transpose, Replicate, Add
Info
gpuarray
необходим для правильного размещения тензора на GPU
Инициализация базовой последовательности:
net = Sequential()
Следующая операция создаёт необходимое количество копий входных данных, чтобы передать их параллельным ветвям сети:
net.append(Replicate(times=2, name="replicate"))
Функция для созданя первой ветви:
def branch1(name):
branch = Sequential(name=name)
branch.append(MulAddConst(a=2, b=0, name="mul_const"))
branch.append(Activation(activation="relu", name="act"))
return branch
Создание параллельного контейнера и добавление к нему первой ветви:
parallel_ = Parallel(name="parallel")
parallel_.append(branch1("branch"))
Добавление второй ветви, состоящей из одного модуля транспонирования:
parallel_.append(Transpose(axes=(0, 1, 3, 2), name="transpose"))
Присоединение параллельного контейнера к сети и добавление модуля суммирования на выход параллельного участка:
net.append(parallel_)
net.append(Add(name="add"))
Синтетический тензор:
np.random.seed(123)
data = np.random.randint(-5, 5, size=(1, 1, 3, 3)).astype(np.float32)
print(data)
[[[[-3. -3. 1.]
[-4. -2. 4.]
[ 1. -4. -5.]]]]
Important
Для корректной работы библиотеки с тензорами должно выполняться два условия:
- Шейп входного тензора - (N, C, H, W), где N - номер тензора в батче, C - количество каналов (карт), H - высота, W - ширина
- Тип данных тензора - float32
Размещение ихсодного тензора на GPU и его прогон через последовательность:
net(gpuarray.to_gpu(data))
Tip
К любому элементу последовательности можно обратиться либо по его имени, либо по его индексу
Результат:
# parallel.transpose layer results
print(net["parallel"]["transpose"].data)
[[[[-3. -4. 1.]
[-3. -2. -4.]
[ 1. 4. -5.]]]]
# parallel.branch.mul_const layer results
print(net["parallel"]["branch"]["mul_const"].data)
[[[[ -6. -6. 2.]
[ -8. -4. 8.]
[ 2. -8. -10.]]]]
# parallel.branch.act layer results
print(net["parallel"]["branch"]["act"].data)
[[[[0. 0. 2.]
[0. 0. 8.]
[2. 0. 0.]]]]
# add layer results
print(net["add"].data)
[[[[-3. -4. 3.]
[-3. -2. 4.]
[ 3. 4. -5.]]]]