caffe資料層相關學習以及訓練線上資料增廣
阿新 • • 發佈:2019-01-02
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.114 for (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 BGR
template <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.114
gray_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++;
}
}
}
}