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

作者(passion) 阅读(912次) 评论(0) 分类( 软件)

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 来定义我们的对象属性:


   



name: "三年级23班"
  
  teacher {
    name: "tom"
    age: 17
    work {
      isworker: 1 ;#中文
      isjiaban: 1;
     }
 }
 
 stu {
     age: 19;
     name: "demo"; ##中文
     grade: 134;
 }
 
 stu {
     age: 19;
     name: "google"; ##中文
     grade: 134;
 }
 
 stu {
     age: 19;
     name: "snake"; ##中文
     grade: 134;
 };

 

 num:"127.0.0.1:1";

 num:"127.0.0.1:2";

 num:"127.0.0.1:3";

 num:"127.0.0.1:4";


 


 


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


 //
 // Created by xijun1 on 2017/12/22.
 //
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <google/protobuf/text_format.h>
 
 //反射机制
 #include <google/protobuf/compiler/importer.h>
 #include <google/protobuf/dynamic_message.h>
 
 #include "proto/demo.pb.h"
 #include<iostream>
 #include <fstream>
 #include<ios>
 #include <cstdlib>
 #include <cstring>
 #include <cstdio>
 
 #include <fcntl.h>   // open
 using namespace std;
 
 void InfoStudents(const caffe::Student & stu){
     cout<< "student info:"<<endl;
     cout<<"     name: "<<stu.name()<<endl;
     cout<<"     age: "<<stu.age()<<endl;
     cout<<"     grade: "<<stu.grade()<<endl;
 }
 
 void InfoTeacher(const caffe::Teacher & teacher) {
     cout << "teacher info:" << endl;
     cout << "       name: " << teacher.name() << endl;
     cout << "       age: " << teacher.age() << endl;
     cout<< "            is worker: "<<teacher.work().isworker()<<endl;
     cout<< "            is jiaban: "<<teacher.work().isjiaban()<<endl;
 }
 
 
 int main(void)
 {
     caffe::Class cls;
     int file_desc = open("./param.prototxt",O_NDELAY);
 
     google::protobuf::io::FileInputStream fileInputStream(file_desc);
     if(!google::protobuf::TextFormat::Parse(&fileInputStream,&cls)){
         std::cout<<"parse failure."<<std::endl;
         return -1;
     }
     std::cout<<cls.name()<<std::endl;
 
 
     //按照索引进行读取
     for(int i=1;i<cls.GetMetadata().descriptor->field_count(); ++i){
         std::cout<<cls.descriptor()->field(i)->name()<<std::endl;
         //cout<<cls.descriptor()->field(i)->full_name()<<endl;
         if(cls.descriptor()->field(i)->name()=="stu"){
             for (auto &stu_info : cls.stu()){
 
                  InfoStudents(stu_info);
             }
         }
 
         if(cls.descriptor()->field(i)->name()=="teacher"){
             for (auto &teacher_info : cls.teacher()){
 
                 InfoTeacher(teacher_info);
             }
         }
     }
 
     return 0;
 }


 


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




 


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


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


https://github.com/gongxijun/protoc


« 上一篇:wifi共享上网(至尊版wifi)
« 下一篇:c++代码优化经验
在这里写下您精彩的评论
  • 微信

  • QQ

  • 支付宝

返回首页
返回首页 img
返回顶部~
返回顶部 img