【Caffe實踐】 多目標輸出探究

正常的CNN,其輸入是圖像,其輸出是一個label整數,其正是用Caffe的底層數據Datum(Image,LMDB,LevelDB的基礎)來表示

message Datum {
  optional int32 channels = 1;
  optional int32 height = 2;
  optional int32 width = 3;
  // the actual image data, in bytes
  optional bytes data = 4;
  optional int32 label = 5;
  // Optionally, the datum could also hold float data.
  repeated float float_data = 6;
  // If true data contains an encoded image that need to be decoded
  optional bool encoded = 7 [default = false];
}

當數據讀入的時候,其是通過

CVMatToDatum(cv_img, datum);
datum->set_label(label);

所以,Image輸入,LevelDB輸入,LMDB輸入,不能解決多輸出問題(改動代碼,對其它代碼的影響比較大)

在HDF5作爲輸入中,其是接受多輸出的,但其只能接受double和float的輸入,但是我們的圖像一般是0–255的,所以其實只要用int8 就可以滿足了,可以節省4-8倍的空間。

而hdf5只能是float和double的原因在於,其是直接將4維數組轉化爲blob數據結構。

  blob->Reshape(
    dims[0],
    (dims.size() > 1) ? dims[1] : 1,
    (dims.size() > 2) ? dims[2] : 1,
    (dims.size() > 3) ? dims[3] : 1);

雖然Blob是一個模板,但是,其unsigned int 和int的類型都沒有實現

template <> void Blob<unsigned int>::Update() 
{ NOT_IMPLEMENTED; }
template <> void Blob<int>::Update() 
{ NOT_IMPLEMENTED; }

沒有實現的原因,是因爲輸入數據和裏面的所有的中間數據都採用相同的結構(Blob),所以如果用int來保存的化,就沒有辦法進行求梯度等操作。

//The "update" method is used for parameter blobs in a Net, which are stored
//as Blob<float> or Blob<double> -- hence we do not define it for
//Blob<int> or Blob<unsigned int>.

template <> unsigned int Blob<unsigned int>::asum_data() const 
{
  NOT_IMPLEMENTED;
  return 0;
}

template <> int Blob<int>::asum_data() const 
{
  NOT_IMPLEMENTED;
  return 0;
}
template <> unsigned int Blob<unsigned int>::asum_diff() const 
{
  NOT_IMPLEMENTED;
  return 0;
}

template <> int Blob<int>::asum_diff() const 
{
  NOT_IMPLEMENTED;
  return 0;
}
template <> unsigned int Blob<unsigned int>::sumsq_data() const 
{
  NOT_IMPLEMENTED;
  return 0;
}

template <> int Blob<int>::sumsq_data() const 
{
  NOT_IMPLEMENTED;
  return 0;
}
template <> unsigned int Blob<unsigned int>::sumsq_diff() const 
{
  NOT_IMPLEMENTED;
  return 0;
}

template <> int Blob<int>::sumsq_diff() const 
{
  NOT_IMPLEMENTED;
  return 0;
}
template <> void Blob<unsigned int>::scale_data(unsigned int scale_factor) 
{
  NOT_IMPLEMENTED;
}

template <> void Blob<int>::scale_data(int scale_factor) 
{
  NOT_IMPLEMENTED;
}
template <> void Blob<unsigned int>::scale_diff(unsigned int scale_factor) 
{
  NOT_IMPLEMENTED;
}

template <> void Blob<int>::scale_diff(int scale_factor) 
{
  NOT_IMPLEMENTED;
}

HDF5最大的缺點在於,因爲其是直接將數據轉化爲Blob,所以其不能利用所有的DataTransformer功能,因爲數據轉換層又是基於Datum或者圖像cv::Mat來轉換.(最近加了直接對Blob的轉換)
解決方案:
1. 自己添加一層DataBlob層來實現。
2. 直接存儲uint8格式,HDF5輸入的時候,強制轉化爲float格式即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章