#include <vector>
#include <iostream> // NOLINT(readability/streams)
#include <fstream> // NOLINT(readability/streams)
+#include <utility>
#include "caffe/layer.hpp"
#include "caffe/util/io.hpp"
#include "caffe/util/rng.hpp"
#include "caffe/vision_layers.hpp"
+using std::iterator;
using std::string;
using std::pair;
DLOG(INFO) << "Restarting data prefetching from start.";
layer->lines_id_ = 0;
if (layer->layer_param_.image_data_param().shuffle()) {
- std::random_shuffle(layer->lines_.begin(), layer->lines_.end());
+ layer->ShuffleImages();
}
}
}
if (this->layer_param_.image_data_param().shuffle()) {
// randomly shuffle data
LOG(INFO) << "Shuffling data";
- std::random_shuffle(lines_.begin(), lines_.end());
+ const unsigned int prefetch_rng_seed = caffe_rng_rand();
+ prefetch_rng_.reset(new Caffe::RNG(prefetch_rng_seed));
+ ShuffleImages();
}
LOG(INFO) << "A total of " << lines_.size() << " images.";
template <typename Dtype>
void ImageDataLayer<Dtype>::CreatePrefetchThread() {
phase_ = Caffe::phase();
- const bool prefetch_needs_rand = (phase_ == Caffe::TRAIN) &&
- (this->layer_param_.data_param().mirror() ||
- this->layer_param_.data_param().crop_size());
+ const bool prefetch_needs_rand =
+ this->layer_param_.image_data_param().shuffle() ||
+ ((phase_ == Caffe::TRAIN) &&
+ (this->layer_param_.image_data_param().mirror() ||
+ this->layer_param_.image_data_param().crop_size()));
if (prefetch_needs_rand) {
const unsigned int prefetch_rng_seed = caffe_rng_rand();
prefetch_rng_.reset(new Caffe::RNG(prefetch_rng_seed));
}
template <typename Dtype>
+void ImageDataLayer<Dtype>::ShuffleImages() {
+ const int num_images = lines_.size();
+ for (int i = 0; i < num_images; ++i) {
+ const int max_rand_index = num_images - i;
+ const int rand_index = PrefetchRand() % max_rand_index;
+ pair<string, int> item = lines_[rand_index];
+ lines_.erase(lines_.begin() + rand_index);
+ lines_.push_back(item);
+ }
+}
+
+template <typename Dtype>
void ImageDataLayer<Dtype>::JoinPrefetchThread() {
CHECK(!pthread_join(thread_, NULL)) << "Pthread joining failed.";
}
#include <iostream> // NOLINT(readability/streams)
#include <fstream> // NOLINT(readability/streams)
+#include <map>
#include <string>
#include <vector>
#include "caffe/proto/caffe.pb.h"
#include "caffe/test/test_caffe_main.hpp"
+using std::map;
using std::string;
namespace caffe {
ImageDataLayerTest()
: blob_top_data_(new Blob<Dtype>()),
blob_top_label_(new Blob<Dtype>()),
- filename(NULL) {}
+ filename_(new string(tmpnam(NULL))),
+ seed_(1701) {}
virtual void SetUp() {
blob_top_vec_.push_back(blob_top_data_);
blob_top_vec_.push_back(blob_top_label_);
+ Caffe::set_random_seed(seed_);
// Create a Vector of files with labels
- filename = tmpnam(NULL); // get temp name
- std::ofstream outfile(filename, std::ofstream::out);
- LOG(INFO) << "Using temporary file " << filename;
+ std::ofstream outfile(filename_->c_str(), std::ofstream::out);
+ LOG(INFO) << "Using temporary file " << *filename_;
for (int i = 0; i < 5; ++i) {
outfile << "examples/images/cat.jpg " << i;
}
delete blob_top_label_;
}
- char* filename;
+ int seed_;
+ shared_ptr<string> filename_;
Blob<Dtype>* const blob_top_data_;
Blob<Dtype>* const blob_top_label_;
vector<Blob<Dtype>*> blob_bottom_vec_;
LayerParameter param;
ImageDataParameter* image_data_param = param.mutable_image_data_param();
image_data_param->set_batch_size(5);
- image_data_param->set_source(this->filename);
+ image_data_param->set_source(this->filename_->c_str());
image_data_param->set_shuffle(false);
ImageDataLayer<TypeParam> layer(param);
layer.SetUp(this->blob_bottom_vec_, &this->blob_top_vec_);
LayerParameter param;
ImageDataParameter* image_data_param = param.mutable_image_data_param();
image_data_param->set_batch_size(5);
- image_data_param->set_source(this->filename);
+ image_data_param->set_source(this->filename_->c_str());
image_data_param->set_new_height(256);
image_data_param->set_new_width(256);
image_data_param->set_shuffle(false);
LayerParameter param;
ImageDataParameter* image_data_param = param.mutable_image_data_param();
image_data_param->set_batch_size(5);
- image_data_param->set_source(this->filename);
+ image_data_param->set_source(this->filename_->c_str());
image_data_param->set_shuffle(true);
ImageDataLayer<TypeParam> layer(param);
layer.SetUp(this->blob_bottom_vec_, &this->blob_top_vec_);
// Go through the data twice
for (int iter = 0; iter < 2; ++iter) {
layer.Forward(this->blob_bottom_vec_, &this->blob_top_vec_);
+ map<TypeParam, int> values_to_indices;
+ int num_in_order = 0;
for (int i = 0; i < 5; ++i) {
- EXPECT_GE(this->blob_top_label_->cpu_data()[i], 0);
- EXPECT_LE(this->blob_top_label_->cpu_data()[i], 5);
+ TypeParam value = this->blob_top_label_->cpu_data()[i];
+ // Check that the value has not been seen already (no duplicates).
+ EXPECT_EQ(values_to_indices.find(value), values_to_indices.end());
+ values_to_indices[value] = i;
+ num_in_order += (value == TypeParam(i));
}
+ EXPECT_EQ(5, values_to_indices.size());
+ EXPECT_GT(5, num_in_order);
}
}