1. 看 blob.cpp 之前,首先来看blob.hpp。
可以看到,Blob有几个主要的成员:
data_ : 存储 data,前向传播的数据
diff_ : 存储 diff, 反向传播的误差
count_ : 当前Blob有效元素个数
capacity_ : Blob的容量大小。
2. 在 Blob 的构造函数中,会调用Reshape() 来初始化对象Blob,根据shape(主要是num, channels, height, width)和数据类型Dtype来为data_ 和 diff_ 分配内存空间。
data_.reset(new SyncedMemory(capacity_ * sizeof(Dtype)));
diff_.reset(new SyncedMemory(capacity_ * sizeof(Dtype)));
在各个 layer 层的初始化SetUp()函数中也会调用Reshape() 来初始化各个层的Blob。
3. offset()
inline int offset(const int n, const int c = 0, const int h = 0, const int w = 0) const {
...
return ((n * channels() + c) * height() + h) * width() + w;
}
offset函数用户计算(n, c, h, w) 表示下的坐标在内存空间中相应的位置。
4.
const Dtype* cpu_data() const;
const Dtype* gpu_data() const;
const Dtype* cpu_diff() const;
const Dtype* gpu_diff() const;
这四个函数分别可以 只读 访问 cpu 或者 gpu 中的 data 和 diff。
Dtype* mutable_cpu_data();
Dtype* mutable_gpu_data();
Dtype* mutable_cpu_diff();
Dtype* mutable_gpu_diff();
这四个函数分别可以 读写 访问 cpu 或者 gpu 中的 data 和 diff。
5. Update()
template <typename Dtype>
void Blob<Dtype>::Update() {
...
caffe_axpy<Dtype>(count_, Dtype(-1),
static_cast<const Dtype*>(diff_->cpu_data()),
static_cast<Dtype*>(data_->mutable_cpu_data()));
...}
Update()函数通过 blas 实现 data = data - diff 的功能。具体可参考math_functions.hpp。
6.
Dtype asum_data() const; //计算的L1范数
Dtype asum_diff() const;
Dtype sumsq_data() const; //计算L2范数
Dtype sumsq_diff() const;
void scale_data(Dtype scale_factor); //乘以一个scale_factor
void scale_diff(Dtype scale_factor);