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
для всех узлов графа.
Параметры
-
Пояснения
-
Примеры¶
Составим простой граф, выполняющий следующие операции:
- Два полносвязных входных слоя 'linear0' и 'linear1'
- Разбиение тензора данных после первого входного слоя на три блока 'split'
- Конкатенация двух блоков от первого тензора с данными второго полносвзяного слоя 'concat0'
- Активация 'act' на конкатенации 'concat0'
- Финальная конкатенация '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. ]]