1. caffe介绍
caffe是贾扬清大神开发的一套系统,caffe2是重构后的版本。其基本结构为:
- 使用blob存储数据
- 使用operator连接blob数据,定义了计算规则
- 使用net组合operator形成批次计算的层
- 使用workspace管理网络、计算符和数据
2. 基本操作
2.1 数据
import numpy as np
import time
from caffe2.python import core, workspace
from caffe2.proto import caffe2_pb2
X = np.random.randn(2, 3).astype(np.float32)
print("Generated X from numpy:\n{}".format(X))
workspace.FeedBlob("X", X)
print(workspace.Blobs())
print(workspace.FetchBlob('X'))
Blobs命令得到数据名列表
FetchBlob获得具体的数据
2.2 操作符
op = core.CreateOperator(
"Relu", # The type of operator that we want to run
["X"], # A list of input blobs by their names
["Y"], # A list of output blobs by their names
'active1'
)
workspace.RunOperatorOnce(op)
workspace.FetchBlobs('Y')
op2 = core.CreateOperator(
"GaussianFill",
[], # GaussianFill does not need any parameters.
["W"],
shape=[100, 100], # shape argument as a list of ints.
mean=1.0, # mean as a single float
std=1.0, # std as a single float
)
workspace.RunOperatorOnce(op2)
temp = workspace.FetchBlob("Z")
使用workspace来控制运行。
2.3 网络
net = core.Net("linear_net")
X = net.GaussianFill([], ["X"], mean=0.0, std=1.0, shape=[2, 3], run_once=0)
W = net.GaussianFill([], ["W"], mean=0.0, std=1.0, shape=[5, 3], run_once=0)
b = net.ConstantFill([], ["b"], shape=[5,], value=1.0, run_once=0)
Y = net.FC([X,W,b],['Y'])
print(net.Proto())
workspace.RunNetOnce(net)
for name in workspace.Blobs():
print("{}:\n{}".format(name, workspace.FetchBlob(name)))
在python中有两种方法来运行一个net:
方法1:使用workspace.RunNetOnce,初始化网络,运行网络,然后销毁网络。
方法2:先使用workspace.CreateNet初始化网络,然后使用workspace.RunNet来运行网络。
可以用下面的代码来画图:
from caffe2.python import net_drawer
from IPython import display
graph = net_drawer.GetPydotGraph(net, rankdir="LR")
display.Image(graph.create_png(), width=400)
2.4 运行推理
with open(INIT_NET) as f:
init_net = f.read()
with open(PREDICT_NET) as f:
predict_net = f.read()
p = workspace.Predictor(init_net, predict_net)
results = p.run([img])
2.5 brew包
caffe2为了更方便调用和管理,可以通过导入brew这个包来调用帮助函数。像fc层的实现就可以使用:
from caffe2.python import brew
brew.fc(model, blob_in, blob_out, ...)
我们使用brew构造网络就十分简单,下面的代码就构造了一个LeNet模型:
from caffe2.python import brew
def AddLeNetModel(model, data):
conv1 = brew.conv(model, data, 'conv1', 1, 20, 5)
pool1 = brew.max_pool(model, conv1, 'pool1', kernel=2, stride=2)
conv2 = brew.conv(model, pool1, 'conv2', 20, 50, 5)
pool2 = brew.max_pool(model, conv2, 'pool2', kernel=2, stride=2)
fc3 = brew.fc(model, pool2, 'fc3', 50 * 4 * 4, 500)
fc3 = brew.relu(model, fc3, fc3)
pred = brew.fc(model, fc3, 'pred', 500, 10)
softmax = brew.softmax(model, pred, 'softmax')
caffe2 使用brew提供很多构造网络的帮助函数,大大简化了我们构建网络的过程。但实际上,这些只是封装的结果,网络构造的原理和之前说的使用operators构建的原理是一样的。