Caffe2 - Tworzenie własnej sieci
W tej lekcji nauczysz się definiować plik single layer neural network (NN)w Caffe2 i uruchom go na losowo wygenerowanym zbiorze danych. Napiszemy kod przedstawiający graficznie architekturę sieci, dane wejściowe i wyjściowe drukowania, wagi i wartości odchylenia. Aby zrozumieć tę lekcję, musisz się z nią zapoznaćneural network architectures, jego terms i mathematics używane w nich.
Architektura sieci
Rozważmy, że chcemy zbudować pojedynczą warstwę NN, jak pokazano na poniższym rysunku -
Matematycznie ta sieć jest reprezentowana przez następujący kod Pythona -
Y = X * W^T + b
Gdzie X, W, b są tensorami i Yjest wyjściem. Wypełnimy wszystkie trzy tensory pewnymi przypadkowymi danymi, uruchomimy sieć i zbadamy plikYwynik. Aby zdefiniować sieć i tensory, Caffe2 udostępnia kilkaOperator Funkcje.
Operatory Caffe2
W Caffe2 Operatorjest podstawową jednostką obliczeniową. The Caffe2Operator przedstawia się następująco.
Caffe2 zawiera wyczerpującą listę operatorów. Dla sieci, którą aktualnie projektujemy, użyjemy operatora o nazwie FC, który oblicza wynik przekazania wektora wejściowegoX w w pełni połączoną sieć z dwuwymiarową macierzą wag W i jednowymiarowy wektor odchylenia b. Innymi słowy, oblicza następujące równanie matematyczne
Y = X * W^T + b
Gdzie X ma wymiary (M x k), W ma wymiary (n x k) i b jest (1 x n). WyjścieY będzie mieć wymiar (M x n), gdzie M to wielkość partii.
Dla wektorów X i W, użyjemy GaussianFilloperator do tworzenia losowych danych. Do generowania wartości odchyleniab, użyjemy ConstantFill operator.
Przejdziemy teraz do zdefiniowania naszej sieci.
Tworzenie sieci
Przede wszystkim zaimportuj wymagane pakiety -
from caffe2.python import core, workspace
Następnie określ sieć, dzwoniąc core.Net w następujący sposób -
net = core.Net("SingleLayerFC")
Nazwa sieci jest określona jako SingleLayerFC. W tym momencie tworzony jest obiekt sieciowy o nazwie net. Na razie nie zawiera żadnych warstw.
Tworzenie tensorów
Utworzymy teraz trzy wektory wymagane przez naszą sieć. Najpierw utworzymy tensor X przez wywołanieGaussianFill operator w następujący sposób -
X = net.GaussianFill([], ["X"], mean=0.0, std=1.0, shape=[2, 3], run_once=0)
Plik X wektor ma wymiary 2 x 3 ze średnią wartością danych 0,0 i odchyleniem standardowym wynoszącym 1.0.
Podobnie my tworzymy W tensor w następujący sposób -
W = net.GaussianFill([], ["W"], mean=0.0, std=1.0, shape=[5, 3], run_once=0)
Plik W wektor ma rozmiar 5 x 3.
Wreszcie tworzymy stronniczość b matryca o rozmiarze 5.
b = net.ConstantFill([], ["b"], shape=[5,], value=1.0, run_once=0)
Teraz najważniejsza część kodu, czyli definiowanie samej sieci.
Definiowanie sieci
Definiujemy sieć w poniższej instrukcji Pythona -
Y = X.FC([W, b], ["Y"])
Nazywamy FC operator danych wejściowych X. Wagi są określone wWi stronniczość w b. Wynik jestY. Alternatywnie możesz utworzyć sieć za pomocą poniższej instrukcji Pythona, która jest bardziej szczegółowa.
Y = net.FC([X, W, b], ["Y"])
W tym momencie sieć jest po prostu tworzona. Dopóki przynajmniej raz nie uruchomimy sieci, nie będzie ona zawierała żadnych danych. Przed uruchomieniem sieci zbadamy jej architekturę.
Drukowanie architektury sieci
Caffe2 definiuje architekturę sieci w pliku JSON, który można sprawdzić, wywołując metodę Proto na utworzonym net obiekt.
print (net.Proto())
Daje to następujący wynik -
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"
}
Jak widać na powyższej liście, najpierw definiuje operatory X, W i b. Przeanalizujmy definicjęWjako przykład. TypW jest określony jako GausianFill. Plikmean jest zdefiniowany jako float 0.0, odchylenie standardowe określa się jako zmiennoprzecinkowe 1.0i shape jest 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
}
...
}
Sprawdź definicje X i bdla własnego zrozumienia. Na koniec przyjrzyjmy się definicji naszej sieci jednowarstwowej, która została tutaj odtworzona
op {
input: "X"
input: "W"
input: "b"
output: "Y"
name: ""
type: "FC"
}
Tutaj typ sieci to FC (W pełni połączony) z X, W, b jako wejścia i Yjest wyjściem. Ta definicja sieci jest zbyt szczegółowa i w przypadku dużych sieci badanie jej zawartości będzie nudne. Na szczęście Caffe2 zapewnia graficzną reprezentację utworzonych sieci.
Graficzna reprezentacja sieci
Aby uzyskać graficzną reprezentację sieci, uruchom następujący fragment kodu, który jest zasadniczo tylko dwoma wierszami kodu Pythona.
from caffe2.python import net_drawer
from IPython import display
graph = net_drawer.GetPydotGraph(net, rankdir="LR")
display.Image(graph.create_png(), width=800)
Po uruchomieniu kodu zobaczysz następujące dane wyjściowe -
W przypadku dużych sieci reprezentacja graficzna staje się niezwykle przydatna w wizualizacji i debugowaniu błędów definicji sieci.
Wreszcie nadszedł czas, aby uruchomić sieć.
Uruchomiona sieć
Uruchamiasz sieć, dzwoniąc pod numer RunNetOnce metoda na workspace obiekt -
workspace.RunNetOnce(net)
Po jednorazowym uruchomieniu sieci wszystkie nasze dane, które są generowane losowo, zostaną utworzone, wprowadzone do sieci i utworzone zostaną dane wyjściowe. Nazywa się tensory, które powstają po uruchomieniu sieciblobsw Caffe2. Obszar roboczy składa się zblobstworzysz i przechowujesz w pamięci. Jest to dość podobne do Matlab.
Po uruchomieniu sieci możesz sprawdzić plik blobs że obszar roboczy zawiera następujące elementy print Komenda
print("Blobs in the workspace: {}".format(workspace.Blobs()))
Zobaczysz następujący wynik -
Blobs in the workspace: ['W', 'X', 'Y', 'b']
Zwróć uwagę, że obszar roboczy składa się z trzech wejściowych obiektów blob - X, W i b. Zawiera również wyjściowy obiekt BLOB o nazwieY. Przeanalizujmy teraz zawartość tych plamek.
for name in workspace.Blobs():
print("{}:\n{}".format(name, workspace.FetchBlob(name)))
Zobaczysz następujący wynik -
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.]
Zwróć uwagę, że dane na twoim komputerze lub w rzeczywistości przy każdym uruchomieniu sieci byłyby inne, ponieważ wszystkie wejścia są tworzone losowo. Teraz pomyślnie zdefiniowałeś sieć i uruchomiłeś ją na swoim komputerze.