在本課程中,您將學習在Caffe2中定義一個單層神經網絡(NN),並在隨機生成的數據集上運行它。我們將編寫代碼以圖形方式描述網絡架構、列印輸入、輸出、權重和偏差值。要理解這一課,您必須熟悉其中使用的神經網絡體系結構、其術語和數學。
Network Architecture
讓我們考慮構建一個單層NN,如下圖所示;
從數學上講,這個網絡由以下Python代碼表示−
Y = X * W^T + b
其中X,W,b是張量,Y是輸出。我們將用一些隨機數據填充所有三個張量,運行網絡並檢查Y輸出。爲了定義網絡和張量,Caffe2提供了幾個運算符函數。
Caffe2 Operators
在Caffe2中,運算符是基本的計算單位。Caffe2運算符表示如下。
Caffe2提供了一個詳盡的運算符列表。對於我們目前正在設計的網絡,我們將使用名爲FC的運算符,它計算將輸入向量X傳遞到具有二維權重矩陣W和一維偏移向量b的完全連接網絡的結果。換言之,它計算下列數學方程
Y = X * W^T + b
其中X具有尺寸(M X k),W具有尺寸(nxk),並且b是(1x n)。輸出Y將具有尺寸(M x n),其中M是批次大小。
對於向量X和W,我們將使用GaussianFill運算符創建一些隨機數據。爲了生成偏差值b,我們將使用ConstantFill運算符。
我們現在開始定義我們的網絡。
Creating Network
首先,導入所需的包&負;
from caffe2.python import core, workspace
接下來,通過調用core.Net來定義網絡,如下所示−
net = core.Net("SingleLayerFC")
網絡的名稱指定爲SingleLayerFC。此時,將創建名爲net的網絡對象。到目前爲止,它還沒有包含任何層。
Creating Tensors
我們現在將創建網絡所需的三個向量。首先,我們將通過調用GaussianFill操作符來創建X張量,如下所示−
X = net.GaussianFill([], ["X"], mean=0.0, std=1.0, shape=[2, 3], run_once=0)
X向量的維數爲2x 3,平均數據值爲0,0,標準偏差爲1.0。
同樣,我們創建W張量,如下所示−
W = net.GaussianFill([], ["W"], mean=0.0, std=1.0, shape=[5, 3], run_once=0)
W向量的大小爲5x 3。
最後,我們創建大小爲5的biasb矩陣。
b = net.ConstantFill([], ["b"], shape=[5,], value=1.0, run_once=0)
現在,代碼中最重要的部分就是定義網絡本身。
Defining Network
我們在下面的Python語句中定義網絡−
Y = X.FC([W, b], ["Y"])
我們對輸入數據調用FC運算符X。權重在W中指定,偏差在b中指定。輸出爲Y。或者,您可以使用下面的Python語句創建網絡,該語句更加詳細。
Y = net.FC([X, W, b], ["Y"])
在這一點上,網絡是簡單創建的。在我們至少運行一次網絡之前,它不會包含任何數據。在運行網絡之前,我們將檢查它的體系結構。
Printing Network Architecture
Caffe2在JSON文件中定義了網絡體系結構,可以通過對創建的net對象調用Proto方法來檢查該文件。
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。平均值定義爲float0.0,標準偏差定義爲float1.0,形狀爲5x 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爲創建的網絡提供了圖形表示。
Network Graphical Representation
要獲得網絡的圖形表示,請運行以下代碼片段,這實際上只是兩行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)
當您運行代碼時,您將看到以下輸出;
對於大型網絡,圖形表示在可視化和調試網絡定義錯誤時非常有用。
最後,現在是運行網絡的時候了。
Running Network
通過調用工作區中的RunNetOnce方法來運行網絡;
workspace.RunNetOnce(net)
在網絡運行一次之後,我們所有隨機生成的數據都將被創建,輸入網絡並生成輸出。在Caffe2中,運行網絡後產生的張量稱爲blobs。工作區由您創建並存儲在內存中的blob組成。這與Matlab非常相似。
運行網絡後,可以使用以下print命令檢查工作區中包含的blob
print("Blobs in the workspace: {}".format(workspace.Blobs()))
您將看到以下輸出&負;
Blobs in the workspace: ['W', 'X', 'Y', 'b']
注意,工作區由三個輸入blob−X、W和b組成。它還包含名爲Y的輸出blob。現在讓我們檢查一下這些斑點的內容。
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.]
請注意,由於所有輸入都是隨機創建的,因此計算機上的數據或實際上網絡每次運行的數據都會有所不同。您現在已經成功地定義了一個網絡並在您的計算機上運行它。