日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

【caffe-Windows】以mnist为例的hdf5单标签处理——matlab实现

發布時間:2023/12/13 windows 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【caffe-Windows】以mnist为例的hdf5单标签处理——matlab实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

主要是想嘗試看一下多標簽的caffe是如何進行輸入輸出的,但是目前還未找到基于原始caffe做多標簽輸入的代碼,大部分都是基于源碼做了一部分修改實現多標簽分類,caffe官網倒是有一個多標簽的Python程序,這個我慢慢研究研究,此篇博客先看看單標簽的數據格式制作與訓練,以hdf5和mnist數據集為例吧

【注】使用hdf5的好處有三個:①相對于前面制作的lmdb和leveldb數據集,用convert的那個代碼轉換前,一般都要求一張圖片一個標簽,也就是說貓圖片的標簽必須是“貓”,而不是”綠“、“貓”,而hdf5的數據格式就能支持后者,一張圖片可有多個標簽描述。②當我們的數據是非圖片類型的,比如一維聲音數據,也能用hdf5制作滿足caffe輸入的數據集。③當程序無法一次性讀取太大的數據集,我們可以將數據集分別放到不同的hdf5文件

國際慣例,參考博客:

caffe HDF5Data 層使用及數據生成

解讀創建hdf5的matlab程序

在caffe中自帶了hdf5的處理程序,我們先來研究研究,然后再套入mnist數據集。

  • 前面說過一個數據集可以放入不同的hdf5文件中,那么我們肯定要現指定當前的數據存在哪個hdf5文件中
filename='trial.h5';
  • 由于自帶的程序中沒有調用指定數據集,所以事先隨機生成了一系列樣本
num_total_samples=10000; % to simulate data being read from disk / generated etc. data_disk=rand(5,5,1,num_total_samples); label_disk=rand(10,num_total_samples);

? 需要注意的是這個數據集的格式,data_disk的每個維度分別代表寬、高、通道數、樣本數,剛好符合opencv的讀取方式,而matlab讀取圖片的方式是高、寬,與這個剛好相反,所以用自己的數據集記得要翻轉前兩個維度,待會再說。此外label_disk的兩個維度分別是標簽的單熱度編碼、樣本數,與我們的習慣也相反,我們習慣一行一個標簽,而這里是一列是一個樣本的標簽。

