Caffe2 手冊(Intro Tutorial)[2]

Caffe2的相關概念

接下來你可以學到更多Caffe2中主要的概念,這些概念對理解和開發Caffe2相當重要。

Blobs and Workspace,Tensors

Caffe2中,數據是用blobs儲存的。Blob只是內存中的一個數據塊。大多數Blobs包含一個張量(tensor),可以理解為多維矩陣,在Python中,他們被轉換為numpy 矩陣。
? Workspace 保存著所有的Blobs。下面的例子展示了如何向Workspace中傳遞Blobs和取出他們。Workspace在你開始使用他們時,才進行初始化。

# 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中最基本的對象是netnet可以說是一系列Operators的集合,每個Operator根據輸入的blob輸出一個或者多個blob
? 下面我們將會創建一個超級簡單的模型。他擁有如下部件:

  • 一個全連接層
  • 一個Sigmoid激活函數和一個Softmax函數
  • 一個交叉損失
    ? 直接構建網絡是很厭煩的,所以最好使用Python接口的模型助手來構建網絡。我們只需簡單的調用CNNModelHelper,他就會幫我們創建兩個想聯系的網絡。
  • 一個用于初始化參數(ref.init_net
  • 一個用于實際訓練(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"])

上面的代碼中,我們首先在內存中創建了輸入數據和標簽,實際使用中,往往從database等載體中讀入數據。可以看到輸入數據和標簽的第一維度是16,這是因為輸入的最小batch最小是16。Caffe2中很多Operator都能直接通過CNNModelHelper來進行,并且能夠一次處理一個batchCNNModelHelper’s Operator List中有更詳細的解析。
? 第二,我們通過一些操作創建了一個模型。比如FCSigmoidSoftmaxWithLoss注意:這個時候,這些操作并沒有真正執行,他們僅僅是對模型進行了定義。
? 模型助手創建了兩個網絡:m.param_init_net,這個網絡將僅僅被執行一次。他將會初始化參數blob,例如全連接層的權重。真正的訓練是通過執行m.net來是現實的。這是自動發生的。
? 網絡的定義保存在一個protobuf結構體中。你可以很容易的通過調用net.proto來查看它。

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"

同時,你也可以查看參數初始化網絡:

print(str(m.param_init_net.Proto()))

這就是Caffe2的API:使用Python接口方便快速的構建網絡并訓練你的模型,Python接口將這些網絡通過序列化的protobuf傳遞給C++接口,然后C++接口全力的執行。

Executing

現在我們可以開始訓練我們的模型。
? 首先,我們先跑一次參數初始化網絡。

workspace.RunNetOnce(m.param_init_net)

這個操作將會把param_init_netprotobuf傳遞給C++代碼進行執行。
? 然后我們真正的創建網絡

workspace.CreateNet(m.net)

一旦創建好網絡,我們就可以高效的跑起來:

# 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 跑十次

這里要注意的是我們怎樣在RunNet()函數中使用網絡的名字。并且在這里,由于網絡已經在workspace中創建,所以我們不需要再傳遞網絡的定義。執行完后,你可以查看存在輸出blob中的結果。

print(workspace.FetchBlob("softmax"))
print(workspace.FetchBlob("loss"))

Backward pass

上面的網絡中,僅僅包含了網絡的前向傳播,因此它是學習不到任何東西的。后向傳播對每一個前向傳播進行gradient operator。如果你想自己嘗試這樣的操作,那么你可以進行以下操作并檢查結果。
? RunNetOnce(),插入下面操作:

m.AddGradientOperators([loss])

然后測試protobuf的輸出:

print(str(m.net.Proto()))

以上就是大體的使用教程
譯者注
訓練過程可以總結為以下步驟:

# 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

結語:
轉載請注明出處:http://www.lxweimin.com/c/cf07b31bb5f2

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容