Caffe2 - Создание собственной сети
В этом уроке вы научитесь определять single layer neural network (NN)в Caffe2 и запустите его на случайно сгенерированном наборе данных. Мы напишем код для графического изображения сетевой архитектуры, печати ввода, вывода, весов и значений смещения. Чтобы понять этот урок, вы должны знатьneural network architectures, его terms и mathematics используется в них.
Сетевая архитектура
Давайте предположим, что мы хотим построить однослойную NN, как показано на рисунке ниже -
Математически эта сеть представлена следующим кодом Python -
Y = X * W^T + b
где X, W, b являются тензорами и Yэто выход. Мы заполним все три тензора случайными данными, запустим сеть и исследуемYвывод. Для определения сети и тензоров Caffe2 предоставляет несколькоOperator функции.
Операторы Caffe2
В Caffe2, Operatorэто основная единица вычисления. Кафе2Operator представлен следующим образом.
Caffe2 предоставляет исчерпывающий список операторов. Для сети, которую мы проектируем в настоящее время, мы будем использовать оператор FC, который вычисляет результат передачи входного вектора.X в полносвязную сеть с двумерной весовой матрицей W и одномерный вектор смещения b. Другими словами, он вычисляет следующее математическое уравнение
Y = X * W^T + b
где X имеет размеры (M x k), W имеет размеры (n x k) и b является (1 x n). ВыходY будет иметь размер (M x n), где M размер партии.
Для векторов X и W, мы будем использовать GaussianFillоператор для создания случайных данных. Для создания значений смещенияb, мы будем использовать ConstantFill оператор.
Теперь приступим к определению нашей сети.
Создание сети
Прежде всего, импортируйте необходимые пакеты -
from caffe2.python import core, workspace
Затем определите сеть, вызвав core.Net следующим образом -
net = core.Net("SingleLayerFC")
Имя сети указывается как SingleLayerFC. На этом этапе создается сетевой объект с именем net. Пока он не содержит слоев.
Создание тензоров
Теперь мы создадим три вектора, необходимые для нашей сети. Сначала мы создадим тензор X, вызвавGaussianFill оператор следующим образом -
X = net.GaussianFill([], ["X"], mean=0.0, std=1.0, shape=[2, 3], run_once=0)
В X вектор имеет размеры 2 x 3 со средним значением данных 0,0 и стандартным отклонением 1.0.
Точно так же мы создаем W тензор следующим образом -
W = net.GaussianFill([], ["W"], mean=0.0, std=1.0, shape=[5, 3], run_once=0)
В W вектор имеет размер 5 x 3.
Наконец, мы создаем предвзятость b матрица размера 5.
b = net.ConstantFill([], ["b"], shape=[5,], value=1.0, run_once=0)
Теперь наступает самая важная часть кода - определение самой сети.
Определение сети
Мы определяем сеть в следующем заявлении Python -
Y = X.FC([W, b], ["Y"])
Мы называем FC оператор входных данных X. Вес указан вWи предвзятость в b. На выходеY. В качестве альтернативы вы можете создать сеть, используя следующую инструкцию Python, которая является более подробной.
Y = net.FC([X, W, b], ["Y"])
На этом этапе сеть просто создана. Пока мы не запустим сеть хотя бы один раз, она не будет содержать никаких данных. Перед запуском сети рассмотрим ее архитектуру.
Архитектура сети печати
Caffe2 определяет сетевую архитектуру в файле JSON, который можно проверить, вызвав метод Proto на созданном net объект.
print (net.Proto())
Это дает следующий результат -
name: "SingleLayerFC"
op {
output: "X"
name: ""
type: "GaussianFill"
arg {
name: "mean"
f: 0.0
}
arg {
name: "std"
f: 1.0
}
arg {
name: "shape"
ints: 2
ints: 3
}
arg {
name: "run_once"
i: 0
}
}
op {
output: "W"
name: ""
type: "GaussianFill"
arg {
name: "mean"
f: 0.0
}
arg {
name: "std"
f: 1.0
}
arg {
name: "shape"
ints: 5
ints: 3
}
arg {
name: "run_once"
i: 0
}
}
op {
output: "b"
name: ""
type: "ConstantFill"
arg {
name: "shape"
ints: 5
}
arg {
name: "value"
f: 1.0
}
arg {
name: "run_once"
i: 0
}
}
op {
input: "X"
input: "W"
input: "b"
output: "Y"
name: ""
type: "FC"
}
Как вы можете видеть в приведенном выше листинге, он сначала определяет операторы X, W и b. Разберем определениеWНапример. ТипW указывается как GausianFill. Вmean определяется как float 0.0, стандартное отклонение определяется как float 1.0, а shape является 5 x 3.
op {
output: "W"
name: "" type: "GaussianFill"
arg {
name: "mean"
f: 0.0
}
arg {
name: "std"
f: 1.0
}
arg {
name: "shape"
ints: 5
ints: 3
}
...
}
Изучите определения X и bдля вашего собственного понимания. Наконец, давайте посмотрим на определение нашей однослойной сети, которое воспроизводится здесь.
op {
input: "X"
input: "W"
input: "b"
output: "Y"
name: ""
type: "FC"
}
Здесь тип сети FC (Полностью подключен) с X, W, b в качестве входов и Yэто выход. Это определение сети является слишком подробным, и для больших сетей будет утомительно изучать его содержимое. К счастью, Caffe2 предоставляет графическое представление созданных сетей.
Графическое представление сети
Чтобы получить графическое представление сети, запустите следующий фрагмент кода, который по сути представляет собой только две строки кода Python.
from caffe2.python import net_drawer
from IPython import display
graph = net_drawer.GetPydotGraph(net, rankdir="LR")
display.Image(graph.create_png(), width=800)
Когда вы запустите код, вы увидите следующий вывод -
Для больших сетей графическое представление становится чрезвычайно полезным при визуализации и отладке ошибок определения сети.
Наконец, пришло время запустить сеть.
Запуск сети
Вы запускаете сеть, вызывая RunNetOnce метод на workspace объект -
workspace.RunNetOnce(net)
После однократного запуска сети все наши данные, которые генерируются случайным образом, будут созданы, введены в сеть и будут созданы выходные данные. Тензоры, которые создаются после запуска сети, называютсяblobsв Caffe2. Рабочее пространство состоит изblobsвы создаете и храните в памяти. Это очень похоже на Matlab.
После запуска сети вы можете проверить blobs что рабочая область содержит, используя следующие print команда
print("Blobs in the workspace: {}".format(workspace.Blobs()))
Вы увидите следующий вывод -
Blobs in the workspace: ['W', 'X', 'Y', 'b']
Обратите внимание, что рабочая область состоит из трех входных BLOB-объектов - X, W и b. Он также содержит выходной BLOB-объект с именемY. Давайте теперь исследуем содержимое этих блобов.
for name in workspace.Blobs():
print("{}:\n{}".format(name, workspace.FetchBlob(name)))
Вы увидите следующий вывод -
W:
[[ 1.0426593 0.15479846 0.25635982]
[-2.2461145 1.4581774 0.16827184]
[-0.12009818 0.30771437 0.00791338]
[ 1.2274994 -0.903331 -0.68799865]
[ 0.30834186 -0.53060573 0.88776857]]
X:
[[ 1.6588869e+00 1.5279824e+00 1.1889904e+00]
[ 6.7048723e-01 -9.7490678e-04 2.5114202e-01]]
Y:
[[ 3.2709925 -0.297907 1.2803618 0.837985 1.7562964]
[ 1.7633215 -0.4651525 0.9211631 1.6511179 1.4302125]]
b:
[1. 1. 1. 1. 1.]
Обратите внимание, что данные на вашем компьютере или, фактически, при каждом запуске сети будут разными, поскольку все входные данные создаются случайным образом. Вы успешно определили сеть и запустили ее на своем компьютере.