Caffe2 手冊(cè)(Intro Tutorial)[2]

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ì)象是netnet可以說(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,SigmoidSoftmaxWithLoss。注意:這個(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_netprotobuf傳遞給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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容