【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格式即可。

你可能感兴趣的:(【Caffe实践】 多目标输出探究)