CAFFE2官方信息整理_入門教學

caffe2 概念

您可以在下面瞭解有關Caffe2的主要概念的更多信息,這些概念對於理解和開發Caffe2模型至關重要。

Blobs和Workspace,Tensors

數據在caffe2中組成成爲blobs, blobs是內存中的一個命名的塊. 大部分的blobs包含一個tensor(可以想成多維向量),在python中轉換成爲numpy數組.
Workspace保存所有的blobs. 下面的例子顯示如何填入blobs到workspace並再次取出它.Workspaces會在你使用它時進行初始化

from caffe2.python import workspace, model_helper
import numpy as np
# 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 和 Operators

Caffe2中的基本模型抽象是一個網絡(network的縮寫)。 網絡是運算符的圖,每個運算符采用一組輸入Blob併產生一個或多個輸出Blob。
在下面的代碼塊中,我們將創建一個超級簡單的模型。 它將具有以下組件:

  • 一個全鏈接層(FC)
  • 一個Sigmoid激活函數包含Softmax
  • 一個交叉熵損失函數

直接構成一個nets非常繁瑣,因此最好使用模型幫助程序(python類用於創建nets). 即使我們叫他"my first net",ModelHelper將會創建兩個關聯的網絡:

  1. 一個初始化參數(參考init_net)
  2. 一個運行實際訓練(參考 exec_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)

創建隨機的data和label,提供給workspace的blobs

# Create model using a model helper
m = model_helper.ModelHelper(name="my first net")

我們使用model_helper來創建剛纔提到的兩個網絡(init_net和exec_net).我們計劃使用FC operator添加一個全連接層,但首先我們需要做準備工作,創建隨機填充blobs以提供給FC需要的weight和bias.添加FC操作時我們通過名稱引用weight和bias.

weight = m.param_init_net.XavierFill([], 'fc_w', shape=[10, 100])
bias = m.param_init_net.ConstantFill([], 'fc_b', shape=[10, ])

在Caffe2中FC操作接受輸入blob(我們的數據)weights和bias.weights和bias使用XavierFill和ConstantFill(將一個空的數組,名稱,和shape填充)

fc_1 = m.net.FC(["data", "fc_w", "fc_b"], "fc1")
pred = m.net.Sigmoid(fc_1, "pred")
softmax, loss = m.net.SoftmaxWithLoss([pred, "label"], ["softmax", "loss"])

查看上面的代碼:
首先,我們在內存中創建了輸入數據和標籤Blob(實際上,您將從諸如數據庫之類的輸入數據源加載數據)。 請注意,數據和標籤Blob的第一維爲“ 16”; 這是因爲模型的輸入是一次最少16個樣本的小批量。 可以通過ModelHelper直接訪問許多Caffe2運算符,並且可以一次處理一小部分輸入。
其次,我們通過定義一堆運算符來創建模型:FC,Sigmoid和SoftmaxWithLoss。 注意:此時,運算符尚未執行,您只是在創建模型的定義(也就是定義模型結構)。
Model helper將會創建兩個網絡:m.param_init_net此net只運行一次.它將所有的參數blobs如FC層的weights進行初始化.實際訓練使用的是m.net.這些自動發生對使用者來說透明的.

這個網絡定義存儲在protobuf結構中,可視使用net.Proto()檢查他:

print(m.net.Proto())

您可以看到如何有兩個運算符爲FC運算符的權重和偏差斑點創建隨機填充。

這是Caffe2 API的主要思想:使用Python方便地組成網絡來訓練模型,將這些網絡作爲序列化的原型緩衝區傳遞給C ++代碼,然後讓C ++代碼以最佳性能運行網絡。

執行

現在,當我們定義了模型訓練操作員後,就可以開始運行它來訓練模型。
首先,我們只運行一次參數初始化:

workspace.RunNetOnce(m.param_init_net)

創建實際訓練網絡

workspace.CreateNet(m.net)

我們創建其一次然後有效的多次運行它:

# Run 100 x 10 iterations
for _ in range(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

注意我們如何只將m.name而不是net定義本身傳遞給RunNet()。 由於網絡是在工作空間內創建的,因此我們無需再次傳遞定義。
執行後我們抗獲取存儲在輸出blobs的結果

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

反向傳播

This net only contains the forward pass, thus it is not learning anything. The backward pass is created by adding the gradient operators for each operator in the forward pass.

If you want to try this, add the following steps and examine the results!
Insert before you call RunNetOnce():

m.AddGradientOperators([loss])

Examine the protobuf output:

print(m.net.Proto())
name: "my first net"
op {
  input: "data"
  input: "fc_w"
  input: "fc_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"
}
#從這一行之後就是方向梯度傳播了
op {
  input: "loss"
  output: "loss_autogen_grad"
  name: ""
  type: "ConstantFill"
  arg {
    name: "value"
    f: 1.0
  }
}
op {
  input: "pred"
  input: "label"
  input: "softmax"
  input: "loss_autogen_grad"
  output: "pred_grad"
  name: ""
  type: "SoftmaxWithLossGradient"
  is_gradient_op: true
}
op {
  input: "pred"
  input: "pred_grad"
  output: "fc1_grad"
  name: ""
  type: "SigmoidGradient"
  is_gradient_op: true
}
op {
  input: "data"
  input: "fc_w"
  input: "fc1_grad"
  output: "fc_w_grad"
  output: "fc_b_grad"
  output: "data_grad"
  name: ""
  type: "FCGradient"
  is_gradient_op: true
}
external_input: "data"
external_input: "fc_w"
external_input: "fc_b"
external_input: "label"

圖片

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章