我觉得学习caffe,必须得做到会修改源码,刚开始可以不需要知道所有的函数是如何实现的,但必须得知道里边都有哪些函数,这些函数都可以干什么。
用网上流行的比喻:Blobs,Layers,Nets的关系就好比,Blob是砖块,Layer是墙,net是一栋大楼。
Blob:
Blob是一个模板类,在内存中表示4维数组,维度从低到高为:width、height、channels(颜色通道)、num(第几帧)
函数总结:
- Reshape:变形函数,根据输入参数重新设置当前Blob形状
- cpu_data:只读获取cpu data的指针
- set_cpu_data:修改cpu data的指针
- gpu_data:只读获得gpu data的指针
- cpu_diff:只读获得cpu diff的指针
- gpu_diff:只读获得gpu diff的指针
- mutable_cpu_data:读写访问cpu data的指针
- mutable_gpu_data:读写访问gpu data的指针
- mutable_cpu_diff:读写访问cpu diff的指针
- mutable_gpu_diff:读写访问gpu diff的指针
- ShareData:共享data指针
- ShareDiff:共享diff指针
- Update:网络参数Blob的更新
- asum_data:计算data的L1范数
- sumsq_data:计算data的L2范数
- scale_data:对data进行幅度缩放
- CopyFrom:从另一个Blob对象拷贝data
- FromProto:从BlobProto中加载一个Blob
- ToProto:将Blob中的data导出到BlobProto结构体
Layer:
Layer至少有一个输入Blob和一个输出Blob,部分Layer带有权值和偏置项,有两个运算方向:前向传播、后向传播
值得注意的是:大部分函数没有在Layer.cpp中实现,只有虚函数,真正实现的都在派生类中,具体看各个cpp
函数总结:
- Reshape:变形函数,修改Top Blob以及内部Blob缓冲区的形状
- Forward:前向传播函数,给定Bottom Blob,计算Top Blob和Loss,返回值为当前层loss
- Backward:反向传播函数,给定Top Blob误差梯度,就按Bottom Blob误差梯度
- ToProto:将Layer初始化参数写入ProtoBuffer缓冲区中
- loss:返回某个Top Blob相关的标量loss值
- CheckBlobCounts:校验输入/输出BLob数目是否满足Layer要求
- SetLossWeights:该函数在layer中SetUp函数中被调用,主要目的是初始化与Top Blob相关的loss权重,放到Top Blob的diff域中,实际由Forward()计算loss
在layer中的Forward和Backward是前向传播函数和后向传播函数包装,不需要修改这两个函数,使用的时候只需要在派生类改写Forward_cpu、Forward_gpu、Backward_cpu、Backward_gpu
Net:
Net在caffe中代表一个完整的CNN模型,它包括若干Layer实例
函数总结:
- ForwardPrefilled:运行前向传播,输入Blob已经预先填充
- ForwardFromTo:前向传播的其中一种形式,还包括其他两种形式
- Forward:前向传播,指定输入Blob进行前向传播
- ClearParamDiffs:清零所有权值的diff域,应在反向传播之前运行
- Backward:反向传播,无需指定输入/输出Blob,因为前向传播的时候已经建立联系
- ForwardBackward:前向传播+后向传播,输入为Bottom Blob,输出为loss
- Update:根据已经(solver)准备好的diff值更新网络权值
- ToProto:序列化一个Net到ProtoBuffer
- ToHDF5:序列化一个Net到HDF5
- num_inputs:返回输入Blob数目
- num_output:返回输出Blob数目
- FilterNet:过滤掉用户指定的在某个阶段、级别、状态下不应该包含的Layer
- AppendTop:为网络追加一个Top Blob
- AppendBottom:为网络追加一个Bottom Blob
- AppendParam:为网络追加一个权值Blob