Caffe2 简明教程
Caffe2 - Creating Your Own Network
在本教程中,你将学习在 Caffe2 中定义一个 single layer neural network (NN) 并针对随机生成的数据集运行它。我们将编写代码来以图形方式描述网络架构,打印输入、输出、权重和偏差值。要理解本教程,你必须熟悉 neural network architectures 及其 terms 和 mathematics 。
Network Architecture
让我们考虑想要构建如下所示的单层神经网络——
从数学上说,此网络由以下 Python 代码表示——
Y = X * W^T + b
其中 X, W, b 为张量, Y 为输出。我们将使用一些随机数据填充所有三个张量,运行网络并检查 Y 输出。为了定义网络和张量,Caffe2 提供了多个 Operator 函数。
Caffe2 Operators
在 Caffe2 中, Operator 是计算的基本单元。Caffe2 Operator 表示如下。
Caffe2 提供了一个详尽的操作符列表。对于我们当前正在设计的网络,我们将使用名为 FC 的运算符,它计算将输入向量 X 传递到具有二维权重矩阵 W 和单维偏差向量的全连接网络中的结果。换句话说,它计算以下数学方程
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 运算符。
我们现在将继续定义我们的网络。
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 矢量的维度 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)
现在,来到代码中最重要的一部分,即对网络本身进行定义。
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 。 mean 定义为浮点 0.0 ,标准偏差定义为浮点 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 为已创建的网络提供了图形化表示。
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
你可以通过对 workspace 对象调用 RunNetOnce 方法来运行网络 −
workspace.RunNetOnce(net)
在运行网络一次后,所有随机生成的我们数据都会被创建,并馈送到网络中,并且将创建输出。在运行网络后创建的张量在 Caffe2 中被称为 blobs 。工作区包含你创建并存储在内存中的 blobs 。这与 Matlab 非常相似。
在运行网络后,你可以使用以下 print 命令检查工作区包含的 blobs
print("Blobs in the workspace: {}".format(workspace.Blobs()))
您将看到以下输出 −
Blobs in the workspace: ['W', 'X', 'Y', 'b']
请注意,工作区包含三个输入 blob − X, W 和 b 。它还包含名为 Y 的输出 blob。现在让我们检查一下这些 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.]
请注意,由于所有输入都是随机创建的,因此机器上的数据,或者事实上每次运行网络时的生成数据都是不同的。你现在已经成功定义了一个网络,并在计算机上运行了它。