void DataLayer<Dtype>::InternalThreadEntry() {
  CPUTimer batch_timer;
  batch_timer.Start();
  double read_time = 0;
  double trans_time = 0;
  CPUTimer timer;
  CHECK(this->prefetch_data_.count());
  CHECK(this->transformed_data_.count());

  // 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(cursor_->value());
  // 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 prefetch_data according to the batch_size.
  top_shape[0] = batch_size;
  this->prefetch_data_.Reshape(top_shape);

  Dtype* top_data = this->prefetch_data_.mutable_cpu_data();
  Dtype* top_label = NULL;  // suppress warnings about uninitialized variables

  if (this->output_labels_) {
    top_label = this->prefetch_label_.mutable_cpu_data();
  }
  timer.Start();
  for (int item_id = 0; item_id < batch_size; ++item_id) {
    // get a datum
    Datum datum;
    datum.ParseFromString(cursor_->value());
    read_time += timer.MicroSeconds();
    timer.Start();
    // Apply data transformations (mirror, scale, crop...)
    int offset = this->prefetch_data_.offset(item_id);
    this->transformed_data_.set_cpu_data(top_data + offset);
    this->data_transformer_->Transform(datum, &(this->transformed_data_));
    // Copy label.
    if (this->output_labels_) {
      top_label[item_id] = datum.label();
    }
    trans_time += timer.MicroSeconds();
    timer.Start();
    // go to the next item.
    cursor_->Next();
    if (!cursor_->valid()) {
      DLOG(INFO) << "Restarting data prefetching from start.";
      cursor_->SeekToFirst();
    }
  }
  timer.Stop();
  batch_timer.Stop();
  DLOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << " ms.";
  DLOG(INFO) << "     Read time: " << read_time / 1000 << " ms.";
  DLOG(INFO) << "Transform time: " << trans_time / 1000 << " ms.";
}
int main(int argc, char** argv) {
	::google::InitGoogleLogging(argv[0]);
	if (argc != 3) {
		LOG(ERROR)<< "Usage: demo_compute_image_mean input_leveldb output_file";
		return(0);
	}

	leveldb::DB* db;
	leveldb::Options options;
	options.create_if_missing = false;

	LOG(INFO) << "Opening leveldb " << argv[1];
	leveldb::Status status = leveldb::DB::Open(options, argv[1], &db);
	CHECK(status.ok()) << "Failed to open leveldb " << argv[1];

	leveldb::ReadOptions read_options;
	read_options.fill_cache = false;
	leveldb::Iterator* it = db->NewIterator(read_options);
	it->SeekToFirst();
	Datum datum;
	BlobProto sum_blob;
	int count = 0;
	datum.ParseFromString(it->value().ToString());
	sum_blob.set_num(1);
	sum_blob.set_channels(datum.channels());
	sum_blob.set_height(datum.height());
	sum_blob.set_width(datum.width());
	const int data_size = datum.channels() * datum.height() * datum.width();
	for (int i = 0; i < datum.data().size(); ++i) {
		sum_blob.add_data(0.);
	}
	LOG(INFO) << "Starting Iteration";
	for (it->SeekToFirst(); it->Valid(); it->Next()) {
		// just a dummy operation
		datum.ParseFromString(it->value().ToString());
		const string& data = datum.data();
		CHECK_EQ(data.size(), data_size)<< "Incorrect data field size " << data.size();
		for (int i = 0; i < data.size(); ++i) {
			sum_blob.set_data(i, sum_blob.data(i) + (uint8_t) data[i]);
		}
		++count;
		if (count % 10000 == 0) {
			LOG(ERROR)<< "Processed " << count << " files.";
			if (count == 100000) break;
		}
	}
	for (int i = 0; i < sum_blob.data_size(); ++i) {
		sum_blob.set_data(i, sum_blob.data(i) / count);
	}
	// Write to disk
	LOG(INFO) << "Write to " << argv[2];
	WriteProtoToBinaryFile(sum_blob, argv[2]);

	delete db;
	return 0;
}
Exemple #3
0
void load_batch(int batch_size, int crop_w, int crop_h,
                Image<float> &data, Image<int> &labels,
                db::Cursor* cur) {

    assert(data.extent(0) == crop_w);
    assert(data.extent(1) == crop_h);
    assert(data.extent(3) == batch_size);
    assert(labels.extent(0) == batch_size);

    for (int n = 0; n < batch_size; n++) {
        Datum datum;
        datum.ParseFromString(cur->value());

        cv::Mat img;
        img = DatumToCVMat(datum);

        assert(crop_w <= img.rows);
        assert(crop_h <= img.cols);

        labels(n) = datum.label();

        for (int h = 0; h < crop_h; h++)
            for (int w = 0; w < crop_w; w++)
                for (int c = 0; c < 3; c++)
                    data(w, h, c, n) = (float)img.at<cv::Vec3b>(h, w)[c];

        cur->Next();
    }
}
Exemple #4
0
void DataLayer<Dtype>::DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  // Initialize DB
  db_.reset(db::GetDB(this->layer_param_.data_param().backend()));
  db_->Open(this->layer_param_.data_param().source(), db::READ);
  cursor_.reset(db_->NewCursor());

  if (this->layer_param_.data_param().rand_skip() ||
      this->layer_param_.data_param().skip()) {
    unsigned int skip;
    // Check if we should randomly skip a few data points
    if (this->layer_param_.data_param().rand_skip()) {
      skip = caffe_rng_rand() %
                          this->layer_param_.data_param().rand_skip();
    } else {
      skip = this->layer_param_.data_param().skip();
    }
    LOG(INFO) << "Skipping first " << skip << " data points.";
    while (skip-- > 0) {
      cursor_->Next();
    }
  }

  // Read a data point, and use it to initialize the top blob.
  Datum datum;
  datum.ParseFromString(cursor_->value());

  bool force_color = this->layer_param_.data_param().force_encoded_color();
  if ((force_color && DecodeDatum(&datum, true)) ||
      DecodeDatumNative(&datum)) {
    LOG(INFO) << "Decoding Datum";
  }
  // image
  int crop_size = this->layer_param_.transform_param().crop_size();
  if (crop_size > 0) {
    top[0]->Reshape(this->layer_param_.data_param().batch_size(),
        datum.channels(), crop_size, crop_size);
    this->prefetch_data_.Reshape(this->layer_param_.data_param().batch_size(),
        datum.channels(), crop_size, crop_size);
    this->transformed_data_.Reshape(1, datum.channels(), crop_size, crop_size);
  } else {
    top[0]->Reshape(
        this->layer_param_.data_param().batch_size(), datum.channels(),
        datum.height(), datum.width());
    this->prefetch_data_.Reshape(this->layer_param_.data_param().batch_size(),
        datum.channels(), datum.height(), datum.width());
    this->transformed_data_.Reshape(1, datum.channels(),
      datum.height(), datum.width());
  }
  LOG(INFO) << "output data size: " << top[0]->num() << ","
      << top[0]->channels() << "," << top[0]->height() << ","
      << top[0]->width();
  // label
  if (this->output_labels_) {
    vector<int> label_shape(1, this->layer_param_.data_param().batch_size());
    top[1]->Reshape(label_shape);
    this->prefetch_label_.Reshape(label_shape);
  }
}
vector<double> GetChannelMean(scoped_ptr<db::Cursor>& cursor)
{
	vector<double> meanv(3, 0);

	int count = 0;
	LOG(INFO) << "Starting Iteration";
	while (cursor->valid()) {
		Datum datum;
		datum.ParseFromString(cursor->value());
		DecodeDatumNative(&datum);

		const std::string& data = datum.data();
		int w = datum.width(), h = datum.height();
		int ch = datum.channels();
		int dim = w*h;
		double chmean[3] = { 0,0,0 };
		for (int i = 0; i < ch;i++)
		{
			int chstart = i*dim;
			for (int j = 0; j < dim;j++)
				chmean[i] += (uint8_t)data[chstart+j];
			chmean[i] /= dim;
		}
		if (ch == 1)
		{
			meanv[0] += chmean[0];
			meanv[1] += chmean[0];
			meanv[2] += chmean[0];
		}
		else
		{
			meanv[0] += chmean[0];
			meanv[1] += chmean[1];
			meanv[2] += chmean[2];
		}
		
		++count;
		if (count % 10000 == 0) {
			LOG(INFO) << "Processed " << count << " files.";
		}
		cursor->Next();
	}

	if (count % 10000 != 0) {
		LOG(INFO) << "Processed " << count << " files.";
	}

	for (int c = 0; c < 3; ++c) {
		LOG(INFO) << "mean_value channel [" << c << "]:" << meanv[c] / count;
	}

	return meanv;
}
void DataReader::Body::read_one(db::Cursor* cursor, QueuePair* qp) {
  Datum* datum = qp->free_.pop();
  // TODO deserialize in-place instead of copy?
  datum->ParseFromString(cursor->value());
  qp->full_.push(datum);

  // go to the next iter
  cursor->Next();
  if (!cursor->valid()) {
    DLOG(INFO) << "Restarting data prefetching from start.";
    cursor->SeekToFirst();
  }
}
Exemple #7
0
void DataReader::Body::read_one(db::Cursor* cursor, db::Transaction* dblt, QueuePair* qp) {
  Datum* datum = qp->free_.pop();
  // TODO deserialize in-place instead of copy?
  datum->ParseFromString(cursor->value());
  if (dblt != NULL) {
    string labels;
    CHECK_EQ(dblt->Get(cursor->key(), labels), 0);
    Datum labelDatum;
    labelDatum.ParseFromString(labels);
//    datum->MergeFrom(labelDatum);
    datum->set_channels(datum->channels() + labelDatum.channels());
    datum->mutable_float_data()->MergeFrom(labelDatum.float_data());
    datum->mutable_data()->append(labelDatum.data());
  }
  qp->full_.push(datum);

  // go to the next iter
  cursor->Next();
  if (!cursor->valid()) {
    DLOG(INFO) << "Restarting data prefetching from start.";
    cursor->SeekToFirst();
  }
}
TYPED_TEST(DBTest, TestKeyValue) {
  unique_ptr<db::DB> db(db::GetDB(TypeParam::backend));
  db->Open(this->source_, db::READ);
  unique_ptr<db::Cursor> cursor(db->NewCursor());
  EXPECT_TRUE(cursor->valid());
  string key = cursor->key();
  Datum datum;
  datum.ParseFromString(cursor->value());
  EXPECT_EQ(key, "cat.jpg");
  EXPECT_EQ(datum.channels(), 3);
  EXPECT_EQ(datum.height(), 360);
  EXPECT_EQ(datum.width(), 480);
  cursor->Next();
  EXPECT_TRUE(cursor->valid());
  key = cursor->key();
  datum.ParseFromString(cursor->value());
  EXPECT_EQ(key, "fish-bike.jpg");
  EXPECT_EQ(datum.channels(), 3);
  EXPECT_EQ(datum.height(), 323);
  EXPECT_EQ(datum.width(), 481);
  cursor->Next();
  EXPECT_FALSE(cursor->valid());
}
Exemple #9
0
  void GetLabelsKeysMap(map<int, vector<MDB_val> >* labels_keys, vector<int>* labels) {
    LMDBCursor::SeekToFirst();
    labels_keys->clear();
    while (valid()) {
      Datum datum;
      datum.ParseFromString(LMDBCursor::value());
      int label = datum.label();     
      (*labels_keys)[label].push_back(mdb_key_);     
      LMDBCursor::Next();
    }

    for(map<int,vector<MDB_val> >::iterator it = labels_keys->begin(); it != labels_keys->end(); ++it) {
	labels->push_back(it->first);
    } 
  }
