日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人工智能 > Caffe >内容正文

Caffe

Caffe代码导读(1):Protobuf例子

發(fā)布時間:2025/3/21 Caffe 142 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Caffe代码导读(1):Protobuf例子 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)載自:

Caffe代碼導(dǎo)讀(1):Protobuf例子 - 卜居 - 博客頻道 - CSDN.NET ?

http://blog.csdn.net/kkk584520/article/details/41046827

Protobuf是一種可以實現(xiàn)內(nèi)存與外存交換的協(xié)議接口。這是由谷歌開發(fā)的開源工具,目前研究Caffe源碼時用到。

一個軟件項目 = 數(shù)據(jù)結(jié)構(gòu) + 算法 + 參數(shù),對于數(shù)據(jù)結(jié)構(gòu)和算法我們都已經(jīng)有較多研究,但不同開發(fā)者對參數(shù)管理卻各有千秋。有人喜歡TXT格式化的參數(shù)文件,有人喜歡BIN簡單高效,也有人喜歡圖形化界面的直觀。不一致的參數(shù)管理帶來很多問題,例如一個項目組內(nèi)不同成員必須約定一套統(tǒng)一的參數(shù)方案,或者稱為通信協(xié)議,這樣便于模塊集成。而Protobuf工具就完美解決了這個問題,關(guān)鍵部分代碼自動生成,節(jié)省了大量的開發(fā)、調(diào)試時間。


首先下載protobuf,地址(打不開?……不解釋)

這里用Linux版本2.5.0

解壓:

tar zxvf protobuf-2.5.0.tar.gz

切到主目錄:

cd?protobuf-2.5.0

編譯:

./configure

make

sudo make install


添加環(huán)境變量:

export PKG_CONFIG_PATH=$(pwd)


編譯examples:

cd examples/

make cpp

這里我們只編譯C++代碼。


編譯完成,生成了以下可執(zhí)行文件:

add_person_cpp

list_people_cpp

這是個通訊錄的例子。我們首先運行add_person_cpp:

