caffe中是如何运用protobuf构建神经网络的?

 caffe这个框架设计的比较小巧精妙,它采用了protobuf来作为交互的媒介,避免了繁重的去设计各个语言的接口,开发者可以使用任意语言通过这个protobuf这个媒介,来运行这个框架.

  我们这里不过多的去阐述caffe的过往以及未来,只是简单的描述一下,caffe框架中的protobuf的作用,以及它的背后原理. 一般来说cafe.proto中有对应的solve,solve中悠悠Layer,通过prototxt解析生成一个大对象sovle,然后solve底下有一个Layer数组对象,我们所定义的网络就是Layer数组,通过解析Layer数组,反射到对应layer对应的,遍历Layer数组的过程也就是勾结神经网络的过程,遍历完成之后,也就构成了一张神经网络图,然后就是执行这个图,也就是依据这个对象数组一步步的,喂数据,forward操作,和backward操作,计算loss,等. 我们可以这样类比,我们可以模仿这个原理简单的设计一个框架,这里先不考虑C++的反射机制问题,这里只讨论如何将prototxt文件解析出来,至于如何反射到实际的类上,下次有时间可以在记录一个备忘录.

  比如,我们设计一个这样的demo.proto 来定义我们的对象属性:

 1 package caffe;
 2 
 3 message Student
 4    {
 5       required int32 age = 1; //ID required 表示必要字段
 6       required string name = 2; //str 必要字段
 7       optional int32 grade = 3 ; //optional field 可选字段,可以有无,最多b
 8    }
 9 
10 message WorkDay{
11     required bool isworker =1;
12     required bool isjiaban =2; //是否算加班
13 }
14 
15 message Teacher{
16     required string name = 1 ;
17     required WorkDay work = 2;  //是否工作
18     optional int32  age = 3;
19 
20 }
21 
22 //班级
23 message Class{
24        required string name = 1;   //班级名称
25        repeated Student stu = 2;    //班级成员 数组
26        repeated Teacher teacher=3;
27    }

 然后我们来设计一些对象:比如我们设计一个班级中有一名老师,和若干个学生. param.prototxt

 1 name: "三年级23班"
 2 
 3 teacher {
 4   name: "tom"
 5   age: 17
 6   work {
 7     isworker: 1 ;#中文
 8     isjiaban: 1;
 9    }
10 }
11 
12 stu {
13     age: 19;
14     name: "demo"; ##中文
15     grade: 134;
16 }
17 
18 stu {
19     age: 19;
20     name: "google"; ##中文
21     grade: 134;
22 }
23 
24 stu {
25     age: 19;
26     name: "snake"; ##中文
27     grade: 134;
28 }

然后我们来依次解析出这个param.prototxt文件中的信息:

 1 //
 2 // Created by xijun1 on 2017/12/22.
 3 //
 4 #include <google/protobuf/io/coded_stream.h>
 5 #include <google/protobuf/io/zero_copy_stream_impl.h>
 6 #include <google/protobuf/text_format.h>
 7 
 8 //反射机制
 9 #include <google/protobuf/compiler/importer.h>