Exemple #10
0
void DataDrivingLayer<Dtype>::DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  // Initialize DB
  leveldb::DB* db_temp;
  leveldb::Options options;
  options.max_open_files = 100;
  options.create_if_missing = false;
  LOG(INFO) << "Opening leveldb " << this->layer_param_.data_driving_param().source();
  leveldb::Status status = leveldb::DB::Open(
      options, this->layer_param_.data_driving_param().source(), &db_temp);
  CHECK(status.ok()) << "Failed to open leveldb "
                     << this->layer_param_.data_driving_param().source() << std::endl
                     << status.ToString();
  db_.reset(db_temp);

  // Read a data point, to initialize the prefetch and top blobs.
  string value;
  const int kMaxKeyLength = 256;
  char key_cstr[kMaxKeyLength];
  srand((int)time(0)); 

  snprintf(key_cstr, kMaxKeyLength, "%08d", 1);
  db_->Get(leveldb::ReadOptions(), string(key_cstr), &value);
  Datum datum;
  datum.ParseFromString(value);

  int batch_size=this->layer_param_.data_driving_param().batch_size();
  // image 
  top[0]->Reshape(batch_size, datum.channels(), datum.height(), datum.width());
  this->prefetch_data_.Reshape(batch_size, datum.channels(), datum.height(), datum.width());

  LOG(INFO) << "output data size: " << top[0]->num() << ","
      << top[0]->channels() << "," << top[0]->height() << ","
      << top[0]->width();

  // label
  top[1]->Reshape(batch_size, 1, 1, para_dim);
  this->prefetch_label_.Reshape(batch_size, 1, 1, para_dim);

  const string& mean_file = this->layer_param_.data_driving_param().mean_file();
  LOG(INFO) << "Loading mean file from: " << mean_file;
  BlobProto blob_proto;
  ReadProtoFromBinaryFileOrDie(mean_file.c_str(), &blob_proto);
  data_mean_.FromProto(blob_proto);
}
Exemple #11
0
// 从数据库中获取一个数据
void DataReader::Body::read_one(db::Cursor* cursor, QueuePair* qp) {
    // 从QueuePair中的free_队列pop出一个  
  Datum* datum = qp->free_.pop();
  // TODO deserialize in-place instead of copy?
   // 然后解析cursor中的值  
  datum->ParseFromString(cursor->value());

  // 然后压入QueuePair中的full_队列  
  qp->full_.push(datum);

  // go to the next iter
  // 游标指向下一个  
  cursor->Next();
  if (!cursor->valid()) {
    DLOG(INFO) << "Restarting data prefetching from start.";
    // 如果游标指向的位置已经无效了则指向第一个位置  
    cursor->SeekToFirst();
  }
}
Exemple #12
0
void DataLayer<Dtype>::DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  // LOG(INFO)<<"jq data_layers setup";
  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 = *(reader_.full().peek());
  db_.reset(db::GetDB(this->layer_param_.data_param().backend()));
  db_->Open(this->layer_param_.data_param().source(), db::WRITE);
  // LOG(INFO)<<"jq Transaction 1";
  // scoped_ptr<db::Transaction> txn(db_->NewTransaction());
  // LOG(INFO)<<"jq Transaction 2";
  cursor_.reset(db_->NewCursor());
  // LOG(INFO)<<"jq Transaction 3";
  // scoped_ptr<db::Transaction> txn2(db_->NewTransaction());
  // LOG(INFO)<<"jq Transaction 4";
  Datum datum;
  datum.ParseFromString(cursor_->value());
  this->use_data_.Reshape(1,1,1,batch_size+ batch_size + 1);
  // 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);
  this->jqbatch_shape = this->data_transformer_->InferBlobShape(datum);
  this->jqbatch_shape[0] = batch_size;
  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
  if (this->output_labels_) {
    vector<int> label_shape(1, batch_size);
    top[1]->Reshape(label_shape);
    for (int i = 0; i < this->PREFETCH_COUNT; ++i) {
      this->prefetch_[i].label_.Reshape(label_shape);
    }
  }
}
void DataLayer<Dtype>::DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  // Initialize DB
  db_.reset(db::GetDB(this->layer_param_.data_param().backend()));
  db_->Open(this->layer_param_.data_param().source(), db::READ);
  cursor_.reset(db_->NewCursor());

  // Check if we should randomly skip a few data points
  if (this->layer_param_.data_param().rand_skip()) {
    unsigned int skip = caffe_rng_rand() %
                        this->layer_param_.data_param().rand_skip();
    LOG(INFO) << "Skipping first " << skip << " data points.";
    while (skip-- > 0) {
      cursor_->Next();
    }
  }
  // Read a data point, to initialize the prefetch and top blobs.
  Datum datum;
  datum.ParseFromString(cursor_->value());
  // 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] = this->layer_param_.data_param().batch_size();
  this->prefetch_data_.Reshape(top_shape);
  top[0]->ReshapeLike(this->prefetch_data_);

  LOG(INFO) << "output data size: " << top[0]->num() << ","
      << top[0]->channels() << "," << top[0]->height() << ","
      << top[0]->width();
  // label
  if (this->output_labels_) {
    vector<int> label_shape(1, this->layer_param_.data_param().batch_size());
    top[1]->Reshape(label_shape);
    this->prefetch_label_.Reshape(label_shape);
  }
}
bool MostCV::LevelDBReader::GetNextEntry(string &key, vector<double> &retVec, int &label) {
  if (!database_iter_->Valid())
    return false;

  Datum datum;
  datum.clear_float_data();
  datum.clear_data();
  datum.ParseFromString(database_iter_->value().ToString());

  key = database_iter_->key().ToString();
  label = datum.label();

  int expected_data_size = std::max<int>(datum.data().size(), datum.float_data_size());
  const int datum_volume_size = datum.channels() * datum.height() * datum.width();
  if (expected_data_size != datum_volume_size) {
    cout << "Something wrong in saved data.";
    assert(false);
  }

  retVec.resize(datum_volume_size);

  const string& data = datum.data();
  if (data.size() != 0) {
    // Data stored in string, e.g. just pixel values of 196608 = 256 * 256 * 3
    for (int i = 0; i < datum_volume_size; ++i)
      retVec[i] = data[i];
  } else {
    // Data stored in real feature vector such as 4096 from feature extraction
    for (int i = 0; i < datum_volume_size; ++i)
      retVec[i] = datum.float_data(i);
  }

  database_iter_->Next();
  ++record_idx_;

  return true;
}
void DataLstmTrainHistLayer<Dtype>::DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  // Initialize DB
  leveldb::DB* db_temp;
  leveldb::Options options;
  options.max_open_files = 100;
  options.create_if_missing = false;
  LOG(INFO) << "Opening leveldb " << this->layer_param_.data_lstm_train_hist_param().source();
  leveldb::Status status = leveldb::DB::Open(
      options, this->layer_param_.data_lstm_train_hist_param().source(), &db_temp);
  CHECK(status.ok()) << "Failed to open leveldb "
                     << this->layer_param_.data_lstm_train_hist_param().source() << std::endl
                     << status.ToString();
  db_.reset(db_temp);

  // Read a data point, to initialize the prefetch and top blobs.
  string value;
  const int kMaxKeyLength = 256;
  char key_cstr[kMaxKeyLength];
  srand((int)time(0)); 

  snprintf(key_cstr, kMaxKeyLength, "%08d", 1);
  db_->Get(leveldb::ReadOptions(), string(key_cstr), &value);
  Datum datum;
  datum.ParseFromString(value);

  const int ind_seq_num=this->layer_param_.data_lstm_train_hist_param().sequence_num();

  buffer_key.clear();
  buffer_marker.clear();
  buffer_total.clear();
  hist_blob.clear();

  for (int i=0;i<ind_seq_num;i++) {
     int tmp=random(total_frames)+1;
     buffer_key.push_back(tmp);
     buffer_marker.push_back(0);
     buffer_total.push_back(0);
     for (int j = 0; j < para_dim; ++j) 
         hist_blob.push_back(0);
  }

  int batch_size=this->layer_param_.data_lstm_train_hist_param().sequence_size()*ind_seq_num;
  // image 
  top[0]->Reshape(batch_size, datum.channels(), datum.height(), datum.width());
  this->prefetch_data_.Reshape(batch_size, datum.channels(), datum.height(), datum.width());

  LOG(INFO) << "output data size: " << top[0]->num() << ","
      << top[0]->channels() << "," << top[0]->height() << ","
      << top[0]->width();

  // label
  top[1]->Reshape(batch_size, 1, 1, para_dim);
  this->prefetch_label_.Reshape(batch_size, 1, 1, para_dim);

  // hist
  top[2]->Reshape(batch_size, 1, 1, para_dim);
  this->prefetch_hist_.Reshape(batch_size, 1, 1, para_dim);

  // marker
  top[3]->Reshape(batch_size, 1, 1, 1);
  this->prefetch_marker_.Reshape(batch_size, 1, 1, 1);

  const string& mean_file = this->layer_param_.data_lstm_train_hist_param().mean_file();
  LOG(INFO) << "Loading mean file from: " << mean_file;
  BlobProto blob_proto;
  ReadProtoFromBinaryFileOrDie(mean_file.c_str(), &blob_proto);
  data_mean_.FromProto(blob_proto);
}
void DataLstmTrainHistLayer<Dtype>::InternalThreadEntry() {
  CPUTimer batch_timer;
  batch_timer.Start();
  double read_time = 0;
  double trans_time = 0;
  CPUTimer timer;
  CHECK(this->prefetch_data_.count());

  Datum datum;
  Dtype* top_data = this->prefetch_data_.mutable_cpu_data();
  Dtype* top_label = this->prefetch_label_.mutable_cpu_data();
  Dtype* top_hist = this->prefetch_hist_.mutable_cpu_data();
  Dtype* top_marker = this->prefetch_marker_.mutable_cpu_data();

  // datum scales
  const int size = resize_height*resize_width*3;
  const Dtype* mean = this->data_mean_.mutable_cpu_data();

  string value;
  const int kMaxKeyLength = 256;
  char key_cstr[kMaxKeyLength];
  int key;

  const int sequence_size = this->layer_param_.data_lstm_train_hist_param().sequence_size();
  const int ind_seq_num=this->layer_param_.data_lstm_train_hist_param().sequence_num();
  const int interval=this->layer_param_.data_lstm_train_hist_param().interval();
  int item_id;

  for (int time_id = 0; time_id < sequence_size; ++time_id) {
     for (int seq_id = 0; seq_id < ind_seq_num; ++seq_id) {
        item_id=time_id*ind_seq_num+seq_id;
        timer.Start();
        // get a blob

        key=buffer_key[seq_id];  // MUST be changed according to the size of the training set

        snprintf(key_cstr, kMaxKeyLength, "%08d", key);
        db_->Get(leveldb::ReadOptions(), string(key_cstr), &value);
        datum.ParseFromString(value);
        const string& data = datum.data();

        read_time += timer.MicroSeconds();
        timer.Start();

        for (int j = 0; j < size; ++j) {
           Dtype datum_element = static_cast<Dtype>(static_cast<uint8_t>(data[j]));
           top_data[item_id * size + j] = (datum_element - mean[j]);
        }

        for (int j = 0; j < para_dim; ++j) { 
           top_label[item_id * para_dim + j] = datum.float_data(j); 
        }

        top_marker[item_id] = datum.float_data(para_dim);

        if (buffer_marker[seq_id] == 0) {
            top_marker[item_id] = 0;   
            buffer_marker[seq_id] = 1;
        }

        //////////////////////////////////// for hist
        if (top_marker[item_id] < 0.5) {
           for (int j = 0; j < para_dim; ++j)
               top_hist[item_id * para_dim + j] = 0; 
        } else {
           if (time_id == 0) {
              top_hist[item_id * para_dim + 0] = hist_blob[seq_id * para_dim + 0]/1.1+0.5;
              top_hist[item_id * para_dim + 1] = hist_blob[seq_id * para_dim + 1]*0.17778+1.34445;
              top_hist[item_id * para_dim + 2] = hist_blob[seq_id * para_dim + 2]*0.14545+0.39091;
              top_hist[item_id * para_dim + 3] = hist_blob[seq_id * para_dim + 3]*0.17778-0.34445;
              top_hist[item_id * para_dim + 4] = hist_blob[seq_id * para_dim + 4]/95.0+0.12;
              top_hist[item_id * para_dim + 5] = hist_blob[seq_id * para_dim + 5]/95.0+0.12;
              top_hist[item_id * para_dim + 6] = hist_blob[seq_id * para_dim + 6]*0.14545+1.48181;
              top_hist[item_id * para_dim + 7] = hist_blob[seq_id * para_dim + 7]*0.16+0.98;
              top_hist[item_id * para_dim + 8] = hist_blob[seq_id * para_dim + 8]*0.16+0.02;
              top_hist[item_id * para_dim + 9] = hist_blob[seq_id * para_dim + 9]*0.14545-0.48181;
              top_hist[item_id * para_dim + 10] = hist_blob[seq_id * para_dim + 10]/95.0+0.12;
              top_hist[item_id * para_dim + 11] = hist_blob[seq_id * para_dim + 11]/95.0+0.12;
              top_hist[item_id * para_dim + 12] = hist_blob[seq_id * para_dim + 12]/95.0+0.12;
              top_hist[item_id * para_dim + 13] = hist_blob[seq_id * para_dim + 13]*0.6+0.2;
           } else {
              int pre_id=(time_id-1)*ind_seq_num+seq_id;
              top_hist[item_id * para_dim + 0] = top_label[pre_id * para_dim + 0]/1.1+0.5;
              top_hist[item_id * para_dim + 1] = top_label[pre_id * para_dim + 1]*0.17778+1.34445;
              top_hist[item_id * para_dim + 2] = top_label[pre_id * para_dim + 2]*0.14545+0.39091;
              top_hist[item_id * para_dim + 3] = top_label[pre_id * para_dim + 3]*0.17778-0.34445;
              top_hist[item_id * para_dim + 4] = top_label[pre_id * para_dim + 4]/95.0+0.12;
              top_hist[item_id * para_dim + 5] = top_label[pre_id * para_dim + 5]/95.0+0.12;
              top_hist[item_id * para_dim + 6] = top_label[pre_id * para_dim + 6]*0.14545+1.48181;
              top_hist[item_id * para_dim + 7] = top_label[pre_id * para_dim + 7]*0.16+0.98;
              top_hist[item_id * para_dim + 8] = top_label[pre_id * para_dim + 8]*0.16+0.02;
              top_hist[item_id * para_dim + 9] = top_label[pre_id * para_dim + 9]*0.14545-0.48181;
              top_hist[item_id * para_dim + 10] = top_label[pre_id * para_dim + 10]/95.0+0.12;
              top_hist[item_id * para_dim + 11] = top_label[pre_id * para_dim + 11]/95.0+0.12;
              top_hist[item_id * para_dim + 12] = top_label[pre_id * para_dim + 12]/95.0+0.12;
              top_hist[item_id * para_dim + 13] = top_label[pre_id * para_dim + 13]*0.6+0.2;
           }
        }
        //////////////////////////////////// for hist

        trans_time += timer.MicroSeconds();

        buffer_key[seq_id]++;
        buffer_total[seq_id]++;
        if (buffer_key[seq_id]>total_frames || buffer_total[seq_id]>interval) {
           buffer_key[seq_id]=random(total_frames)+1;
           buffer_marker[seq_id]=0;
           buffer_total[seq_id]=0;
        }

        //////////////////////////////////// for hist
        if (time_id==sequence_size-1) {
           for (int j = 0; j < para_dim; ++j) 
               hist_blob[seq_id * para_dim + j] = datum.float_data(j); 
        }
        //////////////////////////////////// for hist

/*
        if (seq_id == 0) {
           for (int h = 0; h < resize_height; ++h) {
              for (int w = 0; w < resize_width; ++w) {
                 leveldbTrain->imageData[(h*resize_width+w)*3+0]=(uint8_t)data[h*resize_width+w];
                 leveldbTrain->imageData[(h*resize_width+w)*3+1]=(uint8_t)data[resize_height*resize_width+h*resize_width+w];
                 leveldbTrain->imageData[(h*resize_width+w)*3+2]=(uint8_t)data[resize_height*resize_width*2+h*resize_width+w];

                 //leveldbTrain->imageData[(h*resize_width+w)*3+0]=(uint8_t)top_data[item_id * size+h*resize_width+w];
                 //leveldbTrain->imageData[(h*resize_width+w)*3+1]=(uint8_t)top_data[item_id * size+resize_height*resize_width+h*resize_width+w];
                 //leveldbTrain->imageData[(h*resize_width+w)*3+2]=(uint8_t)top_data[item_id * size+resize_height*resize_width*2+h*resize_width+w];
               }
           }
           cvShowImage("Image from leveldb", leveldbTrain);
           cvWaitKey( 1 );
        }
*/
     }
  }

  batch_timer.Stop();
  DLOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << " ms.";
  DLOG(INFO) << "     Read time: " << read_time / 1000 << " ms.";
  DLOG(INFO) << "Transform time: " << trans_time / 1000 << " ms.";
}
void DataLayer<Dtype>::InternalThreadEntry() {
  CPUTimer batch_timer;
  batch_timer.Start();
  double read_time = 0;
  double trans_time = 0;
  CPUTimer timer;
  CHECK(this->prefetch_data_.count());
  CHECK(this->transformed_data_.count());

  // Reshape on single input batches for inputs of varying dimension.
  const int batch_size = this->layer_param_.data_param().batch_size();
  const int crop_size = this->layer_param_.transform_param().crop_size();
  if (batch_size == 1 && crop_size == 0) {
    Datum datum;
    datum.ParseFromString(cursor_->value());
    this->prefetch_data_.Reshape(1, datum.channels(),
        datum.height(), datum.width());
    this->transformed_data_.Reshape(1, datum.channels(),
        datum.height(), datum.width());
  }

  Dtype* top_data = this->prefetch_data_.mutable_cpu_data();
  Dtype* top_label = NULL;  // suppress warnings about uninitialized variables

  if (this->output_labels_) {
    top_label = this->prefetch_label_.mutable_cpu_data();
  }
  bool force_color = this->layer_param_.data_param().force_encoded_color();
  for (int item_id = 0; item_id < batch_size; ++item_id) {
    timer.Start();
    // get a blob
    Datum datum;
    datum.ParseFromString(cursor_->value());

    cv::Mat cv_img;
    if (datum.encoded()) {
      if (force_color) {
        cv_img = DecodeDatumToCVMat(datum, true);
      } else {
        cv_img = DecodeDatumToCVMatNative(datum);
      }
      if (cv_img.channels() != this->transformed_data_.channels()) {
        LOG(WARNING) << "Your dataset contains encoded images with mixed "
        << "channel sizes. Consider adding a 'force_color' flag to the "
        << "model definition, or rebuild your dataset using "
        << "convert_imageset.";
      }
    }
    read_time += timer.MicroSeconds();
    timer.Start();

    // Apply data transformations (mirror, scale, crop...)
    int offset = this->prefetch_data_.offset(item_id);
    this->transformed_data_.set_cpu_data(top_data + offset);
    if (datum.encoded()) {
      this->data_transformer_->Transform(cv_img, &(this->transformed_data_));
    } else {
      this->data_transformer_->Transform(datum, &(this->transformed_data_));
    }
    if (this->output_labels_) {
      for (int label_i = 0; label_i < datum.label_size(); ++label_i){
        top_label[item_id * datum.label_size() + label_i] = datum.label(label_i);
      }
      //top_label[item_id] = datum.label();
    }
    trans_time += timer.MicroSeconds();
    // go to the next iter
    cursor_->Next();
    if (!cursor_->valid()) {
      DLOG(INFO) << "Restarting data prefetching from start.";
      cursor_->SeekToFirst();
    }
  }
  batch_timer.Stop();
  DLOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << " ms.";
  DLOG(INFO) << "     Read time: " << read_time / 1000 << " ms.";
  DLOG(INFO) << "Transform time: " << trans_time / 1000 << " ms.";
}
Exemple #18
0
std::vector<float> calc_mean(const std::string &db_fname) {
  scoped_ptr<db::DB> db(db::GetDB(FLAGS_backend));
  db->Open(db_fname, db::READ);
  scoped_ptr<db::Cursor> cursor(db->NewCursor());

  BlobProto sum_blob;
  int count = 0;
  // load first datum
  Datum datum;
  datum.ParseFromString(cursor->value());

  if (DecodeDatumNative(&datum)) {
    LOG(INFO) << "Decoding Datum";
  }

  sum_blob.set_num(1);
  sum_blob.set_channels(datum.channels());
  sum_blob.set_height(datum.height());
  sum_blob.set_width(datum.width());
  const int data_size = datum.channels() * datum.height() * datum.width();
  int size_in_datum = std::max<int>(datum.data().size(),
                                    datum.float_data_size());
  for (int i = 0; i < size_in_datum; ++i) {
    sum_blob.add_data(0.);
  }
  LOG(INFO) << "Starting Iteration";
  while (cursor->valid()) {
    Datum datum;
    datum.ParseFromString(cursor->value());
    DecodeDatumNative(&datum);

    const std::string& data = datum.data();
    size_in_datum = std::max<int>(datum.data().size(),
                                  datum.float_data_size());
    CHECK_EQ(size_in_datum, data_size)
      << "Incorrect data field size " << size_in_datum;

    if (data.size() != 0) {
      CHECK_EQ(data.size(), size_in_datum);
      for (int i = 0; i < size_in_datum; ++i) {
        sum_blob.set_data(i, sum_blob.data(i) + (uint8_t)data[i]);
      }
    } else {
      CHECK_EQ(datum.float_data_size(), size_in_datum);
      for (int i = 0; i < size_in_datum; ++i) {
        sum_blob.set_data(i, sum_blob.data(i) +
            static_cast<float>(datum.float_data(i)));
      }
    }
    ++count;
    if (count % 10000 == 0) {
      LOG(INFO) << "Processed " << count << " files.";
    }
    cursor->Next();
  }

  if (count % 10000 != 0) {
    LOG(INFO) << "Processed " << count << " files.";
  }
  for (int i = 0; i < sum_blob.data_size(); ++i) {
    sum_blob.set_data(i, sum_blob.data(i) / count);
  }

  const int channels = sum_blob.channels();
  const int dim = sum_blob.height() * sum_blob.width();
  std::vector<float> mean_values(channels, 0.0);
  LOG(INFO) << "Number of channels: " << channels;
  for (int c = 0; c < channels; ++c) {
    for (int i = 0; i < dim; ++i) {
      mean_values[c] += sum_blob.data(dim * c + i);
    }
    mean_values[c] /= dim;
    LOG(INFO) << "mean_value channel [" << c << "]:" << mean_values[c];
  }

  return mean_values;
}
Exemple #19
0
void calc_stddev(
  const std::string &db_fname,
  std::vector<float> mean_values) {
  
  scoped_ptr<db::DB> db(db::GetDB(FLAGS_backend));
  db->Open(db_fname, db::READ);
  scoped_ptr<db::Cursor> cursor(db->NewCursor());

  // load first datum
  Datum datum;
  datum.ParseFromString(cursor->value());

  if (DecodeDatumNative(&datum)) {
    LOG(INFO) << "Decoding Datum";
  }

  std::vector<double> stddev_values;
  for (int c = 0; c < datum.channels(); ++c) {
    stddev_values.push_back(0.0);
  }

  int files = 0;
  unsigned long count = 0;
  LOG(INFO) << "Starting Iteration";

  while (cursor->valid()) {
    Datum datum;
    datum.ParseFromString(cursor->value());
    DecodeDatumNative(&datum);

    const int channels = datum.channels();
    const int height = datum.height();
    const int width = datum.width();
    const std::string& data = datum.data();

    for (int c = 0; c < channels; ++c) {
      for (int h = 0; h < height; ++h) {
        for (int w = 0; w < width; ++w) {
          const int index = c * height * width + h * width + w;
          const int pixel = static_cast<uint8_t>(data[index]);
          stddev_values[c] += pow((double)pixel - mean_values[c], 2.0);
        }
      }
    }

    count += width * height;
    ++files;
    if (count % 10000 == 0) {
      LOG(INFO) << "Processed " << files << " files.";
      LOG(INFO) << "count:" << count;
    }
    cursor->Next();
  }
  if (files % 10000 != 0) {
    LOG(INFO) << "Processed " << files << " files.";
    LOG(INFO) << "count: " << count;
  }
  LOG(INFO) << "Finished Iteration";

  std::cout.precision(15);
  LOG(INFO) << "Number of channels: " << datum.channels();
  for (int c = 0; c < datum.channels(); ++c) {
    stddev_values[c] /= (double)count;
    stddev_values[c] = sqrt(stddev_values[c]);
    LOG(INFO) << "stddev_value channel [" << c << "]:"
              << std::fixed << stddev_values[c];
  }
}
int main(int argc, char** argv) {
  ::google::InitGoogleLogging(argv[0]);
  if (argc < 3 || argc > 4) {
    LOG(ERROR) << "Usage: compute_image_mean input_db output_file"
               << " db_backend[leveldb or lmdb]";
    return 1;
  }

  string db_backend = "lmdb";
  if (argc == 4) {
    db_backend = string(argv[3]);
  }

  // Open leveldb
  leveldb::DB* db;
  leveldb::Options options;
  options.create_if_missing = false;
  leveldb::Iterator* it = NULL;
  // lmdb
  MDB_env* mdb_env;
  MDB_dbi mdb_dbi;
  MDB_val mdb_key, mdb_value;
  MDB_txn* mdb_txn;
  MDB_cursor* mdb_cursor;

  // Open db
  if (db_backend == "leveldb") {  // leveldb
    LOG(INFO) << "Opening leveldb " << argv[1];
    leveldb::Status status = leveldb::DB::Open(
        options, argv[1], &db);
    CHECK(status.ok()) << "Failed to open leveldb " << argv[1];
    leveldb::ReadOptions read_options;
    read_options.fill_cache = false;
    it = db->NewIterator(read_options);
    it->SeekToFirst();
  } else if (db_backend == "lmdb") {  // lmdb
    LOG(INFO) << "Opening lmdb " << argv[1];
    CHECK_EQ(mdb_env_create(&mdb_env), MDB_SUCCESS) << "mdb_env_create failed";
    CHECK_EQ(mdb_env_set_mapsize(mdb_env, 1099511627776), MDB_SUCCESS);  // 1TB
    CHECK_EQ(mdb_env_open(mdb_env, argv[1], MDB_RDONLY, 0664),
        MDB_SUCCESS) << "mdb_env_open failed";
    CHECK_EQ(mdb_txn_begin(mdb_env, NULL, MDB_RDONLY, &mdb_txn), MDB_SUCCESS)
        << "mdb_txn_begin failed";
    CHECK_EQ(mdb_open(mdb_txn, NULL, 0, &mdb_dbi), MDB_SUCCESS)
        << "mdb_open failed";
    CHECK_EQ(mdb_cursor_open(mdb_txn, mdb_dbi, &mdb_cursor), MDB_SUCCESS)
        << "mdb_cursor_open failed";
    CHECK_EQ(mdb_cursor_get(mdb_cursor, &mdb_key, &mdb_value, MDB_FIRST),
        MDB_SUCCESS);
  } else {
    LOG(FATAL) << "Unknown db backend " << db_backend;
  }

  // set size info
  Datum datum;
  BlobProto sum_blob;
  int count = 0;
  // load first datum
  if (db_backend == "leveldb") {
    datum.ParseFromString(it->value().ToString());
  } else if (db_backend == "lmdb") {
    datum.ParseFromArray(mdb_value.mv_data, mdb_value.mv_size);
  } else {
    LOG(FATAL) << "Unknown db backend " << db_backend;
  }

  sum_blob.set_num(1);
  sum_blob.set_channels(datum.channels());
  sum_blob.set_height(datum.height());
  sum_blob.set_width(datum.width());
  const int data_size = datum.channels() * datum.height() * datum.width();
  int size_in_datum = std::max<int>(datum.data().size(),
                                    datum.float_data_size());
  for (int i = 0; i < size_in_datum; ++i) {
    sum_blob.add_data(0.);
  }
  // start collecting
  LOG(INFO) << "Starting Iteration";

  if (db_backend == "leveldb") {  // leveldb
    for (it->SeekToFirst(); it->Valid(); it->Next()) {
      // just a dummy operation
      datum.ParseFromString(it->value().ToString());
      const string& data = datum.data();
      size_in_datum = std::max<int>(datum.data().size(),
          datum.float_data_size());
      CHECK_EQ(size_in_datum, data_size) << "Incorrect data field size " <<
          size_in_datum;
      if (data.size() != 0) {
        for (int i = 0; i < size_in_datum; ++i) {
          sum_blob.set_data(i, sum_blob.data(i) + (uint8_t)data[i]);
        }
      } else {
        for (int i = 0; i < size_in_datum; ++i) {
          sum_blob.set_data(i, sum_blob.data(i) +
              static_cast<float>(datum.float_data(i)));
        }
      }
      ++count;
      if (count % 10000 == 0) {
        LOG(ERROR) << "Processed " << count << " files.";
      }
    }
  } else if (db_backend == "lmdb") {  // lmdb
    CHECK_EQ(mdb_cursor_get(mdb_cursor, &mdb_key, &mdb_value, MDB_FIRST),
        MDB_SUCCESS);
    do {
      // just a dummy operation
      datum.ParseFromArray(mdb_value.mv_data, mdb_value.mv_size);
      const string& data = datum.data();
      size_in_datum = std::max<int>(datum.data().size(),
          datum.float_data_size());
      CHECK_EQ(size_in_datum, data_size) << "Incorrect data field size " <<
          size_in_datum;
      if (data.size() != 0) {
        for (int i = 0; i < size_in_datum; ++i) {
          sum_blob.set_data(i, sum_blob.data(i) + (uint8_t)data[i]);
        }
      } else {
        for (int i = 0; i < size_in_datum; ++i) {
          sum_blob.set_data(i, sum_blob.data(i) +
              static_cast<float>(datum.float_data(i)));
        }
      }
      ++count;
      if (count % 10000 == 0) {
        LOG(ERROR) << "Processed " << count << " files.";
      }
    } while (mdb_cursor_get(mdb_cursor, &mdb_key, &mdb_value, MDB_NEXT)
        == MDB_SUCCESS);
  } else {
    LOG(FATAL) << "Unknown db backend " << db_backend;
  }

  for (int i = 0; i < sum_blob.data_size(); ++i) {
    sum_blob.set_data(i, sum_blob.data(i) / count);
  }

  caffe::Blob<float> vis;
  vis.FromProto(sum_blob);
  caffe::imshow(&vis, 1, "mean img");
  cv::waitKey(0);
  
  google::protobuf::RepeatedField<float>* tmp = sum_blob.mutable_data();
  std::vector<float> mean_data(tmp->begin(), tmp->end());
  double sum = std::accumulate(mean_data.begin(), mean_data.end(), 0.0);
  double mean2 = sum / mean_data.size();
  double sq_sum = std::inner_product(mean_data.begin(), mean_data.end(), mean_data.begin(), 0.0);
  double stdev = std::sqrt(sq_sum / mean_data.size() - mean2 * mean2);

  LOG(INFO) << "mean of mean image: " << mean2 << " std: " << stdev;

  // Write to disk
  LOG(INFO) << "Write to " << argv[2];
  WriteProtoToBinaryFile(sum_blob, argv[2]);

  // Clean up
  if (db_backend == "leveldb") {
    delete db;
  } else if (db_backend == "lmdb") {
    mdb_cursor_close(mdb_cursor);
    mdb_close(mdb_env, mdb_dbi);
    mdb_txn_abort(mdb_txn);
    mdb_env_close(mdb_env);
  } else {
    LOG(FATAL) << "Unknown db backend " << db_backend;
  }
  return 0;
}
Exemple #21
0
void DataLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom,
      vector<Blob<Dtype>*>* top) {
  CHECK_EQ(bottom.size(), 0) << "Data Layer takes no input blobs.";
  CHECK_EQ(top->size(), 2) << "Data Layer takes two blobs as output.";
  // Initialize the leveldb
  leveldb::DB* db_temp;
  leveldb::Options options;
  options.create_if_missing = false;
  options.max_open_files = 100;
  LOG(INFO) << "Opening leveldb " << this->layer_param_.source();
  leveldb::Status status = leveldb::DB::Open(
      options, this->layer_param_.source(), &db_temp);
  CHECK(status.ok()) << "Failed to open leveldb "
      << this->layer_param_.source() << std::endl << status.ToString();
  db_.reset(db_temp);
  iter_.reset(db_->NewIterator(leveldb::ReadOptions()));
  iter_->SeekToFirst();
  // Check if we would need to randomly skip a few data points
  if (this->layer_param_.rand_skip()) {
    // NOLINT_NEXT_LINE(runtime/threadsafe_fn)
    unsigned int skip = rand() % this->layer_param_.rand_skip();
    LOG(INFO) << "Skipping first " << skip << " data points.";
    while (skip-- > 0) {
      iter_->Next();
      if (!iter_->Valid()) {
        iter_->SeekToFirst();
      }
    }
  }
  // Read a data point, and use it to initialize the top blob.
  Datum datum;
  datum.ParseFromString(iter_->value().ToString());
  // image
  int cropsize = this->layer_param_.cropsize();
  if (cropsize > 0) {
    (*top)[0]->Reshape(
        this->layer_param_.batchsize(), datum.channels(), cropsize, cropsize);
    prefetch_data_.reset(new Blob<Dtype>(
        this->layer_param_.batchsize(), datum.channels(), cropsize, cropsize));
  } else {
    (*top)[0]->Reshape(
        this->layer_param_.batchsize(), datum.channels(), datum.height(),
        datum.width());
    prefetch_data_.reset(new Blob<Dtype>(
        this->layer_param_.batchsize(), datum.channels(), datum.height(),
        datum.width()));
  }
  LOG(INFO) << "output data size: " << (*top)[0]->num() << ","
      << (*top)[0]->channels() << "," << (*top)[0]->height() << ","
      << (*top)[0]->width();
  // label
  (*top)[1]->Reshape(this->layer_param_.batchsize(), 1, 1, 1);
  prefetch_label_.reset(
      new Blob<Dtype>(this->layer_param_.batchsize(), 1, 1, 1));
  // datum size
  datum_channels_ = datum.channels();
  datum_height_ = datum.height();
  datum_width_ = datum.width();
  datum_size_ = datum.channels() * datum.height() * datum.width();
  CHECK_GT(datum_height_, cropsize);
  CHECK_GT(datum_width_, cropsize);
  // check if we want to have mean
  if (this->layer_param_.has_meanfile()) {
    BlobProto blob_proto;
    LOG(INFO) << "Loading mean file from" << this->layer_param_.meanfile();
    ReadProtoFromBinaryFile(this->layer_param_.meanfile().c_str(), &blob_proto);
    data_mean_.FromProto(blob_proto);
    CHECK_EQ(data_mean_.num(), 1);
    CHECK_EQ(data_mean_.channels(), datum_channels_);
    CHECK_EQ(data_mean_.height(), datum_height_);
    CHECK_EQ(data_mean_.width(), datum_width_);
  } else {
    // Simply initialize an all-empty mean.
    data_mean_.Reshape(1, datum_channels_, datum_height_, datum_width_);
  }
  // Now, start the prefetch thread. Before calling prefetch, we make two
  // cpu_data calls so that the prefetch thread does not accidentally make
  // simultaneous cudaMalloc calls when the main thread is running. In some
  // GPUs this seems to cause failures if we do not so.
  prefetch_data_->mutable_cpu_data();
  prefetch_label_->mutable_cpu_data();
  data_mean_.cpu_data();
  DLOG(INFO) << "Initializing prefetch";
  CHECK(!pthread_create(&thread_, NULL, DataLayerPrefetch<Dtype>,
      reinterpret_cast<void*>(this))) << "Pthread execution failed.";
  DLOG(INFO) << "Prefetch initialized.";
}
void DataLayer<Dtype>::InternalThreadEntry() {
  Datum datum;
  CHECK(this->prefetch_data_.count());
  Dtype* top_data = this->prefetch_data_.mutable_cpu_data();
  Dtype* top_label = NULL;  // suppress warnings about uninitialized variables
  if (this->output_labels_) {
    top_label = this->prefetch_label_.mutable_cpu_data();
  }
  const int batch_size = this->layer_param_.data_param().batch_size();

  for (int item_id = 0; item_id < batch_size; ++item_id) {
    // get a blob
    switch (this->layer_param_.data_param().backend()) {
    case DataParameter_DB_LEVELDB:
      CHECK(iter_);
      CHECK(iter_->Valid());
      datum.ParseFromString(iter_->value().ToString());
      break;
    case DataParameter_DB_LMDB:
      CHECK_EQ(mdb_cursor_get(mdb_cursor_, &mdb_key_,
              &mdb_value_, MDB_GET_CURRENT), MDB_SUCCESS);
      datum.ParseFromArray(mdb_value_.mv_data,
          mdb_value_.mv_size);
      break;
    default:
      LOG(FATAL) << "Unknown database backend";
    }

    // Apply data transformations (mirror, scale, crop...)
    this->data_transformer_.Transform(item_id, datum, this->mean_, top_data);

    if (this->output_labels_) {
	  // liu
      // top_label[item_id] = datum.label();
	  // LOG(ERROR) << "label size " << datum.label_size() << " " << datum.label(0) \
				 << " " << datum.label(1) << " " << datum.label(2) << " " << datum.label(3);
	  for(int label_i=0; label_i < datum.label_size(); label_i++){
		top_label[item_id * datum.label_size() + label_i] = datum.label(label_i);
	  }
    }

    // go to the next iter
    switch (this->layer_param_.data_param().backend()) {
    case DataParameter_DB_LEVELDB:
      iter_->Next();
      if (!iter_->Valid()) {
        // We have reached the end. Restart from the first.
        DLOG(INFO) << "Restarting data prefetching from start.";
        iter_->SeekToFirst();
      }
      break;
    case DataParameter_DB_LMDB:
      if (mdb_cursor_get(mdb_cursor_, &mdb_key_,
              &mdb_value_, MDB_NEXT) != MDB_SUCCESS) {
        // We have reached the end. Restart from the first.
        DLOG(INFO) << "Restarting data prefetching from start.";
        CHECK_EQ(mdb_cursor_get(mdb_cursor_, &mdb_key_,
                &mdb_value_, MDB_FIRST), MDB_SUCCESS);
      }
      break;
    default:
      LOG(FATAL) << "Unknown database backend";
    }
  }
}
int main(int argc, char** argv) {
  ::google::InitGoogleLogging(argv[0]);

#ifdef USE_OPENCV
#ifndef GFLAGS_GFLAGS_H_
  namespace gflags = google;
#endif

  gflags::SetUsageMessage("Compute the mean_image of a set of images given by"
        " a leveldb/lmdb\n"
        "Usage:\n"
        "    compute_image_mean [FLAGS] INPUT_DB [OUTPUT_FILE]\n");

  gflags::ParseCommandLineFlags(&argc, &argv, true);

  if (argc < 2 || argc > 3) {
    gflags::ShowUsageWithFlagsRestrict(argv[0], "tools/compute_image_mean");
    return 1;
  }

  scoped_ptr<db::DB> db(db::GetDB(FLAGS_backend));
  db->Open(argv[1], db::READ);
  scoped_ptr<db::Cursor> cursor(db->NewCursor());

  BlobProto sum_blob;
  int count = 0;
  // load first datum
  Datum datum;
  datum.ParseFromString(cursor->value());

  if (DecodeDatumNative(&datum)) {
    LOG(INFO) << "Decoding Datum";
  }

  sum_blob.set_num(1);
  sum_blob.set_channels(datum.channels());
  sum_blob.set_height(datum.height());
  sum_blob.set_width(datum.width());
  const int data_size = datum.channels() * datum.height() * datum.width();
  int size_in_datum = std::max<int>(datum.data().size(),
                                    datum.float_data_size());
  for (int i = 0; i < size_in_datum; ++i) {
    sum_blob.add_data(0.);
  }
  LOG(INFO) << "Starting Iteration";
  while (cursor->valid()) {
    Datum datum;
    datum.ParseFromString(cursor->value());
    DecodeDatumNative(&datum);

    const std::string& data = datum.data();
    size_in_datum = std::max<int>(datum.data().size(),
        datum.float_data_size());
    CHECK_EQ(size_in_datum, data_size) << "Incorrect data field size " <<
        size_in_datum;
    if (data.size() != 0) {
      CHECK_EQ(data.size(), size_in_datum);
      for (int i = 0; i < size_in_datum; ++i) {
        sum_blob.set_data(i, sum_blob.data(i) + (uint8_t)data[i]);
      }
    } else {
      CHECK_EQ(datum.float_data_size(), size_in_datum);
      for (int i = 0; i < size_in_datum; ++i) {
        sum_blob.set_data(i, sum_blob.data(i) +
            static_cast<float>(datum.float_data(i)));
      }
    }
    ++count;
    if (count % 10000 == 0) {
      LOG(INFO) << "Processed " << count << " files.";
      printf("Processed %d files.\n",count);
    }
    cursor->Next();
  }

  if (count % 10000 != 0) {
    LOG(INFO) << "Processed " << count << " files.";
    printf("Processed %d files.\n",count);
  }
  for (int i = 0; i < sum_blob.data_size(); ++i) {
    sum_blob.set_data(i, sum_blob.data(i) / count);
  }
  // Write to disk
  if (argc == 3) {
    LOG(INFO) << "Write to " << argv[2];
    WriteProtoToBinaryFile(sum_blob, argv[2]);
  }
  const int channels = sum_blob.channels();
  const int dim = sum_blob.height() * sum_blob.width();
  std::vector<float> mean_values(channels, 0.0);
  LOG(INFO) << "Number of channels: " << channels;
  for (int c = 0; c < channels; ++c) {
    for (int i = 0; i < dim; ++i) {
      mean_values[c] += sum_blob.data(dim * c + i);
    }
    LOG(INFO) << "mean_value channel [" << c << "]:" << mean_values[c] / dim;
  }
#else
  LOG(FATAL) << "This tool requires OpenCV; compile with USE_OPENCV.";
#endif  // USE_OPENCV
  return 0;
}
Exemple #24
0
void DataLayer<Dtype>::load_batch(Batch<Dtype>* batch) {
  CPUTimer batch_timer;
  batch_timer.Start();
  double read_time = 0;
  double trans_time = 0;
  CPUTimer timer;
  // LOG(INFO)<<"load_batch";
  CHECK(batch->data_.count());
  CHECK(this->transformed_data_.count());

  // 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 = *(reader_.full().peek());
  // // Use data_transformer to infer the expected blob shape from datum.
  Datum datum;
  datum.ParseFromString(cursor_->value());
  // 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 batch according to the batch_size.
  top_shape[0] = batch_size;
  batch->data_.Reshape(top_shape);
  Dtype* top_data = batch->data_.mutable_cpu_data();
  // Dtype* top_data = this->prefetch_data_.mutable_cpu_data();
  Dtype* top_label = NULL;  // suppress warnings about uninitialized variables
  // LOG(INFO)<<" output_labels_:"<<this->output_labels_;
  if (this->output_labels_) {
    top_label = batch->label_.mutable_cpu_data();
    // top_label = this->prefetch_label_.mutable_cpu_data();
  }
  Dtype* use_data=this->use_data_.mutable_cpu_data();
  // LOG(INFO)<<" use_data[0]:"<<use_data[0];
  if (use_data[0]==0.0){
    // LOG(INFO)<<"visit in order";
    for (int item_id = 0; item_id < batch_size; item_id++) {
      Datum datum;
      datum.ParseFromString(cursor_->value());
   
      // Apply data transformations (mirror, scale, crop...)
      // LOG(INFO)<<"jq enter data_layers"<< item_id;
      int offset = batch->data_.offset(item_id);
      // LOG(INFO)<<"jq enter data_layers";
      this->transformed_data_.set_cpu_data(top_data + offset);
      this->data_transformer_->Transform(datum, &(this->transformed_data_));
      // Copy label.
      if (this->output_labels_) {
        top_label[item_id] = datum.label();
        // std::cout<<" cursor_:"<<datum.label();
      }
      // use_data[item_id +5] = start;
      // trans_time += timer.MicroSeconds();
      cursor_->Next();
      // start +=1.0;
      // std::cout<<" output_labels_:"<<this->output_labels_;
      if (!cursor_->valid()) {
        DLOG(INFO) << "Restarting data prefetching from start.";
        cursor_->SeekToFirst();
      }
      // reader_.free().push(const_cast<Datum*>(&datum));
    }
  }else if (use_data[0]!=0.0){
    // forward-backward using semi supervised with false label
    // 0, sami-super-unsuper, 1, label_kinds, 2, step over, 
    // 3, datanum, 4, start index
    // LOG(INFO)<<"visit in Key/value";
    // LOG(INFO)<<"this->PREFETCH_COUNT:"<<this->PREFETCH_COUNT;
    int step_over = batch_size+1;
    // std::cout<<std::endl;
    scoped_ptr<db::Transaction> txn(db_->NewTransaction());
    // std::cout<<"key:";
    int kCIFARImageNBytes=3072;
    for (int item_id = 0; item_id < batch_size; item_id++) {
      char str_buffer[kCIFARImageNBytes];
      int id= static_cast<int>(use_data[item_id+ 1]);
      // std::cout<<" "<<id<<":";
      int length = snprintf(str_buffer, kCIFARImageNBytes, "%05d", id);
      string value;
      string str=string(str_buffer, length);
      txn->Get(str, value);
      Datum datum;
      datum.ParseFromString(value);
      int offset = batch->data_.offset(item_id);
      // LOG(INFO)<<"jq enter data_layers";
      this->transformed_data_.set_cpu_data(top_data + offset);
      this->data_transformer_->Transform(datum, &(this->transformed_data_));
      // std::cout<<" output_labels_:"<<this->output_labels_;
      if (this->output_labels_) {
        // top_label[item_id] = datum.label();
        top_label[item_id] = use_data[item_id+ step_over];
        // std::cout<<" KV:"<<datum.label();
        // top_label[item_id]= static_cast<int>(use_data[item_id + batch_size +3]);
      }
      if( use_data[item_id+ step_over]!=(datum.label()%1000))
        LOG(INFO)<<"image id:"<<id<<" not correctly fetch: "<<datum.label()
      <<" vs "<<use_data[item_id+ step_over];
      // std::cout<<top_label[item_id];
      // std::cout<<" key:"<<id;
    }
    // std::cout<<std::endl;
    // for (int item_id = 0; item_id < 50000; item_id++) {
    //   char str_buffer[kCIFARImageNBytes];
    //   // int id= static_cast<int>(use_data[item_id+ 1]);
    //   int length = snprintf(str_buffer, kCIFARImageNBytes, "%05d", item_id);
    //   string value;
    //   string str=string(str_buffer, length);
    //   txn->Get(str, value);
    //   // Datum datum;
    //   // datum.ParseFromString(value);
    //   // int offset = batch->data_.offset(item_id);
    //   // // LOG(INFO)<<"jq enter data_layers";
    //   // this->transformed_data_.set_cpu_data(top_data + offset);
    //   // this->data_transformer_->Transform(datum, &(this->transformed_data_));
    //   // if (this->output_labels_) {
    //   //   top_label[item_id] = datum.label();
    //   //   // top_label[item_id]= static_cast<int>(use_data[item_id + batch_size +3]);
    //   // }
    //   // std::cout<<" "<<item_id;
    // }
    // std::cout<<std::endl;
    txn->Commit();
  }
  timer.Stop();
  batch_timer.Stop();
  DLOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << " ms.";
  DLOG(INFO) << "     Read time: " << read_time / 1000 << " ms.";
  DLOG(INFO) << "Transform time: " << trans_time / 1000 << " ms.";
}
Exemple #25
0
void* DataLayerPrefetch(void* layer_pointer) {
  CHECK(layer_pointer);
  DataLayer<Dtype>* layer = static_cast<DataLayer<Dtype>*>(layer_pointer);
  CHECK(layer);
  Datum datum;
  CHECK(layer->prefetch_data_);
  Dtype* top_data = layer->prefetch_data_->mutable_cpu_data();
  Dtype* top_label;
  if (layer->output_labels_) {
    top_label = layer->prefetch_label_->mutable_cpu_data();
  }
  const Dtype scale = layer->layer_param_.data_param().scale();
  const int batch_size = layer->layer_param_.data_param().batch_size();
  const int crop_size = layer->layer_param_.data_param().crop_size();
  const bool mirror = layer->layer_param_.data_param().mirror();

  if (mirror && crop_size == 0) {
    LOG(FATAL) << "Current implementation requires mirror and crop_size to be "
        << "set at the same time.";
  }
  // datum scales
  const int channels = layer->datum_channels_;
  const int height = layer->datum_height_;
  const int width = layer->datum_width_;
  const int size = layer->datum_size_;
  const Dtype* mean = layer->data_mean_.cpu_data();
  for (int item_id = 0; item_id < batch_size; ++item_id) {
    // get a blob
    CHECK(layer->iter_);
    CHECK(layer->iter_->Valid());
    datum.ParseFromString(layer->iter_->value().ToString());
    const string& data = datum.data();
    if (crop_size) {
      CHECK(data.size()) << "Image cropping only support uint8 data";
      int h_off, w_off;
      // We only do random crop when we do training.
      if (layer->phase_ == Caffe::TRAIN) {
        h_off = layer->PrefetchRand() % (height - crop_size);
        w_off = layer->PrefetchRand() % (width - crop_size);
      } else {
        h_off = (height - crop_size) / 2;
        w_off = (width - crop_size) / 2;
      }
      if (mirror && layer->PrefetchRand() % 2) {
        // Copy mirrored version
        for (int c = 0; c < channels; ++c) {
          for (int h = 0; h < crop_size; ++h) {
            for (int w = 0; w < crop_size; ++w) {
              int top_index = ((item_id * channels + c) * crop_size + h)
                              * crop_size + (crop_size - 1 - w);
              int data_index = (c * height + h + h_off) * width + w + w_off;
              Dtype datum_element =
                  static_cast<Dtype>(static_cast<uint8_t>(data[data_index]));
              top_data[top_index] = (datum_element - mean[data_index]) * scale;
            }
          }
        }
      } else {
        // Normal copy
        for (int c = 0; c < channels; ++c) {
          for (int h = 0; h < crop_size; ++h) {
            for (int w = 0; w < crop_size; ++w) {
              int top_index = ((item_id * channels + c) * crop_size + h)
                              * crop_size + w;
              int data_index = (c * height + h + h_off) * width + w + w_off;
              Dtype datum_element =
                  static_cast<Dtype>(static_cast<uint8_t>(data[data_index]));
              top_data[top_index] = (datum_element - mean[data_index]) * scale;
            }
          }
        }
      }
    } else {
      // we will prefer to use data() first, and then try float_data()
      if (data.size()) {
        for (int j = 0; j < size; ++j) {
          Dtype datum_element =
              static_cast<Dtype>(static_cast<uint8_t>(data[j]));
          top_data[item_id * size + j] = (datum_element - mean[j]) * scale;
        }
      } else {
        for (int j = 0; j < size; ++j) {
          top_data[item_id * size + j] =
              (datum.float_data(j) - mean[j]) * scale;
        }
      }
    }

    if (layer->output_labels_) {
      top_label[item_id] = datum.label();
    }
    // go to the next iter
    layer->iter_->Next();
    if (!layer->iter_->Valid()) {
      // We have reached the end. Restart from the first.
      DLOG(INFO) << "Restarting data prefetching from start.";
      layer->iter_->SeekToFirst();
    }
  }

  return static_cast<void*>(NULL);
}
Exemple #26
0
void* DataLayerPrefetch(void* layer_pointer) {
  CHECK(layer_pointer);
  DataLayer<Dtype>* layer = reinterpret_cast<DataLayer<Dtype>*>(layer_pointer);
  CHECK(layer);
  Datum datum;
  CHECK(layer->prefetch_data_);
  Dtype* top_data = layer->prefetch_data_->mutable_cpu_data();
  Dtype* top_label = layer->prefetch_label_->mutable_cpu_data();
  const Dtype scale = layer->layer_param_.scale();
  const int batchsize = layer->layer_param_.batchsize();
  const int cropsize = layer->layer_param_.cropsize();
  const bool mirror = layer->layer_param_.mirror();

  if (mirror && cropsize == 0) {
    LOG(FATAL) << "Current implementation requires mirror and cropsize to be "
        << "set at the same time.";
  }
  // datum scales
  const int channels = layer->datum_channels_;
  const int height = layer->datum_height_;
  const int width = layer->datum_width_;
  const int size = layer->datum_size_;
  const Dtype* mean = layer->data_mean_.cpu_data();
  for (int itemid = 0; itemid < batchsize; ++itemid) {
    // get a blob
    CHECK(layer->iter_);
    CHECK(layer->iter_->Valid());
    datum.ParseFromString(layer->iter_->value().ToString());
    const string& data = datum.data();

    if (cropsize) {
      //CHECK(data.size()) << "Image cropping only support uint8 data";
      int h_off, w_off;
      // We only do random crop when we do training.
      if (Caffe::phase() == Caffe::TRAIN) {
        // NOLINT_NEXT_LINE(runtime/threadsafe_fn)
        h_off = rand() % (height - cropsize);
        // NOLINT_NEXT_LINE(runtime/threadsafe_fn)
        w_off = rand() % (width - cropsize);
      } else {
        h_off = (height - cropsize) / 2;
        w_off = (width - cropsize) / 2;
      }
      // NOLINT_NEXT_LINE(runtime/threadsafe_fn)
      if (mirror && rand() % 2) {
        // Copy mirrored version
        for (int c = 0; c < channels; ++c) {
          for (int h = 0; h < cropsize; ++h) {
            for (int w = 0; w < cropsize; ++w) {
              top_data[((itemid * channels + c) * cropsize + h) * cropsize
                       + cropsize - 1 - w] =
                  (static_cast<Dtype>(
                      (float)datum.float_data((c * height + h + h_off) * width
                                    + w + w_off))
                    - mean[(c * height + h + h_off) * width + w + w_off])
                  * scale;
            }
          }
        }
      } else {
        // Normal copy
        for (int c = 0; c < channels; ++c) {
          for (int h = 0; h < cropsize; ++h) {
            for (int w = 0; w < cropsize; ++w) {
              top_data[((itemid * channels + c) * cropsize + h) * cropsize + w]
                  = (static_cast<Dtype>(
                      (float)datum.float_data((c * height + h + h_off) * width
                                    + w + w_off))
                     - mean[(c * height + h + h_off) * width + w + w_off])
                  * scale;
            }
          }
        }
      }
    } else {
      // we will prefer to use data() first, and then try float_data()
      if (data.size()) {

	//cout << "unint8 data!!!!" << endl;
        for (int j = 0; j < size; ++j) {
	  //cout << "datum.int_data " << j << "of size: " << size << static_cast<Dtype>((uint8_t)data[j]) << " mean: " << mean[j] << endl;
          top_data[itemid * size + j] =
              (static_cast<Dtype>((uint8_t)data[j]) - mean[j]) * scale;
        }
      } else {
        //cout << "float data !!!!!!!!!!!" << endl;
        for (int j = 0; j < size; ++j) {
	  
	  //cout << "item: " << itemid <<" datum.float_data " << j << "of size: " << size << endl;
	  //cout << datum.float_data(j) << " mean: " << mean[j] << endl;
          top_data[itemid * size + j] =
              (datum.float_data(j) - mean[j]) * scale;
        }
      }
    }

    top_label[itemid] = datum.label();
    // go to the next iter
    layer->iter_->Next();
    if (!layer->iter_->Valid()) {
      // We have reached the end. Restart from the first.
      DLOG(INFO) << "Restarting data prefetching from start.";
      layer->iter_->SeekToFirst();
    }
  }

  return reinterpret_cast<void*>(NULL);
}
Exemple #27
0
void DataDrivingLayer<Dtype>::InternalThreadEntry() {
  CPUTimer batch_timer;
  batch_timer.Start();
  double read_time = 0;
  double trans_time = 0;
  CPUTimer timer;
  CHECK(this->prefetch_data_.count());

  Datum datum;
  Dtype* top_data = this->prefetch_data_.mutable_cpu_data();
  Dtype* top_label = this->prefetch_label_.mutable_cpu_data();

  // datum scales
  const int size = resize_height*resize_width*3;
  const Dtype* mean = this->data_mean_.mutable_cpu_data();

  string value;
  const int kMaxKeyLength = 256;
  char key_cstr[kMaxKeyLength];
  int key;

  const int batch_size = this->layer_param_.data_driving_param().batch_size();

  for (int item_id = 0; item_id < batch_size; ++item_id) {

      timer.Start();
      // get a blob

      key=random(484815)+1;  // MUST be changed according to the size of the training set

      snprintf(key_cstr, kMaxKeyLength, "%08d", key);
      db_->Get(leveldb::ReadOptions(), string(key_cstr), &value);
      datum.ParseFromString(value);
      const string& data = datum.data();

      read_time += timer.MicroSeconds();
      timer.Start();

      for (int j = 0; j < size; ++j) {
         Dtype datum_element = static_cast<Dtype>(static_cast<uint8_t>(data[j]));
         top_data[item_id * size + j] = (datum_element - mean[j]);
      }

      for (int j = 0; j < para_dim; ++j) { 
         top_label[item_id*para_dim+j] = datum.float_data(j); 
      }

      trans_time += timer.MicroSeconds();
/*
      for (int h = 0; h < resize_height; ++h) {
         for (int w = 0; w < resize_width; ++w) {
            leveldbTrain->imageData[(h*resize_width+w)*3+0]=(uint8_t)data[h*resize_width+w];
            leveldbTrain->imageData[(h*resize_width+w)*3+1]=(uint8_t)data[resize_height*resize_width+h*resize_width+w];
            leveldbTrain->imageData[(h*resize_width+w)*3+2]=(uint8_t)data[resize_height*resize_width*2+h*resize_width+w];

            //leveldbTrain->imageData[(h*resize_width+w)*3+0]=(uint8_t)top_data[item_id * size+h*resize_width+w];
            //leveldbTrain->imageData[(h*resize_width+w)*3+1]=(uint8_t)top_data[item_id * size+resize_height*resize_width+h*resize_width+w];
            //leveldbTrain->imageData[(h*resize_width+w)*3+2]=(uint8_t)top_data[item_id * size+resize_height*resize_width*2+h*resize_width+w];
          }
      }
      cvShowImage("Image from leveldb", leveldbTrain);
      cvWaitKey( 1 );
*/
  }
  batch_timer.Stop();
  DLOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << " ms.";
  DLOG(INFO) << "     Read time: " << read_time / 1000 << " ms.";
  DLOG(INFO) << "Transform time: " << trans_time / 1000 << " ms.";
}
void DataLayer<Dtype>::DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
      vector<Blob<Dtype>*>* top) {
  // Initialize DB
  switch (this->layer_param_.data_param().backend()) {
  case DataParameter_DB_LEVELDB:
    {
    leveldb::DB* db_temp;
    leveldb::Options options = GetLevelDBOptions();
    options.create_if_missing = false;
    LOG(INFO) << "Opening leveldb " << this->layer_param_.data_param().source();
    leveldb::Status status = leveldb::DB::Open(
        options, this->layer_param_.data_param().source(), &db_temp);
    CHECK(status.ok()) << "Failed to open leveldb "
                       << this->layer_param_.data_param().source() << std::endl
                       << status.ToString();
    db_.reset(db_temp);
    iter_.reset(db_->NewIterator(leveldb::ReadOptions()));
    iter_->SeekToFirst();
    }
    break;
  case DataParameter_DB_LMDB:
    CHECK_EQ(mdb_env_create(&mdb_env_), MDB_SUCCESS) << "mdb_env_create failed";
    CHECK_EQ(mdb_env_set_mapsize(mdb_env_, 1099511627776), MDB_SUCCESS);  // 1TB
    CHECK_EQ(mdb_env_open(mdb_env_,
             this->layer_param_.data_param().source().c_str(),
             MDB_RDONLY|MDB_NOTLS, 0664), MDB_SUCCESS) << "mdb_env_open failed";
    CHECK_EQ(mdb_txn_begin(mdb_env_, NULL, MDB_RDONLY, &mdb_txn_), MDB_SUCCESS)
        << "mdb_txn_begin failed";
    CHECK_EQ(mdb_open(mdb_txn_, NULL, 0, &mdb_dbi_), MDB_SUCCESS)
        << "mdb_open failed";
    CHECK_EQ(mdb_cursor_open(mdb_txn_, mdb_dbi_, &mdb_cursor_), MDB_SUCCESS)
        << "mdb_cursor_open failed";
    LOG(INFO) << "Opening lmdb " << this->layer_param_.data_param().source();
    CHECK_EQ(mdb_cursor_get(mdb_cursor_, &mdb_key_, &mdb_value_, MDB_FIRST),
        MDB_SUCCESS) << "mdb_cursor_get failed";
    break;
  default:
    LOG(FATAL) << "Unknown database backend";
  }

  // Check if we would need to randomly skip a few data points
  if (this->layer_param_.data_param().rand_skip()) {
    unsigned int skip = caffe_rng_rand() %
                        this->layer_param_.data_param().rand_skip();
    LOG(INFO) << "Skipping first " << skip << " data points.";
    while (skip-- > 0) {
      switch (this->layer_param_.data_param().backend()) {
      case DataParameter_DB_LEVELDB:
        iter_->Next();
        if (!iter_->Valid()) {
          iter_->SeekToFirst();
        }
        break;
      case DataParameter_DB_LMDB:
        if (mdb_cursor_get(mdb_cursor_, &mdb_key_, &mdb_value_, MDB_NEXT)
            != MDB_SUCCESS) {
          CHECK_EQ(mdb_cursor_get(mdb_cursor_, &mdb_key_, &mdb_value_,
                   MDB_FIRST), MDB_SUCCESS);
        }
        break;
      default:
        LOG(FATAL) << "Unknown database backend";
      }
    }
  }
  // Read a data point, and use it to initialize the top blob.
  Datum datum;
  switch (this->layer_param_.data_param().backend()) {
  case DataParameter_DB_LEVELDB:
    datum.ParseFromString(iter_->value().ToString());
    break;
  case DataParameter_DB_LMDB:
    datum.ParseFromArray(mdb_value_.mv_data, mdb_value_.mv_size);
    break;
  default:
    LOG(FATAL) << "Unknown database backend";
  }

  // image
  int crop_size = this->layer_param_.transform_param().crop_size();
  if (crop_size > 0) {
    (*top)[0]->Reshape(this->layer_param_.data_param().batch_size(),
                       datum.channels(), crop_size, crop_size);
    this->prefetch_data_.Reshape(this->layer_param_.data_param().batch_size(),
        datum.channels(), crop_size, crop_size);
  } else {
    (*top)[0]->Reshape(
        this->layer_param_.data_param().batch_size(), datum.channels(),
        datum.height(), datum.width());
    this->prefetch_data_.Reshape(this->layer_param_.data_param().batch_size(),
        datum.channels(), datum.height(), datum.width());
  }
  LOG(INFO) << "output data size: " << (*top)[0]->num() << ","
      << (*top)[0]->channels() << "," << (*top)[0]->height() << ","
      << (*top)[0]->width();
  // label
  if (this->output_labels_) {
	// liu
    (*top)[1]->Reshape(this->layer_param_.data_param().batch_size(), 4, 1, 1);
    this->prefetch_label_.Reshape(this->layer_param_.data_param().batch_size(),
        4, 1, 1);
	/*
	(*top)[1]->Reshape(this->layer_param_.data_param().batch_size(), 1, 1, 1);
    this->prefetch_label_.Reshape(this->layer_param_.data_param().batch_size(),
								  1, 1, 1);
	*/
  }
  // datum size
  this->datum_channels_ = datum.channels();
  this->datum_height_ = datum.height();
  this->datum_width_ = datum.width();
  this->datum_size_ = datum.channels() * datum.height() * datum.width();
}
	void* DataLayerPrefetch(void* layer_pointer) {
		CHECK(layer_pointer);
		DataLayer<Dtype>* layer = static_cast<DataLayer<Dtype>*>(layer_pointer);
		CHECK(layer);
		Datum datum;
		CHECK(layer->prefetch_data_);
		Dtype* top_data = layer->prefetch_data_->mutable_cpu_data(); //数据
		Dtype* top_label;                                            //标签
		if (layer->output_labels_) {
			top_label = layer->prefetch_label_->mutable_cpu_data();
		}
		const Dtype scale = layer->layer_param_.data_param().scale();
		const int batch_size = layer->layer_param_.data_param().batch_size();
		const int crop_size = layer->layer_param_.data_param().crop_size();
		const bool mirror = layer->layer_param_.data_param().mirror();

		if (mirror && crop_size == 0) {//当前实现需要同时设置mirror和cropsize
			LOG(FATAL) << "Current implementation requires mirror and crop_size to be "
				<< "set at the same time.";
		}
		// datum scales
		const int channels = layer->datum_channels_;
		const int height = layer->datum_height_;
		const int width = layer->datum_width_;
		const int size = layer->datum_size_;
		const Dtype* mean = layer->data_mean_.cpu_data();
		
		for (int item_id = 0; item_id < batch_size; ++item_id) {
			//每一批数据的数量是batchsize,一个循环拉取一张

			// get a blob
			CHECK(layer->iter_);
			CHECK(layer->iter_->Valid());
			datum.ParseFromString(layer->iter_->value().ToString());//利用迭代器拉取下一批数据
			const string& data = datum.data();

			int label_blob_channels = layer->prefetch_label_->channels();
			int label_data_dim = datum.label_size();
			CHECK_EQ(layer->prefetch_label_->channels(), datum.label_size()) << "label size is NOT the same.";
			
			if (crop_size) {//如果需要裁剪  
				CHECK(data.size()) << "Image cropping only support uint8 data";
				int h_off, w_off;
				// We only do random crop when we do training.
				//只是在训练阶段做随机裁剪 
				if (layer->phase_ == Caffe::TRAIN) {
					h_off = layer->PrefetchRand() % (height - crop_size);
					w_off = layer->PrefetchRand() % (width - crop_size);
				} else {//测试阶段固定裁剪
					h_off = (height - crop_size) / 2;
					w_off = (width - crop_size) / 2;
				}
				//怎么感觉下面两种情况的代码是一样的? 
				if (mirror && layer->PrefetchRand() % 2) {
					// Copy mirrored version
					for (int c = 0; c < channels; ++c) {
						for (int h = 0; h < crop_size; ++h) {
							for (int w = 0; w < crop_size; ++w) {
								int top_index = ((item_id * channels + c) * crop_size + h)
									* crop_size + (crop_size - 1 - w);
								int data_index = (c * height + h + h_off) * width + w + w_off;
								Dtype datum_element =
									static_cast<Dtype>(static_cast<uint8_t>(data[data_index]));
								top_data[top_index] = (datum_element - mean[data_index]) * scale;
							}
						}
					}
				} else {//如果不需要裁剪  
					// Normal copy
					//我们优先考虑data(),然后float_data() 
					for (int c = 0; c < channels; ++c) {
						for (int h = 0; h < crop_size; ++h) {
							for (int w = 0; w < crop_size; ++w) {
								int top_index = ((item_id * channels + c) * crop_size + h)
									* crop_size + w;
								int data_index = (c * height + h + h_off) * width + w + w_off;
								Dtype datum_element =
									static_cast<Dtype>(static_cast<uint8_t>(data[data_index]));
								top_data[top_index] = (datum_element - mean[data_index]) * scale;
							}
						}
					}
				}
			} else {
				// we will prefer to use data() first, and then try float_data()
				if (data.size()) {
					for (int j = 0; j < size; ++j) {
						Dtype datum_element =
							static_cast<Dtype>(static_cast<uint8_t>(data[j]));
						top_data[item_id * size + j] = (datum_element - mean[j]) * scale;
					}
				} else {
					for (int j = 0; j < size; ++j) {
						top_data[item_id * size + j] =
							(datum.float_data(j) - mean[j]) * scale;
					}
				}
			}

		
			if (g_item_id++ < 5)
			{
				int label_size = datum.label_size();	
				int image_label = 0;
				for (int j = 0; j < label_size; ++j) {
					if (datum.label(j) == 1)
					{
						image_label = j;
						break;
					}
				}	
				
				char strImgRawDataFile[255] = "";
				sprintf(strImgRawDataFile, "caffe_%s_%05d_%d%s", "train", item_id, image_label, ".txt");
				ofstream fout_image_raw_data(strImgRawDataFile);

				for (int h = 0; h < height; ++h) {
					for (int w = 0; w < width; ++w) {
						int pixel_index = h * height + w;
						Dtype datum_element = static_cast<Dtype>(static_cast<uint8_t>(data[pixel_index]));

						char strHexByte[3] = "";
						sprintf(strHexByte, "%02X", (unsigned char)datum_element);
						fout_image_raw_data<<" "<<strHexByte;
					}
					
					fout_image_raw_data<<endl;
				}
				
				fout_image_raw_data<<endl;
				for (int j = 0; j < label_size; ++j) {
					fout_image_raw_data<<datum.label(j);
				}	

				fout_image_raw_data.close();
			}
		
			if (layer->output_labels_) {
				int label_size = datum.label_size();				
				for (int j = 0; j < label_size; ++j) {
					top_label[item_id * label_size + j] = datum.label(j);
				}				
				//top_label[item_id] = datum.label();
			}
			
			// go to the next iter
			layer->iter_->Next();
			if (!layer->iter_->Valid()) {
				// We have reached the end. Restart from the first.
				DLOG(INFO) << "Restarting data prefetching from start.";
				layer->iter_->SeekToFirst();
			}
		}

		return static_cast<void*>(NULL);
	}
