在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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM