caffe源码阅读(3)-Datalayer
DataLayer是把数据从文件导入到网络的层,从网络定义prototxt文件可以看一下数据层定义
layer {
name: "data"
type: "Data"
top: "data"
top: "label"
include {
phase: TRAIN
}
transform_param {
mirror: true
crop_size: 224
mean_value: 104
mean_value: 117
mean_value: 123
}
data_param {
source: "examples/imagenet/ilsvrc12_train_lmdb"
batch_size: 32
backend: LMDB
}
}
l
数据层包括了文件位置、文件类型、bath_size大小、图片变换等一些参数。可以看书,datalayer之后有top,没有bottom,即它是最底层的,它的forward运算只是负责把数据填充到top即可,并不使用bottom。
在caffe中数据层不仅仅限于DataLayer,因为常常使用DataLayer导入数据,这里只是阅读DataLayer部分。
数据层相关代码定义在data_layers.hpp中,DataLayer是从其他类派生出来的,一层一层来阅读。除了用到了datalayer相关的类,还用到了InternalThread,用来封装了线程,使用线程函数来取数据;类BlockingQueue是一个阻塞队列,用来辅助取数据;类DataReader,用来从文件读数据。
BaseDataLayer
BaseDataLayer直接从Layer派生出来。其成员变量有
TransformationParameter transform_param_;//具体在protobuf中
shared_ptr<DataTransformer<Dtype> > data_transformer_;//和输入数据转换相关。流入scale,crop,mirror等
bool output_labels_;//是否有标签,无标签可以是无监督学习
TransformationParameter是图像变换一些相关的参数,例如图像缩放、镜像变换、crop、减去均值等操作。
DataTransformer类实现了图像变换的函数。
Batch
类Batch是和批相关的类,只是把2个数据结构封装为一个,把数据和标签对应起来。
template <typename Dtype>
class Batch {
public:
Blob<Dtype> data_, label_;
};
BasePrefetchingDataLayer
类BasePrefetchingDataLayer派生自BaseDataLayer和InternalThread。其中InternalThread是封装了线程,通过虚函数InternalThreadEntry来执行线程函数,用一个单独的线程函数来取数据。
成员变量为:
Batch<Dtype> prefetch_[PREFETCH_COUNT];
BlockingQueue<Batch<Dtype>*> prefetch_free_;
BlockingQueue<Batch<Dtype>*> prefetch_full_;
Blob<Dtype> transformed_data_;//用来辅助实现图片变换操作
PREFETCH_COUNT的大小,程序设为3,为了提前填充free队列。两个阻塞队列,逻辑功能比较简单:从free队列取数据结构,填充数据结构放到full队列;从full队列取数据,使用数据,清空数据结构,放到free队列。还有一个Blob结构,用来当做中间变量辅助图像变换。
虚函数InternalThreadEntry是线程执行的函数,用来取数据
//这里是取数据的线程
template <typename Dtype>
void BasePrefetchingDataLayer<Dtype>::InternalThreadEntry() {
#ifndef CPU_ONLY
cudaStream_t stream;
if (Caffe::mode() == Caffe::GPU) {
CUDA_CHECK(cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking));
}
#endif
try {
while (!must_stop()) {
Batch<Dtype>* batch = prefetch_free_.pop();//从free_队列去数据结构
load_batch(batch);//取数据,填充数据结构。在其派生类实现的
#ifndef CPU_ONLY
if (Caffe::mode() == Caffe::GPU) {
batch->data_.data().get()->async_gpu_push(stream);//异步,把数据同步到GPU,使用Syncedmem->async_gpu_push
CUDA_CHECK(cudaStreamSynchronize(stream));
}
#endif
prefetch_full_.push(batch);//把数据放到full_队列
}
} catch (boost::thread_interrupted&) {
// Interrupted exception is expected on shutdown
}
#ifndef CPU_ONLY
if (Caffe::mode() == Caffe::GPU) {
CUDA_CHECK(cudaStreamDestroy(stream));
}
#endif
}
数据层的forward函数不进行计算,不使用bottom,只是准备数据,填充到top
template <typename Dtype>
void BasePrefetchingDataLayer<Dtype>::Forward_cpu(
const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {
Batch<Dtype>* batch = prefetch_full_.pop("Data layer prefetch queue empty");//从full队列取数据
// Reshape to loaded data.
top[0]->ReshapeLike(batch->data_);//调整top大小,一次读取一个batch大小的数据
// Copy the data。把数据拷贝到top中
caffe_copy(batch->data_.count(), batch->data_.cpu_data(),
top[0]->mutable_cpu_data());
DLOG(INFO) << "Prefetch copied";
if (this->output_labels_) {//如果有标签,也要把标签拷贝到top中
// Reshape to loaded labels.
top[1]->ReshapeLike(batch->label_);
// Copy the labels.
caffe_copy(batch->label_.count(), batch->label_.cpu_data(),
top[1]->mutable_cpu_data());
}
prefetch_free_.push(batch);//用过的数据结构,放回free队列
}
DataLayer
DataLayer是真正在网络中使用的类,派生自BasePrefetchingDataLayer。成员变量为:
DataReader reader_;
DataReader负责从硬盘读数据到一个队列,之后提供给data_layer使用.即使并行运行多个solver,也只有一个线程来读数据,这样可以确保'顺序'取数据,不同的solver取到的数据不同.
DataReader的没有bottom,top中,如果没有标签,blob数量为1;有标签blob数量为2。
虚函数load_batch,一次导入一个batch_size大小的数据;之后进行DataTransformer变换。
caffe源码阅读(3)-Datalayer的更多相关文章
- Caffe源码阅读(1) 全连接层
Caffe源码阅读(1) 全连接层 发表于 2014-09-15 | 今天看全连接层的实现.主要看的是https://github.com/BVLC/caffe/blob/master/src ...
- caffe源码阅读
参考网址:https://www.cnblogs.com/louyihang-loves-baiyan/p/5149628.html 1.caffe代码层次熟悉blob,layer,net,solve ...
- caffe源码阅读(1)-数据流Blob
Blob是Caffe中层之间数据流通的单位,各个layer之间的数据通过Blob传递.在看Blob源码之前,先看一下CPU和GPU内存之间的数据同步类SyncedMemory:使用GPU运算时,数据要 ...
- caffe源码阅读(一)convert_imageset.cpp注释
PS:本系列为本人初步学习caffe所记,由于理解尚浅,其中多有不足之处和错误之处,有待改正. 一.实现方法 首先,将文件名与它对应的标签用 std::pair 存储起来,其中first存储文件名,s ...
- caffe源码阅读(2)-Layer
神经网络是由层组成的,深度神经网络就是层数多了.layer对应神经网络的层.数据以Blob的形式,在不同的layer之间流动.caffe定义的神经网络已protobuf形式定义.例如: layer { ...
- caffe源码阅读(1)_整体框架和简介(摘录)
原文链接:https://www.zhihu.com/question/27982282 1.Caffe代码层次.回答里面有人说熟悉Blob,Layer,Net,Solver这样的几大类,我比较赞同. ...
- caffe 源码阅读
bvlc:Berkeley Vision and Learning Center. 1. 目录结构 models(四个文件夹均有四个文件构成,deploy.prototxt, readme.md, s ...
- caffe中batch norm源码阅读
1. batch norm 输入batch norm层的数据为[N, C, H, W], 该层计算得到均值为C个,方差为C个,输出数据为[N, C, H, W]. <1> 形象点说,均值的 ...
- 源码阅读经验谈-slim,darknet,labelimg,caffe(1)
本文首先谈自己的源码阅读体验,然后给几个案例解读,选的例子都是比较简单.重在说明我琢磨的点线面源码阅读方法.我不是专业架构师,是从一个深度学习算法工程师的角度来谈的,不专业的地方请大家轻拍. 经常看别 ...
随机推荐
- 【Kafka入门】Kafka入门第一篇:基础概念篇
Kafka简介 Kafka是一个消息系统服务框架,它以提交日志的形式存储消息,并且消息的存储是分布式的,为了提供并行性和容错保障,消息的存储是分区冗余形式存在的. Kafka的架构 Kafka中包含以 ...
- 嵌套在母版页中的repeater自动生成控件ID
注:如果直接在后台通过e.Item.FindControl()方法直接找控件,然后再通过对其ID赋值,在编译之后会出现“母版页名称_ID“类似的很长的ID值(详情点击) 解决方法:<asp:Co ...
- Redis压缩列表原理与应用分析
摘要 Redis是一款著名的key-value内存数据库软件,同时也是一款卓越的数据结构服务软件.它支持字符串.列表.哈希表.集合.有序集合五种数据结构类型,同时每种数据结构类型针对不同的应用场景又支 ...
- springMVC学习笔记--初识springMVC
前一段时间由于项目的需要,接触了springMVC(这里主要是讲3.1版,以下内容也是围绕这个版本展开),发觉其MVC模式真的很强大,也简单易用,完全是基于注解实现其优雅的路径配置的.想想以前接手的项 ...
- [二]JFreeChart实践一
生成一张简单的图片 java代码: package com.lxl.chart; import javax.servlet.http.HttpSession; import org.jfree.cha ...
- 【转】基于RMAN实现坏块介质恢复(blockrecover)
本文转自:乐沙弥的世界 对于物理损坏的数据块,我们可以通过RMAN块介质恢复(BLOCK MEDIA RECOVERY)功能来完成受损块的恢复,而不需要恢复整个数据库或所有文件来修复这些少量受损的数据 ...
- 库不存在的排查方法:ImportError: No module named selenium2Library
解决办法: 把selenium2Library改成Selenium2Library 安装下面四个: python-2.7.13.amd64.msi robotframework-ride-1.5. ...
- 远程使用Gpupdate(Hash,哈希)
function Start-GPUpdate { param ( [String[]] $ComputerName ) $code ...
- Hibernate关联关系映射
1. Hibernate关联关系映射 1.1. one to one <class name="Person"> <id name="id" ...
- [Javascript] Create an Array concatAll method
In addition to flat Arrays, programmers must often deal with nested Arrays. For example let's say we ...