【caffe-Windows】训练自己数据——数据集格式转换
前言
看了mnist和cifar的實例,是不是想我們現實中一般都是一張張的圖片,和實例里面都不一樣呢?那么如何來進行訓練呢?為了能夠簡便點,我們就不自己去采集數據集了,因為第一自己采集的數據集量可能不夠,第二,采集的數據集可能標注有很大問題,比如噪聲太多等,第三針對每一種數據,我相信有不同的模型去進行classification,并不是一味地套用別人的模型,當然也可以在別人基礎上做微調fine tuning。
在這一個教程中,我們利用cifar數據集去模擬現實中的訓練。
如果你有自己的數據,可直接進行第二步
第一步
cifar數據集的可視化。讀者如果有自己數據集,可以忽視此步驟,此步驟主要用于將cifar 的數據全部轉為png圖片,并制作相應標簽。
先看看我的代碼的目錄結構:
 
接下來介紹每一個文件的由來:
①test和train文件夾是我用來存儲cifar每一張圖片的位置,一個是訓練集、一個是測試集
②幾個mat文件,從cifar的官網去下載matlab version的數據集,解壓就可以得到。
③幾個.m文件就是我們用來可視化以及圖片轉存的代碼。
下面看這幾個程序:
ReadImage.m
function image = ReadImage( data ) %data是一維的,1*3072,轉換為32*32*3的圖片 image(:,:,1)=reshape(data(1,1:1024),32,32); image(:,:,2)=reshape(data(1,1025:2048),32,32); image(:,:,3)=reshape(data(1,2049:3072),32,32); end read_train.m %cifar轉image,可視化 %N*3072維度,每1024分別代表RGB,圖像大小32*32 clear clc load('batches.meta.mat') numpic=0; fp=fopen('./train/train_labels.txt','wt');for i=1:5count=0;str=['data_batch_' num2str(i) '.mat'];fprintf('load %s\n',str);load(str)figure(1)set (gcf,'Position',[50,50,900,900], 'color','w')for j=1:size(data,1)%% 讀取圖片和標簽count=count+1;%每次可視化計數subplot位置numpic=numpic+1;%為圖片編號從1開始,規則:序號+圖片標簽(1-cat,2-frog)image=ReadImage(data(j,:));%按順序讀取圖片label=label_names{labels(j,1)+1};%讀取對應標簽名字%% 每讀100張顯示一次圖片subplot(10,10,count)image=uint8(image);imshow(image);title(label)if mod(count,100)==0count=0;pause(0.1)end%% 存儲在文件夾train中picture_name=['./train/' num2str(numpic) label '.png'];name=[num2str(numpic) label '.png'];imwrite(image,picture_name,'png')fprintf(fp,'%s %s\n',name,num2str(labels(j,1)));end end fclose(fp);read_test.m %cifar轉image,可視化 %N*3072維度,每1024分別代表RGB,圖像大小32*32 clear clc close all load('batches.meta.mat') numpic=0; fp=fopen('./test/test_labels.txt','wt'); fp1=fopen('./test/test_labels1.txt','wt'); count=0; load test_batch.mat figure(1) set (gcf,'Position',[50,50,900,900], 'color','w') for j=1:size(data,1)%% 讀取圖片和標簽count=count+1;%每次可視化計數subplot位置numpic=numpic+1;%為圖片編號從1開始,規則:序號+圖片標簽(1-cat,2-frog)image=ReadImage(data(j,:));%按順序讀取圖片label=label_names{labels(j,1)+1};%讀取對應標簽%% 每讀100張顯示一次圖片subplot(10,10,count)image=uint8(image);imshow(image);title(label)if mod(count,100)==0count=0;pause(0.1)end%% 存儲在文件夾test中picture_name=['./test/' num2str(numpic) label '.png'];name=[num2str(numpic) label '.png'];imwrite(image,picture_name,'png')fprintf(fp,'%s %s\n',name,num2str(labels(j,1)));fprintf(fp1,'%s 0\n',name); end fclose(fp); fclose(fp1);分別運動read_train和read_test,可以看到train和test文件夾會逐漸生成數據集,且均為單張圖片。
讀取完畢以后,在train里面有50000張圖片和一個標簽txt文件,test里面有10000張圖片和兩個標簽txt,一個是正確標注,一個是全標注為0。
【附cifar的幾個文件】
①matlab version的mat文件:鏈接:http://pan.baidu.com/s/1bUAgf8 密碼:wk6t
②讀取完畢的train文件夾:鏈接:http://pan.baidu.com/s/1sl5tqxR 密碼:krhn
③讀取完畢的test文件夾:鏈接:http://pan.baidu.com/s/1mhJ0vXI 密碼:o69i
好了,至此我們已經得到了現實中經常使用的數據格式。
【注】如若想掰正圖像,可以使用?qq_35446561提供的方法解決
subplot(10,10,count) image=uint8(image); image=permute(image,[2,1,3]);%加上這句話會好一些 imshow(image);當然也可以采用翻轉或者轉置等方法,MATLAB都有自帶函數去翻轉圖像。第二步
以cifar的test集的制作為例吧。
先說一下現實基礎:數據集必須分為兩個文件夾(一個train,一個test),然后每一個文件夾必須再分文件夾,每一個文件夾代表一類數據。
比如cifar,上面提取的數據分別存儲在train和test文件夾,但是并未歸類。那么,我在E:\CaffeDev\caffe-master\data\cifar10\cifar-visual\cifar10內新建一個文件夾test,然后在test內部新建了airplane、cat、frog三個文件夾,在每一個文件夾中分別放入了從第一步提取的 test 集中隨便取的對應類別的56張圖片。
還是看一下目錄結構吧
 
 
 
