Skip to content
This repository has been archived by the owner on Aug 5, 2022. It is now read-only.

An improvement on regression and data reading-revision #215

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions include/caffe/util/io.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,15 @@ bool ReadImageToDatum(const string& filename, const int label,
const int height, const int width, const bool is_color,
const std::string & encoding, Datum* datum);

/*
** overload function ReadImageDatum
** the overloaded function aimed to solve the regression problem
** here is shown to be able to handle unlabeled data, such as float data
*/
bool ReadImageToDatum(const string& filename, const vector<float> labels,
const int height, const int width, const bool is_color,
const std::string & encoding, Datum* datum);

inline bool ReadImageToDatum(const string& filename, const int label,
const int height, const int width, const bool is_color, Datum* datum) {
return ReadImageToDatum(filename, label, height, width, is_color,
Expand Down
74 changes: 25 additions & 49 deletions src/caffe/layers/data_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/


#ifdef USE_OPENCV
#include <opencv2/core/core.hpp>
#endif // USE_OPENCV
#include <stdint.h>
#include <string>

#include <vector>

#include "caffe/data_transformer.hpp"
Expand All @@ -64,25 +65,28 @@ void DataLayer<Dtype>::DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top) {
const int batch_size = this->layer_param_.data_param().batch_size();
// Read a data point, and use it to initialize the top blob.
Datum datum;
datum.ParseFromString(*(reader_.full().peek()));
Datum& datum = *(reader_.full().peek());

// Use data_transformer to infer the expected blob shape from datum.
vector<int> top_shape = this->data_transformer_->InferBlobShape(datum);
this->transformed_data_.Reshape(top_shape);
// Reshape top[0] and prefetch_data according to the batch_size.
top_shape[0] = batch_size;

top[0]->Reshape(top_shape);
for (int i = 0; i < this->PREFETCH_COUNT; ++i) {
this->prefetch_[i].data_.Reshape(top_shape);
}
LOG(INFO) << "output data size: " << top[0]->num() << ","
<< top[0]->channels() << "," << top[0]->height() << ","
<< top[0]->width();
// label
int labelNum = 4;
if (this->output_labels_) {
vector<int> label_shape(1, batch_size);

vector<int> label_shape;
label_shape.push_back(batch_size);
label_shape.push_back(labelNum);
label_shape.push_back(1);
label_shape.push_back(1);
top[1]->Reshape(label_shape);
for (int i = 0; i < this->PREFETCH_COUNT; ++i) {
this->prefetch_[i].label_.Reshape(label_shape);
Expand All @@ -98,23 +102,16 @@ void DataLayer<Dtype>::load_batch(Batch<Dtype>* batch) {
double read_time = 0;
double trans_time = 0;
CPUTimer timer;
CPUTimer trans_timer;
CHECK(batch->data_.count());

#ifndef _OPENMP
CHECK(this->transformed_data_.count());
#endif

// Reshape according to the first datum of each batch
// on single input batches allows for inputs of varying dimension.
const int batch_size = this->layer_param_.data_param().batch_size();
Datum datum;
datum.ParseFromString(*(reader_.full().peek()));
Datum& datum = *(reader_.full().peek());
// Use data_transformer to infer the expected blob shape from datum.
vector<int> top_shape = this->data_transformer_->InferBlobShape(datum);
#ifndef _OPENMP
this->transformed_data_.Reshape(top_shape);
#endif
// Reshape batch according to the batch_size.
top_shape[0] = batch_size;
batch->data_.Reshape(top_shape);
Expand All @@ -125,52 +122,31 @@ void DataLayer<Dtype>::load_batch(Batch<Dtype>* batch) {
if (this->output_labels_) {
top_label = batch->label_.mutable_cpu_data();
}

trans_timer.Start();
#ifdef _OPENMP
#pragma omp parallel if (batch_size > 1)
#pragma omp single nowait
#endif
for (int item_id = 0; item_id < batch_size; ++item_id) {
timer.Start();
// get a datum
string* data = (reader_.full().pop("Waiting for data"));
timer.Stop();
Datum& datum = *(reader_.full().pop("Waiting for data"));
read_time += timer.MicroSeconds();
timer.Start();
// Apply data transformations (mirror, scale, crop...)
int offset = batch->data_.offset(item_id);
this->transformed_data_.set_cpu_data(top_data + offset);
this->data_transformer_->Transform(datum, &(this->transformed_data_));

#ifdef _OPENMP
PreclcRandomNumbers precalculated_rand_numbers;
this->data_transformer_->GenerateRandNumbers(precalculated_rand_numbers);
#pragma omp task firstprivate(offset, precalculated_rand_numbers, data, item_id)
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you remove these code?

{
Datum datum;
datum.ParseFromString(*data);
(reader_.free()).push(data);
// Copy label. We need to copy it before we release datum
if (this->output_labels_) {
top_label[item_id] = datum.label();
int labelNum = 4;
if (this->output_labels_) {
for(int i=0;i<labelNum;i++){
top_label[item_id*labelNum+i] = datum.float_data(i); //read float labels
}
#ifdef _OPENMP
Blob<Dtype> tmp_data;
tmp_data.Reshape(top_shape);
tmp_data.set_cpu_data(top_data + offset);
this->data_transformer_->Transform(datum, &tmp_data,
precalculated_rand_numbers);
#else
this->transformed_data_.set_cpu_data(top_data + offset);
this->data_transformer_->Transform(datum, &(this->transformed_data_));
#endif
}


trans_time += timer.MicroSeconds();

reader_.free().push(const_cast<Datum*>(&datum));
}
trans_timer.Stop();
timer.Stop();
batch_timer.Stop();
// Due to multithreaded nature of transformation,
// time it takes to execute them we get from subtracting
// read batch of images time from total batch read&transform time
trans_time = trans_timer.MicroSeconds() - read_time;
DLOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << " ms.";
DLOG(INFO) << " Read time: " << read_time / 1000 << " ms.";
DLOG(INFO) << "Transform time: " << trans_time / 1000 << " ms.";
Expand Down
19 changes: 19 additions & 0 deletions src/caffe/util/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,25 @@ bool ReadImageToDatum(const string& filename, const int label,
}
}

/*
** here is the realization of reloaded function
*/
bool ReadImageToDatum(const string& filename, const vector<float> labels,
const int height, const int width, const bool is_color,
const std::string & encoding, Datum* datum) {
cv::Mat cv_img = ReadImageToCVMat(filename, height, width, is_color);
if (cv_img.data) {
CVMatToDatum(cv_img, datum);
for (int i = 0; i < labels.size(); ++i)
{
datum->add_float_data(labels.at(i));
}
return true;
} else {
return false;
}
}

void GetImageSize(const string& filename, int* height, int* width) {
cv::Mat cv_img = cv::imread(filename);
if (!cv_img.data) {
Expand Down