美文网首页Caffe2程序员
Caffe2 手册(Intro Tutorial)[2]

Caffe2 手册(Intro Tutorial)[2]

作者: 少侠阿朱 | 来源:发表于2017-05-01 21:36 被阅读1408次

    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.jianshu.com/c/cf07b31bb5f2

    相关文章

      网友评论

        本文标题:Caffe2 手册(Intro Tutorial)[2]

        本文链接:https://www.haomeiwen.com/subject/ktlqtxtx.html