Caffe2的相關(guān)概念
接下來(lái)你可以學(xué)到更多Caffe2中主要的概念,這些概念對(duì)理解和開發(fā)Caffe2相當(dāng)重要。
Blobs and Workspace,Tensors
Caffe2中,數(shù)據(jù)是用blobs儲(chǔ)存的。Blob只是內(nèi)存中的一個(gè)數(shù)據(jù)塊。大多數(shù)Blobs包含一個(gè)張量(tensor),可以理解為多維矩陣,在Python中,他們被轉(zhuǎn)換為numpy 矩陣。
? Workspace 保存著所有的Blobs。下面的例子展示了如何向Workspace中傳遞Blobs和取出他們。Workspace在你開始使用他們時(shí),才進(jìn)行初始化。
# Create random tensor of three dimensions
x = np.random.rand(4, 3, 2)
print(x)
print(x.shape)
workspace.FeedBlob("my_x", x)
x2 = workspace.FetchBlob("my_x")
print(x2)
Nets and Operators
Caffe2中最基本的對(duì)象是net,net可以說(shuō)是一系列Operators的集合,每個(gè)Operator根據(jù)輸入的blob輸出一個(gè)或者多個(gè)blob。
? 下面我們將會(huì)創(chuàng)建一個(gè)超級(jí)簡(jiǎn)單的模型。他擁有如下部件:
- 一個(gè)全連接層
- 一個(gè)
Sigmoid激活函數(shù)和一個(gè)Softmax函數(shù) - 一個(gè)交叉損失
? 直接構(gòu)建網(wǎng)絡(luò)是很厭煩的,所以最好使用Python接口的模型助手來(lái)構(gòu)建網(wǎng)絡(luò)。我們只需簡(jiǎn)單的調(diào)用CNNModelHelper,他就會(huì)幫我們創(chuàng)建兩個(gè)想聯(lián)系的網(wǎng)絡(luò)。 - 一個(gè)用于初始化參數(shù)(
ref.init_net) - 一個(gè)用于實(shí)際訓(xùn)練(
ref.init_net)
# Create the input data
data = np.random.rand(16, 100).astype(np.float32)
# Create labels for the data as integers [0, 9].
label = (np.random.rand(16) * 10).astype(np.int32)
workspace.FeedBlob("data", data)
workspace.FeedBlob("label", label)
# Create model using a model helper
m = cnn.CNNModelHelper(name="my first net")
fc_1 = m.FC("data", "fc1", dim_in=100, dim_out=10)
pred = m.Sigmoid(fc_1, "pred")
[softmax, loss] = m.SoftmaxWithLoss([pred, "label"], ["softmax", "loss"])
上面的代碼中,我們首先在內(nèi)存中創(chuàng)建了輸入數(shù)據(jù)和標(biāo)簽,實(shí)際使用中,往往從database等載體中讀入數(shù)據(jù)。可以看到輸入數(shù)據(jù)和標(biāo)簽的第一維度是16,這是因?yàn)檩斎氲淖钚?code>batch最小是16。Caffe2中很多Operator都能直接通過(guò)CNNModelHelper來(lái)進(jìn)行,并且能夠一次處理一個(gè)batch。CNNModelHelper’s Operator List中有更詳細(xì)的解析。
? 第二,我們通過(guò)一些操作創(chuàng)建了一個(gè)模型。比如FC,Sigmoid,SoftmaxWithLoss。注意:這個(gè)時(shí)候,這些操作并沒有真正執(zhí)行,他們僅僅是對(duì)模型進(jìn)行了定義。
? 模型助手創(chuàng)建了兩個(gè)網(wǎng)絡(luò):m.param_init_net,這個(gè)網(wǎng)絡(luò)將僅僅被執(zhí)行一次。他將會(huì)初始化參數(shù)blob,例如全連接層的權(quán)重。真正的訓(xùn)練是通過(guò)執(zhí)行m.net來(lái)是現(xiàn)實(shí)的。這是自動(dòng)發(fā)生的。
? 網(wǎng)絡(luò)的定義保存在一個(gè)protobuf結(jié)構(gòu)體中。你可以很容易的通過(guò)調(diào)用net.proto來(lái)查看它。
print(str(m.net.Proto()))
輸出如下:
name: "my first net"
op {
input: "data"
input: "fc1_w"
input: "fc1_b"
output: "fc1"
name: ""
type: "FC"
}
op {
input: "fc1"
output: "pred"
name: ""
type: "Sigmoid"
}
op {
input: "pred"
input: "label"
output: "softmax"
output: "loss"
name: ""
type: "SoftmaxWithLoss"
}
external_input: "data"
external_input: "fc1_w"
external_input: "fc1_b"
external_input: "label"
同時(shí),你也可以查看參數(shù)初始化網(wǎng)絡(luò):
print(str(m.param_init_net.Proto()))
這就是Caffe2的API:使用Python接口方便快速的構(gòu)建網(wǎng)絡(luò)并訓(xùn)練你的模型,Python接口將這些網(wǎng)絡(luò)通過(guò)序列化的protobuf傳遞給C++接口,然后C++接口全力的執(zhí)行。
Executing
現(xiàn)在我們可以開始訓(xùn)練我們的模型。
? 首先,我們先跑一次參數(shù)初始化網(wǎng)絡(luò)。
workspace.RunNetOnce(m.param_init_net)
這個(gè)操作將會(huì)把param_init_net的protobuf傳遞給C++代碼進(jìn)行執(zhí)行。
? 然后我們真正的創(chuàng)建網(wǎng)絡(luò):
workspace.CreateNet(m.net)
一旦創(chuàng)建好網(wǎng)絡(luò),我們就可以高效的跑起來(lái):
# Run 100 x 10 iterations 跑100*10次迭代
for j in range(0, 100):
data = np.random.rand(16, 100).astype(np.float32)
label = (np.random.rand(16) * 10).astype(np.int32)
workspace.FeedBlob("data", data)
workspace.FeedBlob("label", label)
workspace.RunNet(m.name, 10) # run for 10 times 跑十次
這里要注意的是我們?cè)鯓釉?code>RunNet()函數(shù)中使用網(wǎng)絡(luò)的名字。并且在這里,由于網(wǎng)絡(luò)已經(jīng)在workspace中創(chuàng)建,所以我們不需要再傳遞網(wǎng)絡(luò)的定義。執(zhí)行完后,你可以查看存在輸出blob中的結(jié)果。
print(workspace.FetchBlob("softmax"))
print(workspace.FetchBlob("loss"))
Backward pass
上面的網(wǎng)絡(luò)中,僅僅包含了網(wǎng)絡(luò)的前向傳播,因此它是學(xué)習(xí)不到任何東西的。后向傳播對(duì)每一個(gè)前向傳播進(jìn)行gradient operator。如果你想自己嘗試這樣的操作,那么你可以進(jìn)行以下操作并檢查結(jié)果。
? 在RunNetOnce()前,插入下面操作:
m.AddGradientOperators([loss])
然后測(cè)試protobuf的輸出:
print(str(m.net.Proto()))
以上就是大體的使用教程
譯者注:
訓(xùn)練過(guò)程可以總結(jié)為以下步驟:
# Create model using a model helper
m = cnn.CNNModelHelper(name="my first net")
fc_1 = m.FC("data", "fc1", dim_in=100, dim_out=10)
pred = m.Sigmoid(fc_1, "pred")
[softmax, loss] = m.SoftmaxWithLoss([pred, "label"], ["softmax", "loss"])
m.AddGradientOperators([loss]) #注意這一行代碼
workspace.RunNetOnce(m.param_init_net)
workspace.CreateNet(m.net)
# Run 100 x 10 iterations
for j in range(0, 100):
data = np.random.rand(16, 100).astype(np.float32)
label = (np.random.rand(16) * 10).astype(np.int32)
workspace.FeedBlob("data", data)
workspace.FeedBlob("label", label)
workspace.RunNet(m.name, 10) # run for 10 times
結(jié)語(yǔ):
轉(zhuǎn)載請(qǐng)注明出處:http://www.itdecent.cn/c/cf07b31bb5f2