Graph

Описание

Контейнер, представляющий топологию сети в виде графа.

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

def __init__(self, inputs, outputs, unsafe=False, nodesOnly=False, name=None):

Параметры

Параметр Возможные типы Описание По умолчанию
inputs Union[Node, list] Входные узлы графа -
outputs Union[Node, list] Выходные узлы графа -
unsafe bool Включает/отключает безопасное размещение тензоров на GPU False
nodesOnly bool Если True, то в атрибутах графа не будет сохранена информация об используемых в нём модулях False
name str Имя контейнера None

Пояснения

unsafe - для некоторых модулей возможна перезапись их тензоров на GPU для экономии памяти. Если флаг unsafe опущен, то будет производиться валидация графа на отсутствие участков, приводящих к нарушению целостности тензоров данных на GPU из-за флагов inplace;


nodesOnly - в атрибуте графа nodes сохраняются данные о включённых в него узлах, а при опущенном флаге nodesOnly в отдельном атрибуте modules сохраняется информация о модулях, соответствующих этим узлам.

Методы

gatherTopology

def gatherTopology(self, node, nodesOnly):
Функционал
Собирает информацию о топологии графа, сохраняет её в атрибутах класса, а также при определённых условиях проводит валидацию графа на наличие участков, которые могут привести к нарушению целостности тензоров данных на GPU.

Параметры

Параметр Возможные типы Описание По умолчанию
node Node Объект класса-наследника Node, являющийся входной нодой графа -
nodesOnly bool Если True, то в атрибутах графа не будет сохранена информация об используемых в нём модулях -

Пояснения

-

getBlueprint

def getBlueprint(self):
Функционал
Формирует словарь, содержащий всю необходимую информацию о структуре графа для его восстановления при отсутствии кода.

Параметры

-

Пояснения

-

getNodeByName

def getNodeByName(self, name):
Функционал
Возвращает узел графа (объект класса-наследника Node) по его имени.

Параметры

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

Пояснения

-

optimizeForShape

def optimizeForShape(self, shape, memlimit=None):
Функционал
Производит оптимизацию графа под заданный входной размер.

Параметры

Параметр Возможные типы Описание По умолчанию
shape tuple Входной шейп, под который будет проводиться оптимизация -
memlimit int Лимит выделяемой для оптимизации оперативной памяти None

Пояснения

-

updateData

def updateData(self, data):
Функционал
Начиная с входных нод, производит последовательный проход по графу, применяя закреплённые за узлами операции над данными.

Параметры

Параметр Возможные типы Описание По умолчанию
data tensor Тензор входных данных -

Пояснения

-

dataShapeFrom

def dataShapeFrom(self, shape):
Функционал
Вычисляет шейп данных после их прохода по графу.

Параметры

Параметр Возможные типы Описание По умолчанию
shape Union[list, tuple] Шейп входных данных -

Пояснения
shape - tuple, если один входной узел и List[tuple], если входных нод несколько.

graphDataShape

def graphDataShape(self, shape, onmodule):
Функционал
Базовый метод для вычисления шейпа данных после их прохода по графу. Принимает вспомогательную функцию как аргумент, предоставляя возможность проведения дополнительной операции при вычислении шейпов.

Параметры

Параметр Возможные типы Описание По умолчанию
shape Union[list, tuple] Шейп входных данных -
onmodule Callable Дополнительная функция -

Пояснения
shape - см. dataShapeFrom;


onmmodule - дополнительная функция, которая будет применяться при вычислениях шейпов; как правило, это функция оптимизации ноды под её выходной шейп.

backward

def backward(self, grad, updParamGrads=True, updGrad=True, scale=1.0, momentum=0.0):
Функционал
Начиная с выходных узлов, проходит по графу в обратном направлении, осуществляя алгоритм обратного распространения ошибки - вычисление градиентов на параметры узлов и на их входные данные.

Параметры

Параметр Возможные типы Описание По умолчанию
grad tensor Тензор градиента целевой функции -
updParamGrads bool Флаг, регулирующий вычисление градиента на параметры узла True
updGrad bool Флаг, регулирующий вычисление градиента на входные данные узла True
scale float Масштаб: определяет, как сильно масштабировать градиент 1.0
momentum float Момент, коэффициент сохранения: определяет, сколько градиента нужно сохранить в этой итерации 0.0

Пояснения

-

gradShapeFrom

def gradShapeFrom(self, shape):
Функционал
Вычисляет шейп градиента на входных нодах графа.

Параметры

Параметр Возможные типы Описание По умолчанию
shape Union[list, tuple] Шейп градиента выходных узлов графа -

Пояснения

-

updateGrad

def updateGrad(self, grad):
Функционал
Заглушка.

Параметры

Параметр Возможные типы Описание По умолчанию
grad tensor Тензор градиента -

Пояснения

-

