Caffe2-creating-your-own-network
Caffe2-独自のネットワークの作成
このレッスンでは、Caffe2で*シングルレイヤーニューラルネットワーク(NN)を定義し、ランダムに生成されたデータセットで実行する方法を学習します。 ネットワークアーキテクチャ、印刷入力、出力、重み、およびバイアス値をグラフィカルに描写するコードを作成します。 このレッスンを理解するには、*ニューラルネットワークアーキテクチャ、それらで使用される*用語*および*数学*に精通している必要があります。
ネットワークアーキテクチャ
次の図に示すように、単一層NNを構築したいと考えてみましょう-
数学的には、このネットワークは次のPythonコードで表されます-
Y = X * W^T + b
ここで、 X、W、b はテンソル、 Y は出力です。 3つのテンソルすべてにランダムデータを入力し、ネットワークを実行して Y 出力を調べます。 ネットワークとテンソルを定義するために、Caffe2はいくつかの*演算子*関数を提供します。
Caffe2オペレーター
Caffe2では、 Operator は計算の基本単位です。 Caffe2 *演算子*は次のように表されます。
Caffe2は、オペレーターの包括的なリストを提供します。 現在設計しているネットワークでは、FCと呼ばれる演算子を使用します。これは、入力ベクトル X を2次元の重み行列 W と1次元のバイアスで完全に接続されたネットワークに渡す結果を計算しますベクトル 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というネットワークオブジェクトが作成されます。 これまでのところ、レイヤーは含まれていません。
テンソルの作成
ここで、ネットワークに必要な3つのベクトルを作成します。 まず、次のように GaussianFill 演算子を呼び出してXテンソルを作成します-
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* です。
最後に、サイズ5のバイアス b 行列を作成します。
b = net.ConstantFill([], ["b"], shape=[5,], value=1.0, run_once=0)
さて、コードの最も重要な部分が来て、それはネットワーク自体を定義しています。
ネットワークの定義
私たちは次のPythonステートメントでネットワークを定義します-
Y = X.FC([W, b], ["Y"])
入力データ X で FC 演算子を呼び出します。 重みは W で指定され、バイアスはbで指定されます。 出力は Y です。 または、次のPythonステートメントを使用してネットワークを作成することもできますが、これはより冗長です。
Y = net.FC([X, W, b], ["Y"])
この時点で、ネットワークは単純に作成されます。 ネットワークを少なくとも1回実行するまで、データは含まれません。 ネットワークを実行する前に、そのアーキテクチャを調べます。
印刷ネットワークアーキテクチャ
Caffe2は、作成された net オブジェクトでProtoメソッドを呼び出すことで確認できるJSONファイルでネットワークアーキテクチャを定義します。
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 として指定されます。 平均*はフロート *0.0 として定義され、標準偏差はフロート 1.0 として定義され、形状*は *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コードの2行のみです。
from caffe2.python import net_drawer
from IPython import display
graph = net_drawer.GetPydotGraph(net, rankdir="LR")
display.Image(graph.create_png(), width=800)
あなたがコードを実行すると、次の出力が表示されます-
大規模なネットワークの場合、グラフィック表示はネットワーク定義エラーの視覚化とデバッグに非常に役立ちます。
最後に、ネットワークを実行します。
ランニングネットワーク
*workspace* オブジェクトで *RunNetOnce* メソッドを呼び出してネットワークを実行します-
workspace.RunNetOnce(net)
ネットワークが1回実行されると、ランダムに生成されるすべてのデータが作成され、ネットワークに供給されて出力が作成されます。 ネットワークの実行後に作成されるテンソルは、Caffe2では blobs と呼ばれます。 ワークスペースは、作成してメモリに保存する blobs で構成されます。 これはMatlabに非常に似ています。
ネットワークを実行した後、次の print コマンドを使用して、ワークスペースに含まれる blobs を調べることができます。
print("Blobs in the workspace: {}".format(workspace.Blobs()))
次の出力が表示されます-
Blobs in the workspace: ['W', 'X', 'Y', 'b']
ワークスペースは、 X、W 、 b の3つの入力BLOBで構成されていることに注意してください。 また、 Y という出力BLOBが含まれています。 これらのブロブの内容を調べてみましょう。
for name in workspace.Blobs():
print("{}:\n{}".format(name, workspace.FetchBlob(name)))
次の出力が表示されます-
W:
[[X:
[[e+00 1.5279824e+00 1.1889904e+00]
[ 6.7048723e-01 -9.7490678e-04 2.5114202e-01]]
Y:
[[b:
[1. 1. 1. 1. 1.]
すべての入力がランダムに作成されるため、マシン上のデータまたは実際にはネットワークの実行ごとのデータは異なることに注意してください。 これで、ネットワークが正常に定義され、コンピューターで実行されました。