caffe:debug之数据预取流程

在caffe中我们经常会看到数据读取,但对其入口函数却无从下手。其实训练和预取数据在caffe中是使用了不同的线程,所以在网络训练流程中找不到数据读取的源码。现在我们来分析一下caffe的另一个线程,perfetchingData。读取数据在搭建网络,第一次测试所给权重损失(TestAll),和整个网路训练测试时候的前向传播(Forward(layer.cpp))中都频繁出现。具体如下: 

 

 

首先当一个操作指向了数据层,需要取数据时会进入到BasePrefetchingDataLayer(base_data_layer.cpp) 

具体如下: 

 

 此处的return也是返回的一个函数,对于每一层创建不同的层类型,例如第一层是Data,即数据层,位于data_layer.cpp 

此宏定义如下 

进入 

 

              

成功进入 BaseprefetchingDataLayer(实现位于base_data_layer.cpp) 

BasePrefetchingDataLayer是一个模板类,继承了BaseDataLayer和InternalThread 

此模板类具体如下: 

 

我们的debug进入其构造函数: 

 

然后首先看其初始化列表BaseDataLayer(base_data_layer.cpp)的构造函数  

继续深入。进入其初始化列表Layer(layer.hpp)构造函数 

 

(重点要来了)然后看其第二个父类InternalThread的构造函数,此线程就是用来读取数据的 

此类的介绍为 

 

意思是是要实现了上述函数即可创建一个自己想要的新的线程 

 

在此类中还包含了一个startThread函数在此函数中开了一个线程 

 

线程如下,回调入口函数为entry 

 

在entry的最后就包含了我们所需要实现的InternalThreadEntry() 

 

在BasePrefetchingDataLayer构造函数执行完后进入DataLayer(data_layer.cpp) 

 

然后进入DataReader(data_reader.cpp) 

 

其构造函数中函数Body(data_reader.cpp)于是找到 

终于找到了心心念念的StartInternalThread,于是按照上述所说,创建一个新的线程。 

 

在data_reader.cpp中找到我们要实现的InternalThreadEntry函数 

 

不难看到 

此处便是要读取的数据的类型 

 

然后我们接着往下看 看到了两个read_one函数,如果没理解错,第一个read_one应该是检查用,而第二个是训练时取数据所使用的。但read_one内容一样 

 

read_one(data_reader.cpp)具体实现 

 

 

当read_one执循环执行读取数据后线程获取到InternalThreadEntry 

 

进入load_batch(实现位于data_layer.cpp) 

 

其实现如下 

 

 

当然 在数据读取时首先读取的是datum然后从datum转换为blob,在转换过程中实现了对图片的处理,如宽高,和我们之前定义的均值文件等,确保数据在网络中可以正确运行计算。数据转换位于(data_transformer.cpp) 

 

于是会有 

中的 

其源码为 

 

同时 !!! 在layersetup中也有此函数,也就是说,当创建该层的时候,另一个线程就开始运行。 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值