reset

def reset(self):
Функционал
Обнуляет внутреннее состояние графа и его узлов (подробнее см. Node.reset)

Параметры

-

Пояснения

-

clearTraverse

def clearTraverse(self):
Функционал
Опускает флаги прохода fwdVisited и bwdVisited для всех узлов графа.

Параметры

-

Пояснения

-

Примеры


Составим простой граф, выполняющий следующие операции:

  1. Два полносвязных входных слоя 'linear0' и 'linear1'
  2. Разбиение тензора данных после первого входного слоя на три блока 'split'
  3. Конкатенация двух блоков от первого тензора с данными второго полносвзяного слоя 'concat0'
  4. Активация 'act' на конкатенации 'concat0'
  5. Финальная конкатенация 'concat1' оставшегося блока от 'split' и данных после активации 'act'

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

import numpy as np
from PuzzleLib.Backend import gpuarray
from PuzzleLib.Containers import Graph
from PuzzleLib.Modules import Linear, Split, Concat, Activation, relu

Info

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

Создание узлов будущего графа:

v1 = Linear(10, 5, name="linear0").node()
h1 = Split(axis=1, sections=(2, 2, 1), name="split").node(v1)
v2 = Linear(10, 5, name="linear1").node()
h2 = Concat(axis=1, name="concat0").node((h1, [1, 2]), v2)
h3 = Activation(relu, name="act").node(h2)
h4 = Concat(axis=1, name="concat1").node((h1, 0), h3)

Инициализация самого графа:

graph = Graph(inputs=[v1, v2], outputs=h4)

Подготовка синтетических данных и их загрузка на GPU:

np.random.seed(123)
v1data = gpuarray.to_gpu(np.random.randint(0, 255, (5, 10)).astype(np.float32))
v2data = gpuarray.to_gpu(np.random.randint(0, 255, (5, 10)).astype(np.float32))

Прогон данных по графу:

graph([v1data, v2data])

Подготовка данных (загрузка с GPU в оперативную память с помощью метода get) со 'split' слоя и их вывод на экран. Метод round здесь и далее используется только для упрощения визуального восприятия тензоров:

splitData = [d.get() for d in graph["split"].data]
for i, data in enumerate(splitData):
... print("split block {} results: \n{}".format(i, data.round(1)))
split block 0 results:
[[-306.6 -436.2]
 [-210.  -386.2]
 [-476.1 -364.3]
 [-185.  -217.1]
 [-334.  -413. ]]
split block 1 results:
[[-272.2   52.7]
 [-169.8   13.8]
 [-242.3   57.7]
 [ -50.7   59. ]
 [-245.6   69.7]]
split block 2 results:
`[[296.1]
 [180.9]
 [330.7]
 [124.1]
 [201.5]]

Результаты с других слоёв:

# 'linear1' layer results
print(graph["linear1"].data.get().round(1))
[[ -92.3  241.8  -80.2   18.4   40.3]
 [ -50.2  178.3  -65.8    9.8  -97. ]
 [ -15.3  122.3 -177.9  -26.6 -187.2]
 [ -84.4  293.8 -132.5  -78.5  -58.7]
 [  24.9   34.2 -126.4  -15.8    8. ]]
# 'concat0' layer results
print(graph["concat0"].data.get().round(1))
[[  17.1 -348.5 -222.5  -92.3  241.8  -80.2   18.4   40.3]
 [  82.6 -332.7 -235.6  -50.2  178.3  -65.8    9.8  -97. ]
 [  28.1 -298.3 -102.7  -15.3  122.3 -177.9  -26.6 -187.2]
 [  33.8 -176.1  -96.6  -84.4  293.8 -132.5  -78.5  -58.7]
 [  13.3 -285.  -190.7   24.9   34.2 -126.4  -15.8    8. ]]
# 'act' layer results
print(graph["act"].data.get().round(1))
[[ 17.1   0.    0.    0.  241.8   0.   18.4  40.3]
 [ 82.6   0.    0.    0.  178.3   0.    9.8   0. ]
 [ 28.1   0.    0.    0.  122.3   0.    0.    0. ]
 [ 33.8   0.    0.    0.  293.8   0.    0.    0. ]
 [ 13.3   0.    0.   24.9  34.2   0.    0.    8. ]]
# 'concat1' layer results
print(graph["concat1"].data.get().round(1))
[[205.1  40.4  17.1   0.    0.    0.  241.8   0.   18.4  40.3]
 [145.4  55.7  82.6   0.    0.    0.  178.3   0.    9.8   0. ]
 [112.4 175.7  28.1   0.    0.    0.  122.3   0.    0.    0. ]
 [ 50.4 145.5  33.8   0.    0.    0.  293.8   0.    0.    0. ]
 [216.4 137.9  13.3   0.    0.   24.9  34.2   0.    0.    8. ]]