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

时间: 2024-10-16 10:07:41

Caffe 多目标输出探究的相关文章

makefile--统一目标输出目录 (六)

原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/ 上一节我们把规则单独提取出来,方便了Makefile的维护,每个模块只需要给出关于自己的一些变量,然后再使用统一的规则Makefile.这一节我 们继续改进我们的Makefile,到目前为止我们的Makefile编译链接输出的目标都在源文件同目录下或模块Makefile同一目录下,当一个项 目大了之后,这样会显得很乱,寻找编译输出的文件也比较困难.既然Makefile本身就是按照我们的的规则来

从头开始写项目Makefile(七):统一目标输出目录

[版权声明:转载请保留出处:blog.csdn.net/gentleliu.Mail:shallnew at 163 dot com] 上一节我们把规则单独提取出来,方便了Makefile的维护,每个模块只需要给出关于自己的一些变量,然后再使用统一的规则Makefile.这一节我们继续改进我们的Makefile,到目前为止我们的Makefile编译链接输出的目标都在源文件同目录下或模块Makefile同一目录下,当一个项目大了之后,这样会显得很乱,寻找编译输出的文件也比较困难.既然Makefil

从头開始写项目Makefile(七):统一目标输出文件夹

[版权声明:转载请保留出处:blog.csdn.net/gentleliu. Mail:shallnew at 163 dot com] 上一节我们把规则单独提取出来,方便了Makefile的维护,每一个模块仅仅须要给出关于自己的一些变量,然后再使用统一的规则Makefile.这一节我们继续改进我们的Makefile,到眼下为止我们的Makefile编译链接输出的目标都在源文件同文件夹下或模块Makefile同一文件夹下.当一个项目大了之后,这样会显得非常乱,寻找编译输出的文件也比較困难. 既然

日志输出法则

运行日志应用场景 原型迭代过程 该场景下,一定需要日志输出.原因很显然,因为是个迭代过程,整体结构模型并不明确,一些逻辑都不是很可靠的,故需要提供一个侧面可供观察程序运行动态. 二次开发 二次开发一般也是采用一种原型来迭代完成的.即便不是基于原型迭代变化,那日志观察则更是需要,至少依赖平台的一些调用我们需要观察.程序员一般对于不是自己定义的逻辑都是不能完全信任的.除非有可靠评测数据. 对于有单元测试的依赖项 有单元测试,那就是说有可信可靠的评测数据.对于这部分依赖项,同二次开发说明的,那我们只管

tomcat--catalina-daemon.out日志分割和输出等级控制

为了更加安全,生产环境中我更加青睐把tomcat 使用 jsvc 以守护进程的方式启动(daemon.sh ).这样tomcat自身将会生成另外一个日志文件(catalina-daemon.out),而不是之前的catalina.out.但是随之出现2个问题:1.catalina-daemon.out这个文件不会自动切割,而且会无线增大.2.catalina-daemon.out里面log输出等级无法更改,大量info信息占据了磁盘.为了针对这两个问题特意研究了一番,研究过程因功力尚浅所以并不专

【Listener】利用监听器Listener以MVC的思想通过JSP+Servlet+JDBC完成在线用户列表的输出

Servlet,监听器Listener与<[Filter]拦截器Filter>(点击打开链接)是JSP的三大核心组件,实际上监听器Listener相当于数据库里面的触发器,一旦用户触发了某种行为,则可以通过相关的Java文件执行相应的程序.用户在浏览网页的过程中,主要有打开浏览器的动作,对应的行为是Session的创建,可是,用户关闭浏览器的动作,并不是对应Session的消失,因此对于Session的消失我们意义不大:访问任意网页的动作,对应的行为是request请求的创建,request的

目标检测lmdb数据格式制作

一.任务 现在用caffe做目标检测一般需要lmdb格式的数据,而目标检测的数据和目标分类的lmdb格式的制作难度不同.就目标检测来说,例如准备SSD需要的数据,一般需要以下几步: 1.准备图片并标注groundtruth 2.将图像和txt格式的gt转为VOC格式数据 3.将VOC格式数据转为lmdb格式数据 本文的重点在第2.3步,第一步标注任务用小代码实现即可.网络上大家制作数据格式一般是仿VOC0712的,建立各种目录,很麻烦还容易出错,现我整理了一下代码,只要两个代码,就可以从图片+t

anaconda 安装caffe,cntk,theano-未整理

一,anancona 安装 https://repo.anaconda.com/archive/ conda create -n caffe_gpu -c defaults python=3.6 caffe-gpu conda create -n caffe -c defaults python=3.6 caffe 测试: import caffe python -c "import caffe; print dir(caffe)" 参考:https://blog.csdn.net/w

从软件工程的角度写机器学习6——深度学习之卷积神经网络(CNN)实现

卷积神经网络(CNN)实现 背景 卷积神经网络广泛用于图像检测,它的实现原理与传统神经网络基本上是一样的,因此将普遍意义的神经网络和卷积神经网络的实现合成一篇. 神经网络实现思路 "扔掉神经元" 尽管所有教程在介绍神经网络时都会把一大堆神经元画出来,并且以输入节点--神经元--输出结点连线,但是,在编程实现时,基于神经元去编程是低效的.典型如这篇经典文章里面的代码: http://blog.csdn.net/zzwu/article/details/575125. 比较合适的方法是将神