标签:文档 state 合并 示例 channels 交换 ati 0.00 ret
( (n * channels() + c) * height() + h) * width() + w;
表示的是元素(n,c,h,w)在blob中的索引。
n*channels()+c
表示的是当前元素所处的通道的索引((n * channels() + c) * height() + h)
当前元素所处的行所在的索引以RGB图像为例描述BLOB在内存中的格式,假设当前BLOB中有N张图,图的高为H,宽为W像素:
|------------------------img0-----------------------|...img1~imgN-1...|
|<------channel R-------> <-channel G-><-channel B->|..................
|<row0--row2-...row(H-1)>...........................|..................
|对应的R、或G、或B的值......
成员变量
//指向存储数据的内存或显存块,一般是图像数据、权值或偏置值数据
shared_ptr<SyncedMemory> data_;
shared_ptr<SyncedMemory> diff_;//保存反向传递时的梯度信息
成员函数
void Reshape (const vector<int>& shape);
//用于调整下标。C++数组不支持负数下标,当前函数的功能就是将负数转化为对应的正数下标
inline int CanonicalAxisIndex (int axis_index) const;
//blob中还有一些对数据进行简单计算的方法
SyncedMemory中的部分成员
const void* cpu_data();
void set_cpu_data (void* data);
const void* gpu_data();
void set_gpu_data (void* data);
void* mutable_cpu_data();//与上面的cpu_data和gpu_data相对应,只不过内容可改
void* mutable_gpu_data();
数据成员
//当前层的参数,LayerParameter的结构定义在caffe.proto中
LayerParameter layer_param_;
Phase phase_;//用于测试还是训练,有些层只能用于测试,而有些是测试训练均可
vector<shared_ptr<Blob<Dtype> > > blobs_;//指向需要训练的参数
/** Vector indicating whether to compute the diff of each param blob. */
vector<bool> param_propagate_down_;
/** The vector that indicates whether each top blob has a non-zero weight in the objective function. */
vector<Dtype> loss_;//损失函数值
函数成员
virtual void LayerSetUp (...);
inline Dtype Forward (...);
inline void Backward (...);
//Returns the vector of learnable parameter blobs.
vector<shared_ptr<Blob<Dtype> > >& blobs();
//Writes the layer parameter to a protocol buffer
virtual void ToProto (...);
net类定义了网络的结构,即各个层(layers)之间的组合(连接)方式。网络的结构在caffe中是定义在prototxt文件中的,下面以lenet网络的部分结构为例来说明(caffe中的网络层可以并列,下面使用deepid网络为例来说明)
name: "LeNet"#网络结构的名称
layer {
name: "data" #当前层的名称
type: "Input"#当前层的类型
top: "data" #输出层的名称,一般每个layer都有输入与输出两个“子层”,Input层比较特殊,不用写bottom
input_param { shape: { dim: 64 dim: 1 dim: 28 dim: 28 } } #当前层的参数
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data" #指明当前层将从“data”层获得输入数据
top: "conv1" #指明输出层的名称,一般与当前层的名称相同
param {... #因为篇幅,具体参数这里忽略
}
###################################################################
# 以deepid网络为例,caffe中的层可以连接多个层也可以将多个层合并为一个输出
...
layer {
name: "pool3"
...
}
# 下面两层的输入都取自pool3,且这两层的类别也不同
layer {
name: "deepid_match_conv"
type: "Pooling"
bottom: "pool3" # 从pool3中获得输入数据
...
}
layer {
name: "conv4"
type: "Convolution"
bottom: "pool3" # 从pool3中获得输入数据
...
}
...
layer {
name: "pool4"
type: "Pooling"
bottom: "norm4"
top: "pool4"
...
}
# 下面这一层的输入数据来自于两个层:pool4和上面的deepid_match_conv,并只有一个输出
layer {
name: "deepid_concat"
type: "Concat"
bottom: "deepid_match_conv"
bottom: "pool4"
top: "deepid_concat"
}
...
数据成员
string name; //网络的名称
//各个层的信息
vector<shared_ptr<Layer<Dtype> > > layers_;
vector<string> layer_names_;
map<string, int> layer_names_index_;
//保存层层之间交互的信息
vector<shared_ptr<Blob<Dtype> > > blobs_;
vector<string> blob_names_;
map<string, int> blob_names_index_;
函数成员
//前向传输,前向传输还有其他形式的函数如:ForwardFromTo、ForwardFrom等
const vector<Blob<Dtype>*>& Forward (Dtype* loss = NULL);
//有前向亦有反向传播函数
void Backward();// void BackwardFrom (int start);等形式
//前向传输后进行反向传播并返回前向传输时的损失函数输出
Dtype ForwardBackward();
//设置层数据的函数
void CopyTrainedLayersFrom (const NetParameter& param);//亦有其他形式
//其他形式的help函数,例如ToHDF5、ToProto等
以lenet网络的训练solver为例说明solver需要的参数
net: "./lenet_train_test.prototxt" #网络结构文件
#指明测试时前向传输的次数(每次batch size个样本)
#平均这些结果即为网络的当前对test数据集的精度
test_iter: 100
test_interval: 100 # 指明进行多少次训练后进行测试
base_lr: 0.01 #基本的学习率
momentum: 0.9 #加速训练的一个参数
weight_decay: 0.0005 #目的是正则化,降低过拟合的风险
# 学习率更新的策略,一般在整个训练过程中学习率是会变化的
lr_policy: "inv"
gamma: 0.0001
power: 0.75
# 训练多少次显示一次信息
# 信息中包括迭代次数、时间、当前网络对测试集与训练集的损失函数输出
display: 100
max_iter: 1000 #最大的训练次数,达到这个次数时caffe会停止训练并保存模型
snapshot: 500 #多久保存一次当前训练模型的快照,caffe可以从指定的快照处开始训练
snapshot_prefix: "./snapshot/lenet" # 快照文件保存的位置
solver_mode: GPU #设置solver运行的模式GPU or CPU
LayerParameter中定义了如下参数(这里只有部分,具体可参考caffe.proto文件)
optional string name; // the layer name
optional string type; // the layer type
repeated string bottom; // the name of each bottom blob
repeated string top; // the name of each top blob
// The train / test phase for computation. 有些层只用于TEST
optional Phase phase;
// The blobs containing the numeric parameters of the layer.
//BlobProto也是一种结构,同样定义在caffe.proto中,这个和blob.hpp中定义的结构不同
//在内存中使用后者的结构,在硬盘中使用前者的结构
repeated BlobProto blobs;
// Rules controlling whether and when a layer is included in the network
repeated NetStateRule include;
repeated NetStateRule exclude;
optional LossParameter loss_param;// Parameters shared by loss layers.
// Layer type-specific parameters.
optional AccuracyParameter accuracy_param;
optional ArgMaxParameter argmax_param;
optional BatchNormParameter batch_norm_param;
...
proto 格式示例与解释
syntax = "proto2";//指明所使用的协议版本号
//名字空间,自动生成代码时所有代码均在这个名字空间内,在C++中会像这样:namespace tutorial {...}
package tutorial;
//结构化数据被称为 Message
//在hpp文件中会生成如下类和结构:
//enum Person_PhoneType;
//class Person_PhoneNumber : public ::google::protobuf::Message;
//class Person :public ::google::protobuf::Message;
//class AddressBook : public ::google::protobuf::Message;
message Person {
// 字段(类成员)定义格式:限定修饰符① | 数据类型② | 字段名称③ | = | 字段编码值④ | [字段默认值⑤]
// 每一个变量前都需要使用下面三个词进行修饰:required、optional、repeated
// required表示是一个必须字段,必须相对于发送方(对应于数据的序列化方),在发送消息之前必须设置该字段的值,
// 对于接收方(对应于数据的反序列化方),必须能够识别该字段的意思。
// 发送之前没有设置required字段或者无法识别required字段都会引发编解码异常,导致消息被丢弃。
required string name = 1;
// 这里的数值"=1、=2..."是编码值,编码值用于通信双方互相识别对方的字段
// 其中 1~15的编码时间和空间效率都是最高的,编码值越大,其编码的时间和空间效率就越低
// 1900~2000编码值为Google protobuf 系统内部保留值,建议不要在自己的项目中使用
required int32 id = 2;
// optional表示是一个可选字段,可选对于发送方,在发送消息时,可以有选择性的设置或者不设置该字段的值
// 对于接收方,如果能够识别可选字段就进行相应的处理,如果无法识别,则忽略该字段,消息中的其它字段正常处理
// 项目投入运营以后涉及到版本升级时的新增消息字段全部使用optional或者repeated,尽量不使用required
// 如果使用了required,需要全网统一升级,如果使用optional或者repeated可以平滑升级
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
// 表示该字段可以包含0~N个元素。其特性和optional一样,但是每一次可以包含多个值
// 可以看作是在传递一个数组的值
repeated PhoneNumber phones = 4;
}
message AddressBook {
repeated Person people = 1;
}
The Protocol Buffer API(通过 Protobuf 编译器编译上面的proto文件所获得的)
// name
inline bool has_name() const;//判断信息中是否包含当前元素
inline void clear_name();
inline const ::std::string& name() const;//下面是getter和setter
inline void set_name(const ::std::string& value);
inline void set_name(const char* value);
inline ::std::string* mutable_name();
...
Writing A Message & Reading A Message(使用上面API的示例)
//create Message
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());
...
//read massage
cout << "Person ID: " << person.id() << endl;
cout << " Name: " << person.name() << endl;
if (person.has_email()) {
cout << " E-mail address: " << person.email() << endl;
}
标签:文档 state 合并 示例 channels 交换 ati 0.00 ret
原文地址:http://www.cnblogs.com/jiahu-Blog/p/7895901.html