【Caffe实践】 多目标输出探究

来源:互联网 发布:windows可以不激活码 编辑:程序博客网 时间:2024/05/20 09:48

正常的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格式即可。

0 0