[plain] view plaincopyprint?
  • ./add_person_cpp?zyk??
  • zyk:?File?not?found.??Creating?a?new?file.??
  • Enter?person?ID?number:?123??
  • Enter?name:?zhaoyongke??
  • Enter?email?address?(blank?for?none):?zhaoyongke@yeah.net??
  • Enter?a?phone?number?(or?leave?blank?to?finish):?188188188??
  • Is?this?a?mobile,?home,?or?work?phone?(回車)??
  • Unknown?phone?type.??Using?default.??
  • Enter?a?phone?number?(or?leave?blank?to?finish):(回車)??
  • ./add_person_cpp zyk zyk: File not found. Creating a new file. Enter person ID number: 123 Enter name: zhaoyongke Enter email address (blank for none): zhaoyongke@yeah.net Enter a phone number (or leave blank to finish): 188188188 Is this a mobile, home, or work phone?(回車) Unknown phone type. Using default. Enter a phone number (or leave blank to finish):(回車)
    然后運行l(wèi)ist_people_cpp:

    [plain] view plaincopyprint?
  • ./list_people_cpp?zyk??
  • Person?ID:?123??
  • ??Name:?zhaoyongke??
  • ??E-mail?address:?zhaoyongke@yeah.net??
  • ??Home?phone?#:?188188188??
  • ./list_people_cpp zyk Person ID: 123Name: zhaoyongkeE-mail address: zhaoyongke@yeah.netHome phone #: 188188188
    可見我們生成了新的通訊錄zyk,里面保存了相應(yīng)的信息。


    例子運行結(jié)束了,我們看下代碼是如何生成的。

    protobuf使用前,先編寫proto文件,這是描述我們需要配置參數(shù)的數(shù)據(jù)結(jié)構(gòu)。這個例子里面的proto如下:

    [plain] view plaincopyprint?
  • //?See?README.txt?for?information?and?build?instructions.??
  • ??
  • package?tutorial;??
  • ??
  • option?java_package?=?"com.example.tutorial";??
  • option?java_outer_classname?=?"AddressBookProtos";??
  • ??
  • message?Person?{??
  • ??required?string?name?=?1;??
  • ??required?int32?id?=?2;????????//?Unique?ID?number?for?this?person.??
  • ??optional?string?email?=?3;??
  • ??
  • ??enum?PhoneType?{??
  • ????MOBILE?=?0;??
  • ????HOME?=?1;??
  • ????WORK?=?2;??
  • ??}??
  • ??
  • ??message?PhoneNumber?{??
  • ????required?string?number?=?1;??
  • ????optional?PhoneType?type?=?2?[default?=?HOME];??
  • ??}??
  • ??
  • ??repeated?PhoneNumber?phone?=?4;??
  • }??
  • ??
  • //?Our?address?book?file?is?just?one?of?these.??
  • message?AddressBook?{??
  • ??repeated?Person?person?=?1;??
  • }??
  • // See README.txt for information and build instructions.package tutorial;option java_package = "com.example.tutorial"; option java_outer_classname = "AddressBookProtos";message Person {required string name = 1;required int32 id = 2; // Unique ID number for this person.optional string email = 3;enum PhoneType {MOBILE = 0;HOME = 1;WORK = 2;}message PhoneNumber {required string number = 1;optional PhoneType type = 2 [default = HOME];}repeated PhoneNumber phone = 4; }// Our address book file is just one of these. message AddressBook {repeated Person person = 1; }
    前幾行是定義包的,可以忽略。

    message Person{...}定義了一個需要傳輸?shù)膮?shù)結(jié)構(gòu)體,可見包括這么幾個單元:name(string類型)、id(int32類型)、email(string類型)、phone(PhoneNumber類型,嵌套在Person內(nèi)的類)。前面標(biāo)記為“required”是必須有值的,而“optional“則為可選項,”repeated“表示后面單元為相同類型的一組向量。


    有了如上定義,我們可以用protobuf工具生成接口代碼,命令如下:

    [plain] view plaincopyprint?
  • protoc?--cpp_out=.??addressbook.proto??
  • protoc --cpp_out=. addressbook.proto
    運行后生成了兩個文件:addressbook.pb.cc 和addressbook.pb.h,代碼比較長就不貼了。我們的應(yīng)用程序可以通過自動生成的接口實現(xiàn)參數(shù)的序列化/反序列化,代碼如下:

    [cpp] view plaincopyprint?
  • //add_person.c??
  • #include?<iostream>??
  • #include?<fstream>??
  • #include?<string>??
  • #include?"addressbook.pb.h"??
  • using?namespace?std;??
  • ??
  • //?This?function?fills?in?a?Person?message?based?on?user?input.??
  • void?PromptForAddress(tutorial::Person*?person)?{??
  • ??cout?<<?"Enter?person?ID?number:?";??
  • ??int?id;??
  • ??cin?>>?id;??
  • ??person->set_id(id);??
  • ??cin.ignore(256,?'\n');??
  • ??
  • ??cout?<<?"Enter?name:?";??
  • ??getline(cin,?*person->mutable_name());??
  • ??
  • ??cout?<<?"Enter?email?address?(blank?for?none):?";??
  • ??string?email;??
  • ??getline(cin,?email);??
  • ??if?(!email.empty())?{??
  • ????person->set_email(email);??
  • ??}??
  • ??
  • ??while?(true)?{??
  • ????cout?<<?"Enter?a?phone?number?(or?leave?blank?to?finish):?";??
  • ????string?number;??
  • ????getline(cin,?number);??
  • ????if?(number.empty())?{??
  • ??????break;??
  • ????}??
  • ??
  • ????tutorial::Person::PhoneNumber*?phone_number?=?person->add_phone();??
  • ????phone_number->set_number(number);??
  • ??
  • ????cout?<<?"Is?this?a?mobile,?home,?or?work?phone??";??
  • ????string?type;??
  • ????getline(cin,?type);??
  • ????if?(type?==?"mobile")?{??
  • ??????phone_number->set_type(tutorial::Person::MOBILE);??
  • ????}?else?if?(type?==?"home")?{??
  • ??????phone_number->set_type(tutorial::Person::HOME);??
  • ????}?else?if?(type?==?"work")?{??
  • ??????phone_number->set_type(tutorial::Person::WORK);??
  • ????}?else?{??
  • ??????cout?<<?"Unknown?phone?type.??Using?default."?<<?endl;??
  • ????}??
  • ??}??
  • }??
  • //?Main?function:??Reads?the?entire?address?book?from?a?file,??
  • //???adds?one?person?based?on?user?input,?then?writes?it?back?out?to?the?same??
  • //???file.??
  • int?main(int?argc,?char*?argv[])?{??
  • ??//?Verify?that?the?version?of?the?library?that?we?linked?against?is??
  • ??//?compatible?with?the?version?of?the?headers?we?compiled?against.??
  • ??GOOGLE_PROTOBUF_VERIFY_VERSION;??
  • ??
  • ??
  • ??if?(argc?!=?2)?{??
  • ????cerr?<<?"Usage:??"?<<?argv[0]?<<?"?ADDRESS_BOOK_FILE"?<<?endl;??
  • ????return?-1;??
  • ??}??
  • ??
  • ??
  • ??tutorial::AddressBook?address_book;??
  • ??
  • ??
  • ??{??
  • ????//?Read?the?existing?address?book.??
  • ????fstream?input(argv[1],?ios::in?|?ios::binary);??
  • ????if?(!input)?{??
  • ??????cout?<<?argv[1]?<<?":?File?not?found.??Creating?a?new?file."?<<?endl;??
  • ????}?else?if?(!address_book.ParseFromIstream(&input))?{??
  • ??????cerr?<<?"Failed?to?parse?address?book."?<<?endl;??
  • ??????return?-1;??
  • ????}??
  • ??}??
  • ??
  • ??
  • ??//?Add?an?address.??
  • ??PromptForAddress(address_book.add_person());??
  • ??
  • ??
  • ??{??
  • ????//?Write?the?new?address?book?back?to?disk.??
  • ????fstream?output(argv[1],?ios::out?|?ios::trunc?|?ios::binary);??
  • ????if?(!address_book.SerializeToOstream(&output))?{??
  • ??????cerr?<<?"Failed?to?write?address?book."?<<?endl;??
  • ??????return?-1;??
  • ????}??
  • ??}??
  • ??
  • ??
  • ??//?Optional:??Delete?all?global?objects?allocated?by?libprotobuf.??
  • ??google::protobuf::ShutdownProtobufLibrary();??
  • ??
  • ??
  • ??return?0;??
  • }??
  • //add_person.c #include <iostream> #include <fstream> #include <string> #include "addressbook.pb.h" using namespace std;// This function fills in a Person message based on user input. void PromptForAddress(tutorial::Person* person) {cout << "Enter person ID number: ";int id;cin >> id;person->set_id(id);cin.ignore(256, '\n');cout << "Enter name: ";getline(cin, *person->mutable_name());cout << "Enter email address (blank for none): ";string email;getline(cin, email);if (!email.empty()) {person->set_email(email);}while (true) {cout << "Enter a phone number (or leave blank to finish): ";string number;getline(cin, number);if (number.empty()) {break;}tutorial::Person::PhoneNumber* phone_number = person->add_phone();phone_number->set_number(number);cout << "Is this a mobile, home, or work phone? ";string type;getline(cin, type);if (type == "mobile") {phone_number->set_type(tutorial::Person::MOBILE);} else if (type == "home") {phone_number->set_type(tutorial::Person::HOME);} else if (type == "work") {phone_number->set_type(tutorial::Person::WORK);} else {cout << "Unknown phone type. Using default." << endl;}} } // Main function: ?Reads the entire address book from a file, // ? adds one person based on user input, then writes it back out to the same // ? file. int main(int argc, char* argv[]) {// Verify that the version of the library that we linked against is// compatible with the version of the headers we compiled against.GOOGLE_PROTOBUF_VERIFY_VERSION;if (argc != 2) {cerr << "Usage: ?" << argv[0] << " ADDRESS_BOOK_FILE" << endl;return -1;}tutorial::AddressBook address_book;{// Read the existing address book.fstream input(argv[1], ios::in | ios::binary);if (!input) {cout << argv[1] << ": File not found. ?Creating a new file." << endl;} else if (!address_book.ParseFromIstream(&input)) {cerr << "Failed to parse address book." << endl;return -1;}}// Add an address.PromptForAddress(address_book.add_person());{// Write the new address book back to disk.fstream output(argv[1], ios::out | ios::trunc | ios::binary);if (!address_book.SerializeToOstream(&output)) {cerr << "Failed to write address book." << endl;return -1;}}// Optional: ?Delete all global objects allocated by libprotobuf.google::protobuf::ShutdownProtobufLibrary();return 0; }

    可見只需要調(diào)用addressbook.pb.h中聲明的tutorial::AddressBook類、Person類中的接口(add_person(), add_phone(), set_number(), set_email()等)就能操作相應(yīng)的參數(shù),最后將內(nèi)存中的參數(shù)序列化為文件只需要執(zhí)行SerializeToOstream()。相應(yīng)的讀取參數(shù)文件的操作為ParseFromIstream()。這里貼出例子中的第二個程序如下:

    [cpp] view plaincopyprint?
  • //?list_people.c??
  • ??
  • #include?<iostream>??
  • #include?<fstream>??
  • #include?<string>??
  • #include?"addressbook.pb.h"??
  • using?namespace?std;??
  • ??
  • //?Iterates?though?all?people?in?the?AddressBook?and?prints?info?about?them.??
  • void?ListPeople(const?tutorial::AddressBook&?address_book)?{??
  • ??for?(int?i?=?0;?i?<?address_book.person_size();?i++)?{??
  • ????const?tutorial::Person&?person?=?address_book.person(i);??
  • ??
  • ????cout?<<?"Person?ID:?"?<<?person.id()?<<?endl;??
  • ????cout?<<?"??Name:?"?<<?person.name()?<<?endl;??
  • ????if?(person.has_email())?{??
  • ??????cout?<<?"??E-mail?address:?"?<<?person.email()?<<?endl;??
  • ????}??
  • ??
  • ????for?(int?j?=?0;?j?<?person.phone_size();?j++)?{??
  • ??????const?tutorial::Person::PhoneNumber&?phone_number?=?person.phone(j);??
  • ??
  • ??????switch?(phone_number.type())?{??
  • ????????case?tutorial::Person::MOBILE:??
  • ??????????cout?<<?"??Mobile?phone?#:?";??
  • ??????????break;??
  • ????????case?tutorial::Person::HOME:??
  • ??????????cout?<<?"??Home?phone?#:?";??
  • ??????????break;??
  • ????????case?tutorial::Person::WORK:??
  • ??????????cout?<<?"??Work?phone?#:?";??
  • ??????????break;??
  • ??????}??
  • ??????cout?<<?phone_number.number()?<<?endl;??
  • ????}??
  • ??}??
  • }??
  • ??
  • //?Main?function:??Reads?the?entire?address?book?from?a?file?and?prints?all??
  • //???the?information?inside.??
  • int?main(int?argc,?char*?argv[])?{??
  • ??//?Verify?that?the?version?of?the?library?that?we?linked?against?is??
  • ??//?compatible?with?the?version?of?the?headers?we?compiled?against.??
  • ??GOOGLE_PROTOBUF_VERIFY_VERSION;??
  • ??
  • ??if?(argc?!=?2)?{??
  • ????cerr?<<?"Usage:??"?<<?argv[0]?<<?"?ADDRESS_BOOK_FILE"?<<?endl;??
  • ????return?-1;??
  • ??}??
  • ??
  • ??tutorial::AddressBook?address_book;??
  • ??
  • ??{??
  • ????//?Read?the?existing?address?book.??
  • ????fstream?input(argv[1],?ios::in?|?ios::binary);??
  • ????if?(!address_book.ParseFromIstream(&input))?{??
  • ??????cerr?<<?"Failed?to?parse?address?book."?<<?endl;??
  • ??????return?-1;??
  • ????}??
  • ??}??
  • ??
  • ??ListPeople(address_book);??
  • ??
  • ??//?Optional:??Delete?all?global?objects?allocated?by?libprotobuf.??
  • ??google::protobuf::ShutdownProtobufLibrary();??
  • ??
  • ??return?0;??
  • }??
  • // list_people.c#include <iostream> #include <fstream> #include <string> #include "addressbook.pb.h" using namespace std;// Iterates though all people in the AddressBook and prints info about them. void ListPeople(const tutorial::AddressBook& address_book) {for (int i = 0; i < address_book.person_size(); i++) {const tutorial::Person& person = address_book.person(i);cout << "Person ID: " << person.id() << endl;cout << " Name: " << person.name() << endl;if (person.has_email()) {cout << " E-mail address: " << person.email() << endl;}for (int j = 0; j < person.phone_size(); j++) {const tutorial::Person::PhoneNumber& phone_number = person.phone(j);switch (phone_number.type()) {case tutorial::Person::MOBILE:cout << " Mobile phone #: ";break;case tutorial::Person::HOME:cout << " Home phone #: ";break;case tutorial::Person::WORK:cout << " Work phone #: ";break;}cout << phone_number.number() << endl;}} }// Main function: Reads the entire address book from a file and prints all // the information inside. int main(int argc, char* argv[]) {// Verify that the version of the library that we linked against is// compatible with the version of the headers we compiled against.GOOGLE_PROTOBUF_VERIFY_VERSION;if (argc != 2) {cerr << "Usage: " << argv[0] << " ADDRESS_BOOK_FILE" << endl;return -1;}tutorial::AddressBook address_book;{// Read the existing address book.fstream input(argv[1], ios::in | ios::binary);if (!address_book.ParseFromIstream(&input)) {cerr << "Failed to parse address book." << endl;return -1;}}ListPeople(address_book);// Optional: Delete all global objects allocated by libprotobuf.google::protobuf::ShutdownProtobufLibrary();return 0; }
    相信做完這個實驗,你將不再對Caffe代碼中的參數(shù)初始化、參數(shù)保存操作感到陌生,一切都很自然。

    ?除了上述簡單功能,Protobuf還可以用來傳遞不同語言(C/C++與Java、Python)之間的參數(shù),省去了自己手動維護數(shù)據(jù)結(jié)構(gòu)的繁瑣工作。也可以支持客戶端/服務(wù)器模式,在主機/從機之間傳遞參數(shù)。


    總結(jié)

    以上是生活随笔為你收集整理的Caffe代码导读(1):Protobuf例子的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。