• 在caffe中使用hdf5的数据


    caffe默认使用的数据格式为lmdb文件格式,它提供了把图片转为lmdb文件格式的小程序,但是呢,我的数据为一维的数据,我也要分类啊,那我怎么办?肯定有办法可以转为lmdb文件格式的,我也看了一些源代码,好像是把我们的数据变为Datum的格式(这是一个用google protocol buffer搞的一个数据结构类),然后再把它存为lmdb文件。在Datum里面,label为Int类型,要是我们label为符点数,我还怎么用??(不过看到Datum里面有个float_data的东西,怎么用啊,不懂)。好吧,费了一劲想把转换Mnist的程序为我用,是有点成功,不过太麻烦,好像不怎么好使。   最后,用hdf5格式的数据吧。好在网络有好多资料哦,牛逼的人好多的哦,我实在是很膜拜他们。下面说说怎么转。我用的是matlab转,网络也有好多用python程序的。

    以转Mnist 为例,我们以后可以照着写出自己的来。

    %读入训练数据,下面的函数loadMNISTImages是一个自己的函数,如果你想要的话,可以去gitbub上下载(看 %参考文献里有, 读完以后,这时,images为一个28*28*
    50000的3D数组;
    images = loadMNISTImages('train-images-idx3-ubyte');
    
    %读完后,labels为一个50000*
    1的数组;
    labels = loadMNISTLabels('train-labels-idx1-ubyte');
    
    
    % reshape images to 4-
    D: [rows,col,channel,numbers]
    
    trainData=reshape(images,[28 28 1 size(images,2)]);
    
    
    %
     permute to [cols,rows,channel,numbers]
    
    trainData=permute(trainData,[2 1 3 4]);
    
    
    %
     permute lables to [labels, number of labels ]
    
    trainLabels=permute(labels,[2,1]);
    
    
    %
     create database
    %注意,这是的/data与/label表示文件里的dataset.当我们定义.proto文件的网络时,一定要注意:top:分别也要为data和label.
    h5create('train.hdf5','/data',size(trainData),'Datatype','double');
    
    h5create('train.hdf5','/label',size(trainLabels),'Datatype','double');
    
    h5write('train.hdf5','/data',trainData);
    
    h5write('train.hdf5','/label',trainLabels);
    
    
    % same for test data

    生成文件以后,可以通过h5disp(’文件名‘)看看里面的东西。下面是我自己生成的文件里的内容,不是上面生成的哦;

    >> h5disp('train.hdf5')
    HDF5 train.hdf5 
    Group '/' 
        Dataset 'data' 
            Size:  256x1x1x200
            MaxSize:  256x1x1x200
            Datatype:   H5T_IEEE_F64LE (double)
            ChunkSize:  []
            Filters:  none
            FillValue:  0.000000
        Dataset 'label' 
            Size:  1x200
            MaxSize:  1x200
            Datatype:   H5T_IEEE_F64LE (double)
            ChunkSize:  []
            Filters:  none
            FillValue:  0.000000

    再往下,就是.proto文件里的data的定义了,下面是我的定义自己的:

    2 layer {
      3   name: "mnist"
      4   type: "HDF5Data"
      5   top: "data"        //一定要和上面的dataset的名字一样哦;
      6   top: "label"
      7   include {
      8     phase: TRAIN
      9   }
     13   hdf5_data_param {
     14     source: "mydata/train_list.txt"    //是个坑哦,下面下面解释;
     15     batch_size: 200
     17   }

    注意:

    第一,再生成HDF5文件时,一定要注意数组的维度关系,很敏感的,如,把1*50000写为了50000*1肯定会出错的。在caffe中,数据都是以4维出现的。(我记得python与matlab里的维度是正反的,python与C语言中都是rowmajor, matlab中是 column-major, 相应的就是, matlab是一组维度中,左边的数字变化最快,,而python中为右边。好像是这样的)

    第二,生成的HDF5的dataset的名称一定要与你后面定义的.proto文件里的data层的top:后面的名称(即输出的名称)一样啊,要不出错,找不到数据的)。

    第三,在定义.proto文件里的data层时注意,hdf5_data_param的source不要直接写我们生成的HDF5文件的路径,而是写一个.txt文件的,并在.txt文件里写入你生成的HDF5文件的路经,一个HDF5文件路径占一行,一定要这样哦。原因是因为,我们可以要读入多个HDF5文件,所以要这样写哦。

    第四,生成的HDF5文件一般都很大,如果是图片的话,可以很多的,HDF5Data layer不能按照batch来从磁盘上读取数据,只能一次性把所有数据从h5文件中读到内存中,如果出错了,很可以你的内存不够了哦;

    第五,HDF5Data layer不支持预处理功能。

    一开始吧, 我老是想一个总是,当读取HDF5文件时,它是怎么知道包含有多少个数据的,现在想想,HDF5文件肯定写入了相关的数据结构相关的内容啊,看看上面的h5disp()的输出,我们就知道啦。

    其实上面这个问题,我一开始是在想使用lmdb文件时,它把数据写入的Datum中,在Datum文件中,放数据的为bytes格式,我再想,它怎么知道一个数据占多少个byte的呢??Datum里也没有这个选项。现在还是不明白,如果这个问题明白了,我就可以把数据转为lmdb文件了,但是我始终没有找到由datum变为数据的源代码呢??

    如果好心人看到了,请帮我解答一下子哦;

    参考:

    https://github.com/mravendi/caffe-mnist-hdf5

    http://blog.csdn.net/langb2014/article/details/53065153

    http://blog.csdn.net/u010417185/article/details/53047096

  • 相关阅读:
    哪有什么互联网寒冬?只是你穿的少而已!
    我不是机器人:谷歌最新版验证码系统ReCaptcha破解已开源
    Gradle更小、更快构建APP的奇淫技巧
    一篇文章让你了解Android各个版本的历程
    快速开发android,离不开这10个优秀的开源项目
    年底Android面试整理(附答案)
    最近Android真的凉凉了?
    Android 应用防止被二次打包指南
    开发了5年android,我开始了go学习之旅
    做了5年的Android,我转Java后台了!
  • 原文地址:https://www.cnblogs.com/yinheyi/p/6083855.html
Copyright © 2020-2023  润新知