/************************************************************************************************************************
文件说明:
【1】Caffe的I/O模块
【2】数据读取层
Caffe的I/O模块的说明:
【1】Caffe的I/O模块,即与数据打交道的模块
【2】我们在运行caffe例程前,首先需要将【原始数据】转换为LMDB格式
【3】训练网络时则需要由【数据读取层】【DataLayer】不断地从LMDB读取数据,送入后续卷积、下采样等计算层。
【4】俗话说“民以食为天”,caffeI/O模块的效率直接影响到处理效率。
Caffe的数据读取层:
【1】Caffe的数据读取层(DataLayer)是Layer的派生类。
【2】除了读取LMDB、LEVELDB之外,也可以从原始图像直接获取(ImageDataLayer)
开发环境:
Win10+caffe+cuda7.5+opencv+vs2013
时间地点:
陕西师范大学 文津楼 2017.8.8
作 者:
九 月
*************************************************************************************************************************/
/************************************************************************************************************************
文件说明:
【数据输入层】(DataLayer)数据结构的描述
开发环境:
Win10+caffe+cuda7.5+opencv+vs2013
时间地点:
陕西师范大学 文津楼 2017.8.8
作 者:
九 月
*************************************************************************************************************************/
message DataParameter
{
enum DB //【1】输入数据使用的DB类型
{
LEVELDB = 0; //【2】使用LEVELDB数据结构
LMDB = 1; //【3】使用LMDB数据结构
}
optional string source = 1; //【1】源数据的路径
optional uint32 batch_size = 4; //【2】一个批量数据包含的图片数量
optional uint32 rand_skip = 7 [default = 0]; //【3】随机跳过若干图片,跳跃数目为rand_skip*rand(0,1)
optional DB backend = 8 [default = LEVELDB];//【4】默认输入数据使用的DB类型,默认为LEVELDB
optional float scale = 2 [default = 1]; //【5】scale、mean_file、crop_size、mirror均为旧版参数,现在
// 已经转移到TransformationParameter
optional string mean_file = 3;
optional uint32 crop_size = 5 [default = 0];
optional bool mirror = 6 [default = false];
optional bool force_encoded_color = 9 [default = false]; //【6】强制编码图像为三通道彩色图像
optional uint32 prefetch = 10 [default = 4]; //【7】预取队列(预先存放到主机内存中的批量数目,默认为4个Batch)
}
#ifndef CAFFE_DATA_LAYERS_HPP_
#define CAFFE_DATA_LAYERS_HPP_
#include <vector>
#include "caffe/blob.hpp"
#include "caffe/data_transformer.hpp"
#include "caffe/internal_thread.hpp"
#include "caffe/layer.hpp"
#include "caffe/proto/caffe.pb.h"
#include "caffe/util/blocking_queue.hpp"
namespace caffe
{
template <typename Dtype>
class BaseDataLayer : public Layer<Dtype>
{
public:
/***************************************************************************************************************
函数说明:
显示构造函数
****************************************************************************************************************/
explicit BaseDataLayer(const LayerParameter& param);
/***************************************************************************************************************
函数说明:
层配置函数,实现通用层配置功能,之后调用DataLayerSetUp进行数据读取层的特殊配置
****************************************************************************************************************/
virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top);
/***************************************************************************************************************
函数说明:
数据读取层应被多个并行【求解器】共享
****************************************************************************************************************/
virtual inline bool ShareInParallel() const { return true; }
/***************************************************************************************************************
函数说明:
数据读取层的特殊配置函数
****************************************************************************************************************/
virtual void DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top) {}
/***************************************************************************************************************
函数说明:
数据读取层的变形操作函数
****************************************************************************************************************/
virtual void Reshape(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top) {}
/***************************************************************************************************************
函数说明:
反向传播函数不需要做任何操作
****************************************************************************************************************/
virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {}
virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {}
protected:
TransformationParameter transform_param_; //【1】【数据预处理变换器】参数
shared_ptr<DataTransformer<Dtype> > data_transformer_; //【2】数据预处理变换器
bool output_labels_; //【3】是否输出标签数据
};
/*****************************************************************************************************************
模块说明:
批量数据,用于存放数据读取层的输出
******************************************************************************************************************/
template <typename Dtype>
class Batch
{
public:
Blob<Dtype> data_; //【1】存放图片数据
Blob<Dtype> label_; //【2】存放标签数据
};
template <typename Dtype>
class BasePrefetchingDataLayer :public BaseDataLayer<Dtype>, public InternalThread
{
public:
explicit BasePrefetchingDataLayer(const LayerParameter& param);
void LayerSetUp(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top);
virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top);
virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top);
static const int PREFETCH_COUNT = 3;
protected:
virtual void InternalThreadEntry();
virtual void load_batch(Batch<Dtype>* batch) = 0;
Batch<Dtype> prefetch_[PREFETCH_COUNT];
BlockingQueue<Batch<Dtype>*> prefetch_free_;
BlockingQueue<Batch<Dtype>*> prefetch_full_;
Blob<Dtype> transformed_data_;
};
} // namespace caffe
#endif // CAFFE_DATA_LAYERS_HPP_
/************************************************************************************************************************
文件说明:
【1】数据变换读取层
【2】Caffe的【数据变换读取层】(DataTransformer)主要提供了对【原始输入图像】的预处理方法,包括:
【1】随机切块
【2】随机镜像
【3】幅度缩放
【4】去均值
【5】灰度/色度变换
开发环境:
Win10+caffe+cuda7.5+opencv+vs2013
时间地点:
陕西师范大学 文津楼 2017.8.8
作 者:
九 月
*************************************************************************************************************************/
/************************************************************************************************************************
文件说明:
【1】数据变换读取层
【2】数据结构描述
开发环境:
Win10+caffe+cuda7.5+opencv+vs2013
时间地点:
陕西师范大学 文津楼 2017.8.8
作 者:
九 月
*************************************************************************************************************************/
message TransformationParameter
{
optional float scale = 1 [default = 1]; //【1】像素幅度缩放参数,默认为1,即不缩放
optional bool mirror = 2 [default = false]; //【2】图像随机镜像开关,默认为false,不进行镜像操作
optional uint32 crop_size = 3 [default = 0]; //【3】图像随机切块的大小,默认为false,不进行切块
optional string mean_file = 4; //【4】存储图像均值的文件
repeated float mean_value = 5; //【5】均值数值,无需读取文件
optional bool force_color = 6 [default = false]; //【6】强制为三通道彩色图像输入
optional bool force_gray = 7 [default = false]; //【7】强制为三通道灰度
}
#ifndef CAFFE_DATA_TRANSFORMER_HPP
#define CAFFE_DATA_TRANSFORMER_HPP
#include <vector>
#include "caffe/blob.hpp"
#include "caffe/common.hpp"
#include "caffe/proto/caffe.pb.h"
namespace caffe
{
template <typename Dtype>
class DataTransformer {
public:
explicit DataTransformer(const TransformationParameter& param, Phase phase);
virtual ~DataTransformer() {}
void InitRand();
void Transform(const Datum& datum, Blob<Dtype>* transformed_blob);
void Transform(const vector<Datum> & datum_vector,Blob<Dtype>* transformed_blob);
#ifdef USE_OPENCV
void Transform(const vector<cv::Mat> & mat_vector,Blob<Dtype>* transformed_blob);
void Transform(const cv::Mat& cv_img, Blob<Dtype>* transformed_blob);
#endif // USE_OPENCV
void Transform(Blob<Dtype>* input_blob, Blob<Dtype>* transformed_blob);
vector<int> InferBlobShape(const Datum& datum);
vector<int> InferBlobShape(const vector<Datum> & datum_vector);
#ifdef USE_OPENCV
vector<int> InferBlobShape(const vector<cv::Mat> & mat_vector);
vector<int> InferBlobShape(const cv::Mat& cv_img);
#endif // USE_OPENCV
protected:
virtual int Rand(int n);
void Transform(const Datum& datum, Dtype* transformed_data);
TransformationParameter param_;
shared_ptr<Caffe::RNG> rng_;
Phase phase_;
Blob<Dtype> data_mean_;
vector<Dtype> mean_values_;
};
} // namespace caffe
#endif // CAFFE_DATA_TRANSFORMER_HPP_