Net在caffe中代表一个完整的CNN模型,它包含若干Layer实例,一个Net对应一个*.prototxt文件,*.prototxt文件对应ProtoBuffer数据,*.prototxt文件的解析和.bin后缀的ProtoBuffer文件类似。caffe具体的prototxt文件的读写函数,在/caffe/utils/io.cpp中。
// 从txt读取proto的定义
bool ReadProtoFromTextFile(const char* filename, Message* proto);
// 从text读取proto的定义
inline bool ReadProtoFromTextFile(const string& filename, Message* proto) {
return ReadProtoFromTextFile(filename.c_str(), proto);
}
// 从text读取proto的定义,只是增加了检查而已
inline void ReadProtoFromTextFileOrDie(const char* filename, Message* proto) {
CHECK(ReadProtoFromTextFile(filename, proto));
}
// 从text读取proto的定义,只是增加了检查而已
inline void ReadProtoFromTextFileOrDie(const string& filename, Message* proto) {
ReadProtoFromTextFileOrDie(filename.c_str(), proto);
}
// 将proto写入到txt文件
void WriteProtoToTextFile(const Message& proto, const char* filename);
inline void WriteProtoToTextFile(const Message& proto, const string& filename) {
WriteProtoToTextFile(proto, filename.c_str());
}
以caffe中caffe-master/examples/cifar10/下的cifar10_full.prototxt文件的解析为例:
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/text_format.h>
#include "caffe.pb.h"
using namespace std;
using namespace caffe;
using google::protobuf::io::FileInputStream;
using google::protobuf::io::FileOutputStream;
using google::protobuf::io::ZeroCopyInputStream;
using google::protobuf::io::CodedInputStream;
using google::protobuf::io::ZeroCopyOutputStream;
using google::protobuf::io::CodedOutputStream;
using google::protobuf::Message;
bool ReadProtoFromTextFile(const char* filename, Message* proto)
{
int fd = open(filename, O_RDONLY);
FileInputStream* input = new FileInputStream(fd);
bool success = google::protobuf::TextFormat::Parse(input, proto);//TextFormat::Parse函数从指定文本文件中读取protobuf数据
delete input;
close(fd);
return success;
}
void WriteProtoToTextFile(const Message& proto, const char* filename) {
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
FileOutputStream* output = new FileOutputStream(fd);
google::protobuf::TextFormat::Print(proto, output); //TextFormat::Print函数把protobuf数据写入到指定文本文件中
delete output;
close(fd);
}
int main()
{
std::string fileName = "cifar10_full.prototxt";
caffe::NetParameter *protoMsgPtr = new caffe::NetParameter;
ReadProtoFromTextFile(fileName.c_str(), protoMsgPtr);
std::cout<<protoMsgPtr->DebugString()<<std::endl;
std::string writeFile = "cifar10_full_write.prototxt";
WriteProtoToTextFile(*protoMsgPtr, writeFile.c_str());
delete protoMsgPtr;
return 0;
}
运行结果
name: "CIFAR10_full_deploy"
layer {
name: "data"
type: "Input"
top: "data"
input_param {
shape {
dim: 1
dim: 3
dim: 32
dim: 32
}
}
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 32
pad: 2
kernel_size: 5
stride: 1
}
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 3
stride: 2
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "pool1"
top: "pool1"
}
layer {
name: "norm1"
type: "LRN"
bottom: "pool1"
top: "norm1"
lrn_param {
local_size: 3
alpha: 5e-05
beta: 0.75
norm_region: WITHIN_CHANNEL
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "norm1"
top: "conv2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 32
pad: 2
kernel_size: 5
stride: 1
}
}
layer {
name: "relu2"
type: "ReLU"
bottom: "conv2"
top: "conv2"
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: AVE
kernel_size: 3
stride: 2
}
}
layer {
name: "norm2"
type: "LRN"
bottom: "pool2"
top: "norm2"
lrn_param {
local_size: 3
alpha: 5e-05
beta: 0.75
norm_region: WITHIN_CHANNEL
}
}
layer {
name: "conv3"
type: "Convolution"
bottom: "norm2"
top: "conv3"
convolution_param {
num_output: 64
pad: 2
kernel_size: 5
stride: 1
}
}
layer {
name: "relu3"
type: "ReLU"
bottom: "conv3"
top: "conv3"
}
layer {
name: "pool3"
type: "Pooling"
bottom: "conv3"
top: "pool3"
pooling_param {
pool: AVE
kernel_size: 3
stride: 2
}
}
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool3"
top: "ip1"
param {
lr_mult: 1
decay_mult: 250
}
param {
lr_mult: 2
decay_mult: 0
}
inner_product_param {
num_output: 10
}
}
layer {
name: "prob"
type: "Softmax"
bottom: "ip1"
top: "prob"
}
Press <RETURN> to close this window...