前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >caffe源码分析-DataReader

caffe源码分析-DataReader

作者头像
bear_fish
发布2019-02-25 11:53:00
4740
发布2019-02-25 11:53:00
举报

DataReader作为DataLayer的数据成员变量,以多线程的方式从数据库(如lmdb, hdf5)读取数据:

代码语言:javascript
复制
class DataReader {
public:
    explicit DataReader(const LayerParameter& param);
    ~DataReader();

    inline BlockingQueue<Datum*>& free() const {
        return queue_pair_->free_;
    }
    inline BlockingQueue<Datum*>& full() const {
        return queue_pair_->full_;
    }

protected:
    // Queue pairs are shared between a body and its readers
    class QueuePair {
    public:
        explicit QueuePair(int size);
        ~QueuePair();

        BlockingQueue<Datum*> free_;
        BlockingQueue<Datum*> full_;

    DISABLE_COPY_AND_ASSIGN(QueuePair);
    };

    // A single body is created per source
    class Body : public InternalThread {
    public:
        explicit Body(const LayerParameter& param);
        virtual ~Body();

    protected:
        void InternalThreadEntry();
        void read_one(db::Cursor* cursor, QueuePair* qp);

        const LayerParameter param_;
        BlockingQueue<shared_ptr<QueuePair> > new_queue_pairs_;

        friend class DataReader;

    DISABLE_COPY_AND_ASSIGN(Body);
    };

    // A source is uniquely identified by its layer name + path, in case
    // the same database is read from two different locations in the net.
    static inline string source_key(const LayerParameter& param) {
        return param.name() + ":" + param.data_param().source();
    }

protected:
    const shared_ptr<QueuePair> queue_pair_;
    shared_ptr<Body> body_;

    static map<const string, boost::weak_ptr<DataReader::Body> > bodies_;

    DISABLE_COPY_AND_ASSIGN(DataReader);
};

下面看构造函数, 预读取的总的数据长度为prefetch*batch_size, weak_ptr结合shared_ptr保证线程安全:

代码语言:javascript
复制
DataReader::DataReader(const LayerParameter& param)
        : queue_pair_(new QueuePair(  //
        param.data_param().prefetch() * param.data_param().batch_size())) {
    // Get or create a body
    boost::mutex::scoped_lock lock(bodies_mutex_);
    string key = source_key(param);
    weak_ptr<Body>& weak = bodies_[key];
    body_ = weak.lock();
    if (!body_) {
        body_.reset(new Body(param));
        bodies_[key] = weak_ptr<Body>(body_);
    }
    body_->new_queue_pairs_.push(queue_pair_);
}

线程的核心函数:

代码语言:javascript
复制
void DataReader::Body::InternalThreadEntry() {
    shared_ptr<db::DB> db(db::GetDB(param_.data_param().backend()));
    db->Open(param_.data_param().source(), db::READ);
    shared_ptr<db::Cursor> cursor(db->NewCursor());
    vector<shared_ptr<QueuePair> > qps;

        // Main loop
        while (!must_stop()) {
            for (int i = 0; i < solver_count; ++i) {
                read_one(cursor.get(), qps[i].get());
            }
            CHECK_EQ(new_queue_pairs_.size(), 0);
        }
}

void DataReader::Body::read_one(db::Cursor* cursor, QueuePair* qp) {
    Datum* datum = qp->free_.pop();
    datum->ParseFromString(cursor->value());
    qp->full_.push(datum);
    // go to the next iter
    cursor->Next();
}

caffe系列源码分析介绍

本系列深度学习框架caffe 源码分析主要内容如下:

1. caffe源码分析-cmake 工程构建:

caffe源码分析-cmake 工程构建主要内容:

自己从头构建一遍工程,这样能让我更好的了解大型的项目的构建。当然原始的caffe的构建感觉还是比较复杂(主要是cmake),我这里仅仅使用cmake构建,而且简化点,当然最重要的是支持CLion直接运行调试(如果需要这个工程可以评论留下你的邮箱,我给你发送过去)。

2. caffe的数据内存分配类SyncedMemory, 以及类Blob数据传输的媒介.

主要内容:

caffe源码分析-SyncedMemory

caffe源码分析-Blob

其中Blob分析给出了其直接与opencv的图片相互转化以及操作,可以使得我们更好的理解Blob.

3. caffe layer的源码分析,包括从整体上说明了layer类别以及其proto定义与核心函数.

内容如下:

caffe源码分析-layer

caffe源码分析-ReLULayer

caffe源码分析-inner_product_layer

caffe源码分析-layer_factory

首先分析了最简单的layer Relu,然后在是inner_product_layer全连接层, 最后是layer_factorycaffe中 以此工厂模式create各种Layer.

4. 数据输入层,主要是多线程+BlockingQueue的方式读取数据训练:

内容如下:

caffe源码分析-BlockingQueue

caffe源码分析-InternalThread

caffe源码分析-DataReader

5. IO处理例如读取proto文件转化为网络,以及网络参数的序列化

内容如下:

caffe源码分析-DataTransformer

caffe源码分析-db, io

6. 最后给出了使用纯C++结合多层感知机网络训练mnist的示例

内容如下:

caffe c++示例(mnist 多层感知机c++训练,测试)

类似与caffe一样按照layer、solver、loss、net等模块构建的神经网络实现可以见下面这篇blog,相信看懂了这个python的代码理解caffe框架会更简单点.

神经网络python实现


最后如果需要**cmake** + CLion**直接运行调试**caffe**的代码工程,可以评论留下你的邮箱,我给你发送过去.**

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年10月07日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • caffe系列源码分析介绍
    • 1. caffe源码分析-cmake 工程构建:
      • 2. caffe的数据内存分配类SyncedMemory, 以及类Blob数据传输的媒介.
        • 3. caffe layer的源码分析,包括从整体上说明了layer类别以及其proto定义与核心函数.
          • 4. 数据输入层,主要是多线程+BlockingQueue的方式读取数据训练:
            • 5. IO处理例如读取proto文件转化为网络,以及网络参数的序列化
              • 6. 最后给出了使用纯C++结合多层感知机网络训练mnist的示例
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档