int GetGlobleChannelMean(int argc, char** argv)
{

#ifdef USE_OPENCV
#ifndef GFLAGS_GFLAGS_H_
	namespace gflags = google;
#endif

	gflags::SetUsageMessage("Compute the mean_image of a set of images given by"
		" a leveldb/lmdb\n"
		"Usage:\n"
		"    compute_image_mean [FLAGS] INPUT_DB [OUTPUT_FILE]\n");

	gflags::ParseCommandLineFlags(&argc, &argv, true);

	if (argc < 2 || argc > 3) {
		gflags::ShowUsageWithFlagsRestrict(argv[0], "tools/compute_image_mean");
		return 1;
	}

	scoped_ptr<db::DB> db(db::GetDB(FLAGS_backend));
	db->Open(argv[1], db::READ);
	scoped_ptr<db::Cursor> cursor(db->NewCursor());

	double sum_channels[3] = { 0 };
	double sum_pixels = 0;

	int count = 0;
	LOG(INFO) << "Starting Iteration";
	while (cursor->valid()) {
		Datum datum;
		datum.ParseFromString(cursor->value());
		cv::Mat mat = DecodeDatumToCVMatNative(datum);

		vector<cv::Mat> chmats;
		split(mat, chmats);
		if (chmats.size() == 3)
		{
			for (int i = 0; i < 3;i++)
			{
				cv::Scalar sumch = sum(chmats[i]);
				sum_channels[i] += sumch(0);
			}
			sum_pixels += chmats[0].cols*chmats[0].rows;
		
		}
		else if (chmats.size() == 1)
		{
			cv::Scalar sumch = sum(chmats[0]);
			sum_channels[0] += sumch(0);
			sum_channels[1] += sumch(0);
			sum_channels[2] += sumch(0);
			sum_pixels += chmats[0].cols*chmats[0].rows;
		}

		++count;
		if (count % 10000 == 0) {
			LOG(INFO) << "Processed " << count << " files." << "channel means: "
				<< sum_channels[0] / sum_pixels << ","
				<< sum_channels[1] / sum_pixels << ","
				<< sum_channels[2] / sum_pixels;
		}
		cursor->Next();
	}

	if (count % 10000 != 0) {
		LOG(INFO) << "Processed " << count << " files.";
	}
	// Write to disk
	if (argc == 3) {
		LOG(INFO) << "Write to " << argv[2];
		std::ofstream ofs(argv[2]);
		ofs << sum_channels[0] / sum_pixels << std::endl;
		ofs << sum_channels[1] / sum_pixels << std::endl;
		ofs << sum_channels[2] / sum_pixels << std::endl;
	}
	
#else
	LOG(FATAL) << "This tool requires OpenCV; compile with USE_OPENCV.";
#endif  // USE_OPENCV
	return 0;
}