然后我們看看到底是怎么寫入文件的?

  • 定義了三個變量,分別是每次讀取的數據大小,是否覆蓋寫入原來的hdf5文件(1/0)

    chunksz=100; created_flag=false; totalct=0;

    看不懂沒關系,接著往下讀代碼

    fprintf('batch no. %d\n', batchno);last_read=(batchno-1)*chunksz;% to simulate maximum data to be held in memory before dumping to hdf5 file batchdata=data_disk(:,:,1,last_read+1:last_read+chunksz); batchlabs=label_disk(:,last_read+1:last_read+chunksz);

    這里就是按照事先設置的chunksz分批讀取數據。比如第一次讀取第1-100個數據,第二次就是101-200,以此類推,當然讀取數據的時候,雖然從每批的第一個數據(1/101/201…)開始讀,但是有時候我們需要從這個數據的第m個樣本的第n行第m列開始讀,所以提供了這樣一個結構體,用于指示讀取數據的開始位置

    startloc=struct('dat',[1,1,1,totalct+1], 'lab', [1,totalct+1]);

    也就是從totalct+1個數據的第1行第1列第1個通道開始讀取,標簽同理

  • 接下來就是存儲每批數據到最開始指定的trial.h5文件中了

    curr_dat_sz=store2hdf5(filename, batchdata, batchlabs, ~created_flag, startloc, chunksz);

    有興趣可以看看store2hdf5的源碼,這里分別介紹一下幾個參數的含義:

    • filename:存儲的hdf5文件名稱
    • batchdata:讀取的數據,一般是四個維度(寬、高、通道、批大小
    • batchlabs:讀取的批數據對應的輸出,可以是標簽也可以是其它的東東,兩維(類別、批大小)
    • created_flag:是否覆蓋寫入(0不覆蓋,1覆蓋),一般來說第一個批次肯定是覆蓋寫入(~false=1)
    • startloc:前面說的第一個數據開始位置
    • chunksz:批大小
    • curr_dat_sz:返回值,四維(寬、高、通道、已寫入樣本數)
  • 接下來兩個就是重置3中的下一個讀取數據的位置totalct和4中的是否覆蓋寫入為否(0=~true)

    created_flag=true;% flag set so that file is created only oncetotalct=curr_dat_sz(end);% updated dataset size (#samples)

    【注】代碼靈活多變,請不要循環類似于“為什么函數store2hdf5用~created_flag而不把非號去掉?”諸如此類的問題。

  • 后面有一行代碼用于展示存儲的hdf5數據情況

    h5disp(filename);

    自帶的程序輸出如下,一般我們核對核對大小和樣本數就行咯:

    HDF5 trial.h5 Group '/' Dataset 'data' Size: 5x5x1x10000MaxSize: 5x5x1xInfDatatype: H5T_IEEE_F32LE (single)ChunkSize: 5x5x1x100Filters: noneFillValue: 0.000000Dataset 'label' Size: 10x10000MaxSize: 10xInfDatatype: H5T_IEEE_F32LE (single)ChunkSize: 10x100Filters: noneFillValue: 0.000000
  • 這樣還不夠,我們還得檢測一下數據是不是真的是我們輸入的數據,也就是一致性

    data_rd=h5read(filename, '/data', [1 1 1 1000], [5, 5, 1, 1000]); label_rd=h5read(filename, '/label', [1 1000], [10, 1000]); fprintf('Testing ...\n'); try assert(isequal(data_rd, single(data_disk(:,:,:,1000:1999))), 'Data do not match');assert(isequal(label_rd, single(label_disk(:,1000:1999))), 'Labels do not match');fprintf('Success!\n'); catch errfprintf('Test failed ...\n');getReport(err) end

    ? 可以發現讀取了存儲的trial.h5文件中從第[1 1 1 1000]個數據開始的隨后1000個每個大小[5,5,1]的數據。其實也就是按照[5,5,1]從第1000個樣本的第一個數值讀,總共讀1000個就行了,即完成了讀取第1000-1999的樣本數據和標簽。隨后在try catch語句中判斷這讀出來的和我們原始數據data_disk和label_disk是不是對應的,是就返回Success!,錯誤的話不僅返回Test failed ...而且還有錯誤原因,非常便于調試。

  • 最后,當然就是指示一下我們的hdf5文件名字是什么,為什么用txt文檔存?因為前面已經說了,一個大的數據集一般存在多個hdf5中,換行存儲就行。自帶源碼只存儲到了一個hdf5文件中,因而對應的list.txt存儲只有一行,那就是:

    trial.h5
  • 在prototxt中使用hdf5的方法,其實也就是換掉了type類型和指定hdf5存儲的txt位置

    layer {name: "data"type: "HDF5Data"top: "data"top: "labelvec"hdf5_data_param {source: "/path/to/list.txt"batch_size: 64} }
  • 以mnist為實例創建hdf5文件

    制作訓練集

    去顯示mnist手寫數字這一博文中copy一下loadMNISTImages和loadMNISTLabels這兩個文件,用于讀取存儲mnist的四個二進制文件,哪四個就不說了吧t10k-images-idx3-ubyte、t10k-labels-idx1-ubyte、train-images-idx3-ubyte、train-labels-idx1-ubyte

    然后按照上面介紹的基本流程分別進行如下修改:

    • 數據集的讀取

      data = loadMNISTImages('t10k-images-idx3-ubyte')'; labels = loadMNISTLabels('t10k-labels-idx1-ubyte'); num_total_samples=size(data,1); data_disk=reshape(data,[28,28,1,num_total_samples]);%將數據集讀取出來(高*寬*通道*樣本數)
    • 圖片寬高翻轉和標簽的行列變換

      data_disk=permute(data_disk,[2 1 3 4]);%翻轉matlab讀取的高寬 label_disk=permute(labels,[2 1]);%轉換為caffe標簽的輸入格式(類別數*總樣本數)
    • 驗證一致性

      data_rd=h5read(filename, '/data', [1 1 1 1000], [28, 28, 1, 1000]); label_rd=h5read(filename, '/label', [1 1000], [1, 1000]);
    • 附上train.h5制作的完整代碼,注意test.h5的制作相同,只需替換代碼中的train為test以及測試數據對應的二進制文件即可。

      %% WRITING TO HDF5 clear clc filename='train.h5';%可改test.h5% data = loadMNISTImages('train-images-idx3-ubyte')';%可改test的數據集 % labels = loadMNISTLabels('train-labels-idx1-ubyte');%可改test的標簽 data = loadMNISTImages('train-images-idx3-ubyte')'; labels = loadMNISTLabels('train-labels-idx1-ubyte'); num_total_samples=size(data,1); data_disk=reshape(data,[28,28,1,num_total_samples]);%將數據集讀取出來(高*寬*通道*樣本數) %由于caffe正常的處理方法是opencv讀取圖片,與matlab的高寬相反 data_disk=permute(data_disk,[2 1 3 4]);%翻轉matlab讀取的高寬 label_disk=permute(labels,[2 1]);%轉換為caffe標簽的輸入格式(類別數*總樣本數) % num_total_samples=10000; % to simulate data being read from disk / generated etc. % data_disk=rand(5,5,1,num_total_samples); % label_disk=rand(10,num_total_samples); chunksz=100; created_flag=false; totalct=0; for batchno=1:num_total_samples/chunksz fprintf('batch no. %d\n', batchno); last_read=(batchno-1)*chunksz;% to simulate maximum data to be held in memory before dumping to hdf5 file batchdata=data_disk(:,:,1,last_read+1:last_read+chunksz); batchlabs=label_disk(:,last_read+1:last_read+chunksz);% store to hdf5 startloc=struct('dat',[1,1,1,totalct+1], 'lab', [1,totalct+1]); curr_dat_sz=store2hdf5(filename, batchdata, batchlabs, ~created_flag, startloc, chunksz); %1代表新建,0代表附加 created_flag=true;% flag set so that file is created only once totalct=curr_dat_sz(end);% updated dataset size (#samples) end% display structure of the stored HDF5 file h5disp(filename);%% READING FROM HDF5% Read data and labels for samples #1000 to 1999 data_rd=h5read(filename, '/data', [1 1 1 1000], [28, 28, 1, 1000]); label_rd=h5read(filename, '/label', [1 1000], [1, 1000]); fprintf('Testing ...\n'); try assert(isequal(data_rd, single(data_disk(:,:,:,1000:1999))), 'Data do not match'); assert(isequal(label_rd, single(label_disk(:,1000:1999))), 'Labels do not match');fprintf('Success!\n'); catch err fprintf('Test failed ...\n'); getReport(err) end%delete(filename);% CREATE list.txt containing filename, to be used as source for HDF5_DATA_LAYER FILE=fopen('train.txt', 'w');%可改test.txt fprintf(FILE, '%s', filename); fclose(FILE); fprintf('HDF5 filename listed in %s \n', 'list.txt');% NOTE: In net definition prototxt, use list.txt as input to HDF5_DATA as: % layer { % name: "data" % type: "HDF5Data" % top: "data" % top: "labelvec" % hdf5_data_param { % source: "/path/to/list.txt" % batch_size: 64 % } % }

      運行結果,總共600個batch:

      HDF5 test.h5 Group '/' Dataset 'data' Size: 28x28x1x60000MaxSize: 28x28x1xInfDatatype: H5T_IEEE_F32LE (single)ChunkSize: 28x28x1x100Filters: noneFillValue: 0.000000Dataset 'label' Size: 1x60000MaxSize: 1xInfDatatype: H5T_IEEE_F32LE (single)ChunkSize: 1x100Filters: noneFillValue: 0.000000 Testing ... Success! HDF5 filename listed in list.txt

      同理制作test.h5文件。

      以hdf5為輸入進行訓練

      把原始的lenet_train_test.prototxt的前兩個’layer’改一下:

      name: "LeNet" layer { name: "mnist" type: "HDF5Data" top: "data" top: "label" include {phase: TRAIN } hdf5_data_param {source: "train.txt"batch_size: 64 } } layer { name: "mnist" type: "HDF5Data" top: "data" top: "label" include {phase: TEST } hdf5_data_param {source: "test.txt"batch_size: 100 } }

      寫個bat文件訓練試試

      E:\caffeDEV1\caffe-master\Build\x64\Release\caffe.exe train --solver=lenet_solver.prototxt pause

      截取了部分運行過程

      I0621 11:01:55.571880 10520 solver.cpp:244] Train net output #0: loss = 2.29 63 (* 1 = 2.2963 loss) I0621 11:01:55.571880 10520 sgd_solver.cpp:106] Iteration 6600, lr = 0.00683784 I0621 11:01:56.463932 10520 solver.cpp:228] Iteration 6700, loss = 2.29493 I0621 11:01:56.464931 10520 solver.cpp:244] Train net output #0: loss = 2.29 493 (* 1 = 2.29493 loss) I0621 11:01:56.464931 10520 sgd_solver.cpp:106] Iteration 6700, lr = 0.00680711 I0621 11:01:57.424986 10520 solver.cpp:228] Iteration 6800, loss = 2.28502 I0621 11:01:57.425987 10520 solver.cpp:244] Train net output #0: loss = 2.28 502 (* 1 = 2.28502 loss) I0621 11:01:57.425987 10520 sgd_solver.cpp:106] Iteration 6800, lr = 0.0067767 I0621 11:01:58.465046 10520 solver.cpp:228] Iteration 6900, loss = 2.29951 I0621 11:01:58.466047 10520 solver.cpp:244] Train net output #0: loss = 2.29 951 (* 1 = 2.29951 loss) I0621 11:01:58.466047 10520 sgd_solver.cpp:106] Iteration 6900, lr = 0.0067466 I0621 11:01:59.259091 10520 solver.cpp:337] Iteration 7000, Testing net (#0) I0621 11:01:59.883127 10520 solver.cpp:404] Test net output #0: accuracy = 0 .1049 I0621 11:01:59.884127 10520 solver.cpp:404] Test net output #1: loss = 2.385 52 (* 1 = 2.38552 loss) I0621 11:01:59.889127 10520 solver.cpp:228] Iteration 7000, loss = 2.29426 I0621 11:01:59.889127 10520 solver.cpp:244] Train net output #0: loss = 2.29 426 (* 1 = 2.29426 loss) I0621 11:01:59.889127 10520 sgd_solver.cpp:106] Iteration 7000, lr = 0.00671681

      好了,附件打包:

      程序和prototxt以及bat下載地址: 鏈接:http://pan.baidu.com/s/1hr4UM2o 密碼:bqiy

      mnist手寫數字:鏈接:http://pan.baidu.com/s/1jHYCQJ8 密碼:vaeo
      后續研究將擴展到多標簽中,預先參考文獻戳這里
      ?

    總結

    以上是生活随笔為你收集整理的【caffe-Windows】以mnist为例的hdf5单标签处理——matlab实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。