目录
一、Caffe pooling layer修改(添加ceil mode属性)
Step1:pooling_layer.hpp文件
- 找到属性定义并添加bool ceil_mode_;
Step2:pooling_layer.cpp文件
- 找到相应参数解析处添加代码
ceil_mode_ = param.ceil_mode()
- 找到相应计算处根据个人需求添加代码
if ceil_mode_ ...
else ...
Step3:caffe.proto文件
- 找到pooling layer相应属性列表,添加
optional bool ceil_mode = 13 [default=true]
二、Caffe自定义图像处理
Step1:data_transformer.cpp修改
- …\caffe-master\src\caffe中data_transformer.cpp文件找到如下两个函数并修改
- 此函数主要是使用caffe Datalayer时调用的预处理函数
void DataTransformer<Dtype>::Transform(const Datum& datum, Dtype* transformed_data)
/// … ///之间为新写的代码,下方是被注释的原有代码
// -------------------------------------新代码--------------------------------------------------
Dtype mean_datum_element;
int mean_top_index, mean_data_index;
float pixel_sum_value = 0.0, global_mean = 0.0;
for (int c = 0; c < datum_channels; ++c)
{
for (int h = 0; h < height; ++h)
{
for (int w = 0; w < width; ++w)
{
mean_data_index = (c * datum_height + h_off + h) * datum_width + w_off + w;
mean_top_index = (c * height + h) * width + w;
if (has_uint8) {
mean_datum_element =
static_cast<Dtype>(static_cast<uint8_t>(data[mean_data_index]));
}
else {
mean_datum_element = datum.float_data(mean_data_index);
}
pixel_sum_value += mean_datum_element;
}
}
}
global_mean = pixel_sum_value / (datum_channels * height * width) * 1.0;
//LOG(INFO) << "Using datum to load data ----------------------------------------------------";
Dtype datum_element;
int top_index, data_index;
// 遍历像素点
for (int c = 0; c < datum_channels; ++c)
{
for (int h = 0; h < height; ++h)
{
for (int w = 0; w < width; ++w)
{
data_index = (c * datum_height + h_off + h) * datum_width + w_off + w;
top_index = (c * height + h) * width + w;
if (has_uint8) {
datum_element =
static_cast<Dtype>(static_cast<uint8_t>(data[data_index]));
} else {
datum_element = datum.float_data(data_index);
}
transformed_data[top_index] = (datum_element * 1.0 - global_mean) * scale;
}
}
}
//
// ----------------------------------------------原有代码---------------------------------
//Dtype datum_element;
//int top_index, data_index;
//for (int c = 0; c < datum_channels; ++c) {
// for (int h = 0; h < height; ++h) {
// for (int w = 0; w < width; ++w) {
// data_index = (c * datum_height + h_off + h) * datum_width + w_off + w;
// if (do_mirror) {
// top_index = (c * height + h) * width + (width - 1 - w);
// } else {
// top_index = (c * height + h) * width + w;
// }
// if (has_uint8) {
// datum_element =
// static_cast<Dtype>(static_cast<uint8_t>(data[data_index]));
// } else {
// datum_element = datum.float_data(data_index);
// }
// if (has_mean_file) {
// transformed_data[top_index] =
// (datum_element - mean[data_index]) * scale;
// } else {
// if (has_mean_values) {
// transformed_data[top_index] =
// (datum_element - mean_values_[c]) * scale;
// } else {
// transformed_data[top_index] = datum_element * scale;
// }
// }
// }
// }
//}
- 此函数主要是使用caffe imagedatalayer时调用的预处理函数
void DataTransformer<Dtype>::Transform(const cv::Mat& cv_img, Blob<Dtype>* transformed_blob)
//
// ----------------------------------------------新代码---------------------------------
cv::Scalar channel_mean = cv::mean(cv_cropped_img);
float global_mean = 0.0, mean_sum_value = 0.0;
for (int i = 0; i < cv_cropped_img.channels(); i++)
{
mean_sum_value += channel_mean[i];
}
global_mean = mean_sum_value / img_channels;
//LOG(INFO) << "Using opencv to load data ----------------------------------------------";
Dtype* transformed_data = transformed_blob->mutable_cpu_data();
int top_index;
// 遍历像素点
for (int h = 0; h < height; ++h)
{
const uchar* ptr = cv_cropped_img.ptr<uchar>(h);
int img_index = 0;
for (int w = 0; w < width; ++w)
{
for (int c = 0; c < img_channels; ++c)
{
top_index = (c * height + h) * width + w;
Dtype pixel = static_cast<Dtype>(ptr[img_index++]);
transformed_data[top_index] = (pixel * 1.0 - global_mean) * scale;
}
}
}
/
// ------------------------------------原有代码--------------------------------------------
//Dtype* transformed_data = transformed_blob->mutable_cpu_data();
//int top_index;
//for (int h = 0; h < height; ++h) {
// const uchar* ptr = cv_cropped_img.ptr<uchar>(h);
// int img_index = 0;
// for (int w = 0; w < width; ++w) {
// for (int c = 0; c < img_channels; ++c) {
// if (do_mirror) {
// top_index = (c * height + h) * width + (width - 1 - w);
// } else {
// top_index = (c * height + h) * width + w;
// }
// // int top_index = (c * height + h) * width + w;
// Dtype pixel = static_cast<Dtype>(ptr[img_index++]);
// if (has_mean_file) {
// int mean_index = (c * img_height + h_off + h) * img_width + w_off + w;
// transformed_data[top_index] =
// (pixel - mean[mean_index]) * scale;
// } else {
// if (has_mean_values) {
// transformed_data[top_index] =
// (pixel - mean_values_[c]) * scale;
// } else {
// transformed_data[top_index] = pixel * scale;
// }
// }
// }
// }
//}
Step2:总结
- 基本就是找到数据预处理操作的地方,修改 / 重写相应代码
- 同样的,也可以将预处理做完再进行数据转换,不需要修改代码,看个人喜好
- resize操作尽可能提前做完,不然拖慢效果拔群
- 尽可能减少I/O操作,拖慢效果拔群