Caffe阅读记录(1)

[TOC]

安装

环境

  • Ubuntu 14.04.4, 无N卡, 不使用CUDA

安装依赖

编译准备

修改Makefile.config

  • 注释掉所有与CUDA相关的配置

需要修改的配置

编译

使用IDE调试Caffe

  • 为了方便查看和理解代码, 使用IDE加载项目, 可方便地进行单步调试等。这里以Qt为例

Caffe目录结构

  • > data 用于存放训练数据等
  • > docs 文档
  • > examples 一些示例等
  • > matlab MATLAB接口
  • > python Python接口
  • > models 用于存放模型
  • > scripts 存放一些需要用到的脚本
  • > tools 编译好的一些二进制可执行文件, caffe实际运行中就是直接调用这些二进制
  • > include caffe代码的头文件们
  • > src caffe的源文件

** 核心为src和include **

src结构

  • src
    • gtest //Google test 一个用于测试的库
    • caffe
      • test
      • util
      • proto
      • layers
      • solvers

Blob类

  • Blob类存在namespace caffe 中, Blob是作为Caffe中数据流通的一个基本类,网络各层之间的数据是通过Blob来传递的。

related programming methods

  • 条件编译, 命名空间, 类模板, inline等

specific coding skills

  • exlicit

具体解析

类定义

  • Blob类使用了类模板

  • DISABLE_COPY_AND_ASSIGN(Blob) 为一个宏定义, 用来禁止一个类拷贝构造

类成员变量

  • shared_ptr

    shared_ptr是一种智能指针(smart pointer)。shared_ptr的作用有如同指针,但会记录有多少个shared_ptrs共同指向一个对象。
    (即引用计数),shared_ptr最初实现于Boost库中,后来被C++标准委员会收录于TR1技术报告中,成为C++11标准的一部分。shared_ptr与scoped_ptr一样包装了new操作符在堆上分配的动态对象,但它实现的是引用计数型的智能指针 ,可以被自由地拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为0)它时才删除被包装的动态分配的对象。shared_ptr也可以安全地放到标准容器中,并弥补了auto_ptr因为转移语义而不能把指针作为STL容器元素的缺陷。

  • SyncedMemory类

    SyncedMemory类用于管理CPU和GPU之间的内存分配和同步

    在SyncedMemory的实现中使用了CHECK(data)这样的代码, CHECK()是glog中的一个宏定义, 这里用来
    data是否为空(未被初始化)

    Glog 是一个C++语言的应用级日志记录框架

    在这里用到了__builtin_expect(x, 0), __builtin_expect是GCC的一个内建函数, 用于帮助编译器优化分支预测.
    __builtin_expect(x, 0)是指告知编译器x的期望值为0.

  • 回到Blob类成员变量

    • data_ 指针用于存储正向传播时的数据
    • diff_ 指针用于存储反向传播时的偏差
    • shape_data 和 shape_ 都用于存储Blob的形状, 其中一个是老版本, 一个是新版本
    • count 表示Blob中的元素个数, 即 个数*每个通道数*高度*宽度
    • capacity表示当前的元素个数,因为Blob可能会reshape。

构造函数

  • explicit

    在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换。

    • explicit 关键字只能用于类内部的构造函数声明上
    • explicit 关键字作用于单个参数的构造函数
    • 在 C++ 中, explicit关键字用来修饰类的构造函数, 被修饰的构造函数, 不能发生相应的隐式类型转换

reshape

  • reshape 用来改变数据的形状, 前向传播和后向传播时或其他时候使用, 实际上, 构造函数也是调用此函数来达到初始化的目的

    • CHECK_LE(shape.size(), kMaxBlobAxes); 用于检查是否超过32维
    • 使用了static_cast<int*> 来进行类型转换
    • if (count_ > capacity_) 只有reshape之后大小比当前更大时才重新分配内存, 而不是每次都重新分配以减小开销

其他函数

  • 此处用了多个CHECK_XX, 来自Glog, 用来保证参数合法.

  • Update 中调用了 caffe_axpy, 其位于math_functions, 作用是Y = alpha*X – Y, 因此Update()作用是将data减去diff

  • BlobProto继承自::google::protobuf::Message
    > Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前提供了 C++、Java、Python 三种语言的 API。

Blob收获

Leave a Comment

电子邮件地址不会被公开。 必填项已用*标注