10 #include <google/protobuf/dynamic_message.h>
11 
12 #include "proto/demo.pb.h"
13 #include<iostream>
14 #include <fstream>
15 #include<ios>
16 #include <cstdlib>
17 #include <cstring>
18 #include <cstdio>
19 
20 #include <fcntl.h>   // open
21 using namespace std;
22 
23 void InfoStudents(const caffe::Student & stu){
24     cout<< "student info:"<<endl;
25     cout<<"     name: "<<stu.name()<<endl;
26     cout<<"     age: "<<stu.age()<<endl;
27     cout<<"     grade: "<<stu.grade()<<endl;
28 }
29 
30 void InfoTeacher(const caffe::Teacher & teacher) {
31     cout << "teacher info:" << endl;
32     cout << "       name: " << teacher.name() << endl;
33     cout << "       age: " << teacher.age() << endl;
34     cout<< "            is worker: "<<teacher.work().isworker()<<endl;
35     cout<< "            is jiaban: "<<teacher.work().isjiaban()<<endl;
36 }
37 
38 
39 int main(void)
40 {
41     caffe::Class cls;
42     int file_desc = open("./param.prototxt",O_NDELAY);
43 
44     google::protobuf::io::FileInputStream fileInputStream(file_desc);
45     if(!google::protobuf::TextFormat::Parse(&fileInputStream,&cls)){
46         std::cout<<"parse failure."<<std::endl;
47         return -1;
48     }
49     std::cout<<cls.name()<<std::endl;
50 
51 
52     //按照索引进行读取
53     for(int i=1;i<cls.GetMetadata().descriptor->field_count(); ++i){
54         std::cout<<cls.descriptor()->field(i)->name()<<std::endl;
55         //cout<<cls.descriptor()->field(i)->full_name()<<endl;
56         if(cls.descriptor()->field(i)->name()=="stu"){
57             for (auto &stu_info : cls.stu()){
58 
59                  InfoStudents(stu_info);
60             }
61         }
62 
63         if(cls.descriptor()->field(i)->name()=="teacher"){
64             for (auto &teacher_info : cls.teacher()){
65 
66                 InfoTeacher(teacher_info);
67             }
68         }
69     }
70 
71     return 0;
72 }

我们试着运行一下,会看到这个结果:

这样之后是不是对caffe有了很直观的认识了呢.....

详细的代码,我放到github上了,附上地址:

https://github.com/gongxijun/protoc

----完----

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java学习

java每日一练(2017/8/15)

最新通知 ●回复"每日一练"获取以前的题目! ●【新】Android视频更新了!(回复【安卓视频】获取下载链接) ●【新】Ajax知识点视频更新了!(回复【学习...

2524
来自专栏青蛙要fly的专栏

Android技能树 — 数组,链表,散列表基础小结

现在安卓面试,对于数据结构的问题也越来越多了,要求也越来越多,所以我对于数据结构只能慢慢补起来了。(灬ꈍ ꈍ灬)

1134
来自专栏Crossin的编程教室

【Python 第57课】 正则表达式(3)

先来公布上一课习题的答案: \bs\S*?e\b 有的同学给出的答案是"\bs.*?e\b"。测试一下就会发现,有奇怪的'sea sue'和'sweet see...

2536
来自专栏python3

习题35:物以类聚

用到"class"的编程语言被称为"Object Oriented Programming(面向对象编程)"语言,这是一种传统的编程方式,你需要做出'东西'来,...

823
来自专栏胖胖的专栏

使用 trie 树实现简单的中文分词

导语:工作中偶尔遇到需要对中文进行分词的情况,不要求非常高的精确度和语境符合度,仅是为了统计某些词出现的热度。本文提供了一种简单易行的中文分词方法。 工作中,偶...

7565
来自专栏Golang语言社区

Go的语言特性总结

写在前面: 近来关于对Golang的讨论有很多,七牛的几个大牛们也断定Go语言在未来将会快速发展,并且很可能会取代Java成为互联网时代最受欢迎的编程语言。G...

4577
来自专栏韩伟的专栏

OO玩法:基于对象

“基于对象”的特点 什么是“基于”对象呢?就是关注“对象之间”的关系,而不是关注对象和类的关系。“面向对象编程”(OOP)的概念已经诞生了很多年,在业界可谓深入...

3224
来自专栏Crossin的编程教室

【Python 第51课】 and-or技巧

今天介绍一个python中的小技巧:and-or 看下面这段代码: a = "heaven" b = "hell" c = True and a or b p...

2769
来自专栏aCloudDeveloper

python学习总结

最近经学长介绍学习python,为研究生做研究做准备,python对于科学计算有着很高的效率,对于科研人员当然是有着很强的诱惑,虽然我还没真正用它,但从整个学习...

2185
来自专栏青玉伏案

代码重构(五):继承关系重构规则

陆陆续续的发表了多篇关于重构的文章了,还是那句话,重构是一个项目迭代开发中必不可少的一个阶段。其实重构伴随着你的项目的整个阶段。在前几篇关于重构的文章中我们谈到...

1996

扫码关注云+社区