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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

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

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

前言

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

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

國際慣例,參考博客:

caffe HDF5Data 層使用及數(shù)據(jù)生成

解讀創(chuàng)建hdf5的matlab程序

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

  • 前面說過一個(gè)數(shù)據(jù)集可以放入不同的hdf5文件中,那么我們肯定要現(xiàn)指定當(dāng)前的數(shù)據(jù)存在哪個(gè)hdf5文件中
filename='trial.h5';
  • 由于自帶的程序中沒有調(diào)用指定數(shù)據(jù)集,所以事先隨機(jī)生成了一系列樣本
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);

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

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

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

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

    看不懂沒關(guān)系,接著往下讀代碼

    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);

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

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

    也就是從totalct+1個(gè)數(shù)據(jù)的第1行第1列第1個(gè)通道開始讀取,標(biāo)簽同理

  • 接下來就是存儲(chǔ)每批數(shù)據(jù)到最開始指定的trial.h5文件中了

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

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

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

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

    【注】代碼靈活多變,請(qǐng)不要循環(huán)類似于“為什么函數(shù)store2hdf5用~created_flag而不把非號(hào)去掉?”諸如此類的問題。

  • 后面有一行代碼用于展示存儲(chǔ)的hdf5數(shù)據(jù)情況

    h5disp(filename);

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

    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
  • 這樣還不夠,我們還得檢測一下數(shù)據(jù)是不是真的是我們輸入的數(shù)據(jù),也就是一致性

    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

    ? 可以發(fā)現(xiàn)讀取了存儲(chǔ)的trial.h5文件中從第[1 1 1 1000]個(gè)數(shù)據(jù)開始的隨后1000個(gè)每個(gè)大小[5,5,1]的數(shù)據(jù)。其實(shí)也就是按照[5,5,1]從第1000個(gè)樣本的第一個(gè)數(shù)值讀,總共讀1000個(gè)就行了,即完成了讀取第1000-1999的樣本數(shù)據(jù)和標(biāo)簽。隨后在try catch語句中判斷這讀出來的和我們?cè)紨?shù)據(jù)data_disk和label_disk是不是對(duì)應(yīng)的,是就返回Success!,錯(cuò)誤的話不僅返回Test failed ...而且還有錯(cuò)誤原因,非常便于調(diào)試。

  • 最后,當(dāng)然就是指示一下我們的hdf5文件名字是什么,為什么用txt文檔存?因?yàn)榍懊嬉呀?jīng)說了,一個(gè)大的數(shù)據(jù)集一般存在多個(gè)hdf5中,換行存儲(chǔ)就行。自帶源碼只存儲(chǔ)到了一個(gè)hdf5文件中,因而對(duì)應(yīng)的list.txt存儲(chǔ)只有一行,那就是:

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

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

    制作訓(xùn)練集

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

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

    • 數(shù)據(jù)集的讀取

      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]);%將數(shù)據(jù)集讀取出來(高*寬*通道*樣本數(shù))
    • 圖片寬高翻轉(zhuǎn)和標(biāo)簽的行列變換

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

      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以及測試數(shù)據(jù)對(duì)應(yīng)的二進(jìn)制文件即可。

      %% WRITING TO HDF5 clear clc filename='train.h5';%可改test.h5% data = loadMNISTImages('train-images-idx3-ubyte')';%可改test的數(shù)據(jù)集 % labels = loadMNISTLabels('train-labels-idx1-ubyte');%可改test的標(biāo)簽 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]);%將數(shù)據(jù)集讀取出來(高*寬*通道*樣本數(shù)) %由于caffe正常的處理方法是opencv讀取圖片,與matlab的高寬相反 data_disk=permute(data_disk,[2 1 3 4]);%翻轉(zhuǎn)matlab讀取的高寬 label_disk=permute(labels,[2 1]);%轉(zhuǎn)換為caffe標(biāo)簽的輸入格式(類別數(shù)*總樣本數(shù)) % 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 % } % }

      運(yùn)行結(jié)果,總共600個(gè)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為輸入進(jìn)行訓(xùn)練

      把原始的lenet_train_test.prototxt的前兩個(gè)’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 } }

      寫個(gè)bat文件訓(xùn)練試試

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

      截取了部分運(yùn)行過程

      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手寫數(shù)字:鏈接:http://pan.baidu.com/s/1jHYCQJ8 密碼:vaeo
      后續(xù)研究將擴(kuò)展到多標(biāo)簽中,預(yù)先參考文獻(xiàn)戳這里
      ?

    總結(jié)

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

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。