云盤分享可以看出目錄結構:鏈接:http://pan.baidu.com/s/1i5nuKb7 密碼:xlr4
接下來就是讀取每一張圖片,并且添加相應的數據標簽到txt里面去了,在E:\CaffeDev\caffe-master\data\cifar10\cifar-visual\cifar10新建了一個test_label.txt,然后使用matlab書寫文件寫入的代碼:
【注】一定千萬要記住,圖片名字不要有空格。
%讀取圖片,制作cifar測試集 fprintf(2,'Reading test data.... \n'); rt_data_dir = './test_cifar'; %測試集的根目錄 data_dir='test_cifar'; %標簽txt中不需要根目錄前面的./,所以新建一個變量存儲 subfolders = dir(rt_data_dir); %根目錄結構 totalclass=0;%用于存儲有類別數 fp=fopen('test_label.txt','wt'); for ii = 1:length(subfolders),subname = subfolders(ii).name;%獲取根目錄下的所有文件夾名稱%有兩個隱藏文件夾,用于./和../跳轉,讀取數據集不需要它倆if ~strcmp(subname, '.') && ~strcmp(subname, '..'),totalclass=totalclass+1;%每一個文件夾都是一個類別label_name{totalclass} = subname; %讀取此文件夾的名稱,也可以自己建立一個標簽集,依次取data = dir(fullfile(rt_data_dir, subname, '*.png')); %取出所有后綴為png的數據c_num=length(data);%當前類別有多少個數據for jj=1:c_numname=fullfile(data_dir, subname, data(jj).name);fprintf(fp,'%s %s\n',name,num2str(totalclass-1));%從0開始編號endfprintf(1,'正在處理類別:%s\n',label_name{totalclass});end end
 
主要功能就是完成了當前目錄下的test文件夾下每一個類別的全部數據的文件名(比如\test_cifar\airplane\9483airplane.png)讀取,并且寫入到txt里面。
 
第三步
轉換leveldb格式
主要調用caffe.sln編譯完畢得到的convert_imageset.exe這個程序,首先看一下使用說明
 
