Caffe源码理解(1)——caffe框架梳理

Caffe是深度学习的一种框架,由C++和Python编写,底层是C++源码。

一、Caffe-master源代码大框架:
这里写图片描述

关键文件如下:
- data:用于存放caffe-master中程序所需要的原始数据(图片等)
- docs:用于存放帮助文档
- examples:用于存放代码
- include/caffe:用于存放头文件.hpp(非常重要!!)
- matlab:用于存放Matlab接口文件
- python:用于存放Python接口文件
- scripts:用于存放在跑程序的时候会用到的脚本文件(shell、sh)
- src:用于存放Caffe源码.cpp/.cu(非常重要!!)
- tools:用于存放一些二进制文件,用于调用一些可直接运行的的帮助程序

上述4&8中最重要的核心代码为:

  • layers:各类层定义的.cpp/.cu/.hpp文件(后续会详细讲解如何新定义一个层结构)
  • solvers:各类优化方法SGD、Adam等(后续会详细分析优化实现具体过程)
  • test:测试Caffe的代码
  • proto:protobuf

    二、 Caffe的四大组成:
    1、Blob:表示网络中的数据

  • 头文件:存放在caffe/include/caffe/blob.hpp
    其中定义protected数据成员:

protected:
  shared_ptr<SyncedMemory> data_;
  shared_ptr<SyncedMemory> diff_;
  shared_ptr<SyncedMemory> shape_data_;
  vector<int> shape_;
  int count_;
  int capacity_;

其中定义Blob数据(data&diff)访问方法:

const Dtype* cpu_data() const;
const int* gpu_shape() const;
const Dtype* cpu_diff() const;
const Dtype* gpu_diff() const;
Dtype* mutable_cpu_data();
Dtype* mutable_gpu_data();
Dtype* mutable_cpu_diff();
Dtype* mutable_gpu_diff();
  • 源代码:存放在caffe/src/caffe/blob.cpp,其主要成员函数主要有:
void Blob<Dtype>::Reshape(...)
void Blob<Dtype>::ReshapeLike(const Blob<Dtype>& other)
void Blob<Dtype>::Update()  //更新权值的函数:data_=data_-diff_
void Blob<Dtype>::ShareData(const Blob& other)
 void Blob<Dtype>::ShareDiff(const Blob& other)

2、Net:连接layers,整个网络的表示

3、Layer:对神经网络中各个层的抽象(后续会详细讲解定义一个新的层)

4、Solver:定义了神经网络模型的求解方法(默认SGD,后续会讲解Solver是如何完成权值更新)

  • caffe/src/caffe/solver.cpp

在Solver类的成员函数solve()中实际调用Solver的另一个成员函数Step():

void Solver<Dtype>::Solve(const char* resume_file) {
 CHECK(Caffe::root_solver());
...
Step(param_.max_iter() - iter_);
...
}

Step():

template <typename Dtype>
void Solver<Dtype>::Step(int iters) {
  const int start_iter = iter_;
  const int stop_iter = iter_ + iters;
  int average_loss = this->param_.average_loss();
  losses_.clear();
  smoothed_loss_ = 0;
  iteration_timer_.Start();

  ...

  //accumulate the loss and gradient
  Dtype loss = 0;
    for (int i = 0; i < param_.iter_size(); ++i) {
      loss += net_->ForwardBackward(); //Net类中的Forward()函数,用于传递loss
    }
    loss /= param_.iter_size();
// average the loss across iterations for smoothed reporting
    UpdateSmoothedLoss(loss, start_iter, average_loss); //求平均让loss变得更平滑

   ...

ApplyUpdate();//重要!!Solver类的一个纯虚函数,需要派生类来实现,所以在不同的具体**_solver.cpp中对此进行详细定义

那么以SGD为例来看ApplyUpdate():
- caffe/include/caffe/solvers/sgd_solver.hpp
- caffe/src/caffe/solvers/sgd_solver.cpp(caffe/src/caffe/solvers/sgd_solver.cpp)

template <typename Dtype>
void SGDSolver<Dtype>::ApplyUpdate() {
  Dtype rate = GetLearningRate();//得到当前迭代的learning_rate的值
  if (this->param_.display() && this->iter_ % this->param_.display() == 0) {
    LOG_IF(INFO, Caffe::root_solver()) << "Iteration " << this->iter_
        << ", lr = " << rate;
  }
  ClipGradients();//避免梯度爆炸所做的梯度裁剪
  //对网络中所有需要更新的参数进行操作:
  for (int param_id = 0; param_id < this->net_->learnable_params().size();
       ++param_id) {
    Normalize(param_id);//正规化:related to the issue of feature scaling
    Regularize(param_id);//正则化:to avoid overfitting when training machine learning algorithm
    ComputeUpdateValue(param_id, rate);//计算新的权值更新梯度diff_
  }
  this->net_->Update();//完成更新操作:data_=data_-diff_
}

其中:GetLearningRate()、ClipGradients()、Normalize()、Regularize()在此.cpp文件中均有定义,感兴趣的读者可以自行阅读。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值