caffe数据层相关学习以及训练在线数据增广

来源:互联网 发布:什么是java远程调用 编辑:程序博客网 时间:2024/05/23 23:18

caffe数据层是将已经生成好的LMDB文件中的label和数据读入到Datum数据结构体中,然后将数据转化到Blob中,进而进行数据传递,才能进行数据训练。目前使用的data_layer是经过了别人的改版,能够读入多个LMDB,并且在source_filelists中除了写入图像数据,还会加入每个数据样本所对应的key,从而实现Key—Value一一对应的结果。

本次希望实现的主要功能是希望在训练过程中,能够实时的随机改变图像数据的饱和度、亮度和对比度,进而能够达到数据增广的目的,增加数据的多样性,使得训练得到的模型的泛化性更好。而如果要达到这样的目的,就需要对data_transformer.cpp进行相应的代码更改。除此以外,因为希望在训练过程中,只对负样本进行数据增广,而不改变正样本。所以还需要对data_layer层进行相应更改。因为最初生成的key中已经记录了样本的正负属性,所以可以在对key进行相应处理知道属性是“正”or“负”。

提前在数据结构体中增加了bool is_augmentated变量。如果在data_layer中判断样本为负,则将is_augmentated值设为true,则在data_transformer.cpp中进行相应的数据增广。

在data_transformer.cpp和data_transformer.hpp中首先添加调整图像饱和度、亮度和对比度的函数。几个函数都传入的是Blob数据体的数据头,因为已经Blob的地址都是连续的,这样方便直接进行地址操作。但是要注意,和cv::Mat的数据存储格式HWC有所区别,Blob的存储格式是CHW,因此在使用指针进行地址操作的时候,需要进行相应的转变。

饱和度调整函数代码如下:

template <typename Dtype> \\注意次数需要使用对应的模板void DataTransformer<Dtype>::Saturation( \\饱和度调整Dtype* img, \\ 第一个坑,尽管blob是float型的,但是因为使用了模板,所以需要将所有和blob挂钩的变量类型都要更改为Dtype,这是一个模板类型的变量。const int img_size,const float alpha_rand  \\ 增广参数的范围,该参数是在网络中设置的,所以需要相应的更改caffe.proto文件,在TransformationParameter中增加相关参数) {float alpha = 0.0f;Dtype tempPixel = 0.0f;GenerateRandomFloat_range(alpha_rand, &alpha); \\根据caffe自带的随机数生成器Rand(),得到-alpha_rand~alpha_rand的随机实数// BGR to Gray scale image: R -> 0.299, G -> 0.587, B -> 0.114for (int h = 0; h < img_size; ++h) {for (int w = 0; w < img_size; ++w) {Dtype gray_color = img[0 * img_size*img_size + h*img_size + w] * 0.114f + img[1 * img_size*img_size + h*img_size + w] * 0.587f +img[2 * img_size*img_size + h*img_size + w] * 0.299f;                  // 因为是已经是直接对Blob进行地址操作,所以可以直接使用指针头进行相应的位置移                for (int c = 0; c < 3; ++c) { t                        empPixel = img[c * img_size*img_size + h*img_size + w] * alpha + gray_color * (1.0f - alpha);img[c * img_size*img_size + h*img_size + w] = CheckAugmentatedValue(&tempPixel);                  //CheckAugmentatedValue()是特意增加的边界检测,防止修改后的数值超过[0,255]的图像范围}}}}
调整亮度和对比度的代码和饱和度的类似,不再增加相关注释

// assume HWC order and color channels BGRtemplate <typename Dtype>void DataTransformer<Dtype>::Brightness(Dtype* img,const int img_size,const float alpha_rand) {float alpha = 0.0f;Dtype tempPixel = 0.0f;GenerateRandomFloat_range(alpha_rand, &alpha);LOG(INFO) << "Brightness Alpha = " << alpha;int p = 0;for (int h = 0; h < img_size; ++h) {for (int w = 0; w < img_size; ++w) {for (int c = 0; c < 3; ++c) {tempPixel = img[p] * alpha;img[p] = CheckAugmentatedValue(&tempPixel);p++;}}}}



template <typename Dtype>void DataTransformer<Dtype>::Contrast(Dtype* img,const int img_size,const float alpha_rand) {float gray_mean = 0;Dtype tempPixel = 0;for (int h = 0; h < img_size; ++h) {for (int w = 0; w < img_size; ++w) {// BGR to Gray scale image: R -> 0.299, G -> 0.587, B -> 0.114gray_mean += img[0 * img_size*img_size + h*img_size + w] * 0.114f + img[1 * img_size*img_size + h*img_size + w] * 0.587f +img[2 * img_size*img_size + h*img_size + w] * 0.299f;}}gray_mean /= (img_size * img_size);float alpha = 0.0f;GenerateRandomFloat_range(alpha_rand, &alpha);LOG(INFO) << "Contrast Alpha = " << alpha;int p = 0;for (int h = 0; h < img_size; ++h) {for (int w = 0; w < img_size; ++w) {for (int c = 0; c < 3; ++c) {tempPixel = img[p] * alpha + gray_mean * (1.0f - alpha);img[p] = CheckAugmentatedValue(&tempPixel);p++;}}}}