按照這個說明,首先是找到exe的路徑,然后是數據集文件夾,數據集標簽,轉換以后的數據存儲位置,-backend設置轉換格式(leveldb/lmdb)
【注意】如果是你自己的數據集,這個地方的標簽一定要注意,讀取的時候是按照“數據文件夾/標簽內容”依次讀取的,不然無法讀取成功。比如在下例中,如果你的標簽內容第一行為airplane\9483airplane.png,數據集文件夾是test_cifar\?那么讀取的時候就是test_cifar\airplane\9483airplane.png,但是如果標簽內容為test_cifar\airplane\9483airplane.png,那么讀取的時候就讀取test_cifar\test_cifar\airplane\9483airplane.png?,顯然讀取失敗,不存在此文件,因為前面重復了根目錄,這個地方一定要注意。
轉換數據使用的convert.bat內容如下:
E:\CaffeDev\caffe-master\Build\x64\Debug\convert_imageset.exe ./test_cifar/ test_label.txt test_leveldb -backend=leveldb pause也可以設置一下[FLAGS]重新把所有的圖像resize一下,注意caffe的輸入數據集必須是統一大小
更新日志2017-1-9
這個地方resize開始寫博客的時候寫成28*28了,導致caffe -test命令自動終止,而無測試的batch信息,改成32*32的原始大小即可了,這個大小必須和train的數據集的大小相同,不然會導致同一個模型參數,接受了不同尺寸大小的圖片輸入。
E:\CaffeDev\caffe-master\Build\x64\Debug\convert_imageset.exe --resize_width=32 --resize_height=32 ./test_cifar/ test_label.txt test_leveldb -backend=leveldb pause
 
運行時候內容如下:
E:\CaffeDev\caffe-master\data\cifar10\cifar-visual\cifar10>E:\CaffeDev\caffe-mas ter\Build\x64\Debug\convert_imageset.exe ./test_cifar/ test_label.txt test_lev eldb -backend=leveldb I1017 17:25:38.574908 16872 convert_imageset.cpp:86] A total of 168 images. I1017 17:25:38.584908 16872 db_leveldb.cpp:18] Opened leveldb test_leveldb I1017 17:25:38.768919 16872 convert_imageset.cpp:150] Processed 168 files.E:\CaffeDev\caffe-master\data\cifar10\cifar-visual\cifar10>pause 請按任意鍵繼續. . .如果顯示的讀取圖片數量為0,或者圖片不存在,那么肯定是文件夾名寫錯或者是標簽問題,確切地說,是標簽里面的路徑問題,一定要注意這一點。
【注】如果這個步驟你想轉換為lmdb格式,只需要修改-backend=lmdb即可。
轉換完畢以后可以用已經訓練好的模型來測試一下這三類模型(注意區分這時的test雖然取自val,但是作用并非val的作用,而是作為test集的,詳細自行查找機器學習三個數據集的作用):鏈接:http://pan.baidu.com/s/1jHPGMpw 密碼:g97n
第四步
總結一下,容易出錯的地方在于:
①bat 內部書寫出問題,嚴格按照第三步的幾個順序書寫
②標簽txt 內部的路徑問題,很可能與bat 所書寫的根路徑重復
訓練模型回看前面的
【caffe-Windows】cifar實例編譯之model的生成:http://blog.csdn.net/zb1165048017/article/details/51476516
 
重中之重
【更新日志】2017年5月21日11:50:28
如果是灰度圖像,一定要記得convert.bat 要加入一條信息
 
 授人以魚不如授人以漁,所以我是怎么發現這個問題的,方法就是看數據集轉換的說明書
backend: 格式就不說了,后續我會研究研究官網對caffe的輸入數據格式的轉換及對應使用
check_size: 應該是檢查是不是所有圖像都是同樣的大小
encode_type: 圖片的格式
encoded: 咳咳,這個我也不知道,后續知道了再補充,有知道的同學,可以在評論區說一下哈
gray: 是否轉換為灰度圖,一定要注意,默認不是灰度圖,也就是說就算你的圖像是灰度圖,它轉換也是當做彩色圖像轉換,這樣很容易導致你的測試數據與模型參數不匹配,只要記住,圖像是灰度的,就把gray=1打開
resize_height和resize_width: 把圖片切成你設置的大小
shuffle:隨機打亂數據和對應標簽,原因和機器學習里面一樣
附錄
順帶把mnist可視化和轉換方法打包一下了,有興趣可以下載看看,直接把mnist對應的四個文件:t10k-images-idx3-ubyte,t10k-labels-idx1-ubyte,train-images-idx3-ubyte,train-labels-idx1-ubyte放到與代碼并列的目錄即可,然后運行vis_mnist.m將可視化手寫數字存成jpg格式。
鏈接:http://pan.baidu.com/s/1cpilB4 密碼:jr5h
 
總結
以上是生活随笔為你收集整理的【caffe-Windows】训练自己数据——数据集格式转换的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 美团信用卡审批要多久?网申速度比较快!
- 下一篇: 微信亲属卡解绑不了是怎么回事?解绑亲属卡
