生活随笔
收集整理的這篇文章主要介紹了
                                
深度学习(六)caffe入门学习
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
 
                                
                            
                            
                             caffe入門學習
 
 
 原文地址:http://blog.csdn.net/hjimce/article/details/48933813
 
 作者:hjimce
 
 本文主要講解caffe的整個使用流程,適用于初級入門caffe,通過學習本篇博文,理清項目訓練、測試流程。初級教程,高手請繞道。
 
 我們知道,在caffe編譯完后,在caffe目錄下會生成一個build目錄,在build目錄下有個tools,這個里面有個可執行文件caffe,如下圖所示:
 
 
 
 
 有了這個可執行文件我們就可以進行模型的訓練,只需要學會調用這個可執行文件就可以了,這便是最簡單的caffe學習,不需要對caffe底層的東西懂太多,只需要會調參數,就可以構建自己的網絡,然后調用這個可執行文件就可以進行訓練,當然如果你不僅僅是調參數,而且想要更改相關的算法,那就要深入學習caffe的底層函數調用了,這個以后再講。本篇博文僅適合于剛入門學習caffe,高手請繞道。廢話不多說,回歸正題:
 
 一、總流程
 
 完成一個簡單的自己的網絡模型訓練預測,主要包含幾個步驟:
 
 1、數據格式處理,也就是把我們的圖片.jpg,.png等圖片以及標注標簽,打包在一起,搞成caffe可以直接方便調用的文件。后面我將具體講解如何打包自己的數據,讓caffe進行調用。
 
 2、編寫網絡結構文件,這個文件的后綴格式是.prototxt。就是編寫你的網絡有多少層,每一層有多少個特征圖,輸入、輸出……。看個例子,看一下caffe-》example-》mnist-》lenet_train_test.prototxt。這個便是手寫字體網絡結構文件了,我們需要根據自己的需要學會修改這個文件:
 
 
 
   [cpp]?view plaincopy     
 <span?style="font-size:18px;">name:?"LeNet"?? layer?{?? ??name:?"mnist"?? ??type:?"Data"???? ??top:?"data"?? ??top:?"label"?? ??include?{?? ????phase:?TRAIN????? ??}?? ??transform_param?{?? ????scale:?0.00390625????? ??}?? ??data_param?{?? ????source:?"examples/mnist/mnist_train_lmdb"???? ????batch_size:?64?????? ????backend:?LMDB?? ??}?? }?? layer?{?? ??name:?"mnist"?? ??type:?"Data"?? ??top:?"data"?? ??top:?"label"?? ??include?{?? ????phase:?TEST????? ??}?? ??transform_param?{?? ????scale:?0.00390625?? ??}?? ??data_param?{?? ????source:?"examples/mnist/mnist_test_lmdb"??? ????batch_size:?100?? ????backend:?LMDB?? ??}?? }?? layer?{?? ??name:?"conv1"????? ??type:?"Convolution"???? ??bottom:?"data"????? ??top:?"conv1"????? ??param?{?? ????lr_mult:?1????? ??}?? ??param?{?? ????lr_mult:?2?? ??}?? ??convolution_param?{?? ????num_output:?20?????? ????kernel_size:?5?????? ????stride:?1?? ????weight_filler?{?? ??????type:?"xavier"?? ????}?? ????bias_filler?{?? ??????type:?"constant"?? ????}?? ??}?? }?? layer?{?? ??name:?"pool1"?? ??type:?"Pooling"???????? ??bottom:?"conv1"????? ??top:?"pool1"?? ??pooling_param?{?? ????pool:?MAX????? ????kernel_size:?2?? ????stride:?2?? ??}?? }?? layer?{?? ??name:?"conv2"?? ??type:?"Convolution"?? ??bottom:?"pool1"?? ??top:?"conv2"?? ??param?{?? ????lr_mult:?1?? ??}?? ??param?{?? ????lr_mult:?2?? ??}?? ??convolution_param?{?? ????num_output:?50?? ????kernel_size:?5?? ????stride:?1?? ????weight_filler?{?? ??????type:?"xavier"?? ????}?? ????bias_filler?{?? ??????type:?"constant"?? ????}?? ??}?? }?? layer?{?? ??name:?"pool2"?? ??type:?"Pooling"?? ??bottom:?"conv2"?? ??top:?"pool2"?? ??pooling_param?{?? ????pool:?MAX?? ????kernel_size:?2?? ????stride:?2?? ??}?? }?? layer?{?? ??name:?"ip1"?? ??type:?"InnerProduct"?? ??bottom:?"pool2"?? ??top:?"ip1"?? ??param?{?? ????lr_mult:?1?? ??}?? ??param?{?? ????lr_mult:?2?? ??}?? ??inner_product_param?{?? ????num_output:?500?? ????weight_filler?{?? ??????type:?"xavier"?? ????}?? ????bias_filler?{?? ??????type:?"constant"?? ????}?? ??}?? }?? layer?{?? ??name:?"relu1"?? ??type:?"ReLU"?? ??bottom:?"ip1"?? ??top:?"ip1"?? }?? layer?{?? ??name:?"ip2"?? ??type:?"InnerProduct"?? ??bottom:?"ip1"?? ??top:?"ip2"?? ??param?{?? ????lr_mult:?1?? ??}?? ??param?{?? ????lr_mult:?2?? ??}?? ??inner_product_param?{?? ????num_output:?10?? ????weight_filler?{?? ??????type:?"xavier"?? ????}?? ????bias_filler?{?? ??????type:?"constant"?? ????}?? ??}?? }?? layer?{?? ??name:?"accuracy"?? ??type:?"Accuracy"?? ??bottom:?"ip2"?? ??bottom:?"label"?? ??top:?"accuracy"?? ??include?{?? ????phase:?TEST?? ??}?? }?? layer?{?? ??name:?"loss"?? ??type:?"SoftmaxWithLoss"?? ??bottom:?"ip2"?? ??bottom:?"label"?? ??top:?"loss"?? }</span>?? 
 
 上面的網絡結構,定義的data層,就是定義我們輸入的訓練數據的路徑、圖片變換等。
 
 3、網絡求解文件,這個文件我們喜歡把它取名為:solver.prototxt,這個文件的后綴格式也是.prototxt。這個文件主要包含了一些求解網絡,梯度下降參數、迭代次數等參數……,看下手寫字體的solver.prototxt文件:
 
 
 
   [cpp]?view plaincopy     
 <span?style="font-size:18px;">net:?"examples/mnist/lenet_train_test.prototxt"???? ?? test_iter:?100??? ?? test_interval:?500??? ?? base_lr:?0.01??????? momentum:?0.9????? weight_decay:?0.0005????? ?? lr_policy:?"inv"????? gamma:?0.0001?? power:?0.75?? ?? display:?100?? ?? max_iter:?10000????? ?? snapshot:?5000?????? snapshot_prefix:?"examples/mnist/lenet"??? ?? solver_mode:?GPU????? 
 
 這個文件的輸入就是我們前面一步定義的網絡結構。
 
 4、編寫網絡求解文件后,我們可以說已經完成了CNN網絡的編寫。接著我們需要把這個文件,作為caffe的輸入參數,調用caffe可執行文件,進行訓練就可以了。具體的命令如下:
 
 
 
   [cpp]?view plaincopy     
 <span?style="font-size:18px;">./build/tools/caffe?train?--solver=examples/mnist/lenet_solver.prototxt</span>?? 
 
 
 
 這樣就完事了,程序就開始訓練了。上面的第一個參數caffe,就是我們在編譯caffe,生成的可執行文件:
 
 
 
 
 
 
 
 然后solver就是我們在步驟3編寫的solver文件了,只要在ubuntu終端輸入上面的命令,就可以開始訓練了。
 
 回想一下文件調用過程:首先caffe可執行文件,調用了solver.prototxt文件,而這個文件又調用了網絡結構文件lenet_train_test.prototxt,然后lenet_train_test.prototxt文件里面又會調用輸入的訓練圖片數據等。因此我們如果要訓練自己的模型,需要備好3個文件:數據文件lmdb(該文件包含尋數據)、網絡結構lenet_train_test.prototxt、求解文件solver.prototxt,這幾個文件名隨便,但是文件后綴格式不要隨便亂改。把這三個文件放在同一個目錄下,然后在終端輸入命令,調用caffe就可以開始訓練了。
 
 二、相關細節
 
 
 
 1、lmdb數據格式生成
 
 caffe輸入訓練圖片數據我比較喜歡用lmdb格式,好像還有另外一種格式leveldb,這個具體沒用過,這里主要講解lmdb格式數據的制作。其實在caffe-》example-》imagenet文件夾下面的一些腳本文件可以幫助我們快速生產相關的caffe所需的數據。
 
 
 
 
 create_imagenet.sh這個文件可以幫我們快速的生成lmdb的數據格式文件,因此我們只需要把這個腳本文件復制出來,稍作修改,就可以對我們的訓練圖片、標注文件進行打包為lmdb格式文件了。制作圖片的腳本文件如下:
 
 
 
   [python]?view plaincopy     
 <span?style="font-size:18px;">?? ?? ?? ?? EXAMPLE=.???????????? TOOLS=../../build/tools???????????????????????????????? DATA=.???????????????????? ?? TRAIN_DATA_ROOT=train/???? VAL_DATA_ROOT=val/???????? ?? ?? ?? ?? ?? RESIZE=true????? if?$RESIZE;?then?? ??RESIZE_HEIGHT=256?? ??RESIZE_WIDTH=256?? else?? ??RESIZE_HEIGHT=0?? ??RESIZE_WIDTH=0?? fi?? ?? if?[?!?-d?"$TRAIN_DATA_ROOT"?];?then?? ??echo?"Error:?TRAIN_DATA_ROOT?is?not?a?path?to?a?directory:?$TRAIN_DATA_ROOT"?? ??echo?"Set?the?TRAIN_DATA_ROOT?variable?in?create_imagenet.sh?to?the?path"?\?? ???????"where?the?ImageNet?training?data?is?stored."?? ??exit?1?? fi?? ?? if?[?!?-d?"$VAL_DATA_ROOT"?];?then?? ??echo?"Error:?VAL_DATA_ROOT?is?not?a?path?to?a?directory:?$VAL_DATA_ROOT"?? ??echo?"Set?the?VAL_DATA_ROOT?variable?in?create_imagenet.sh?to?the?path"?\?? ???????"where?the?ImageNet?validation?data?is?stored."?? ??exit?1?? fi?? ?? echo?"Creating?train?lmdb..."?? ?? GLOG_logtostderr=1?$TOOLS/convert_imageset?\?? ????--resize_height=$RESIZE_HEIGHT?\?? ????--resize_width=$RESIZE_WIDTH?\?? ????--shuffle?\?? ????$TRAIN_DATA_ROOT?\?? ????$DATA/train.txt?\??????? ????$EXAMPLE/train_lmdb?? ?? echo?"Creating?val?lmdb..."?? ?? GLOG_logtostderr=1?$TOOLS/convert_imageset?\?? ????--resize_height=$RESIZE_HEIGHT?\?? ????--resize_width=$RESIZE_WIDTH?\?? ????--shuffle?\?? ????$VAL_DATA_ROOT?\?? ????$DATA/val.txt?\?????? ????$EXAMPLE/val_lmdb?? ?? echo?"Done."</span>?? 
 
同時我們需要制作如下四個文件:
 
 
 
 1、文件夾train,用于存放訓練圖片
 
 2、文件夾val,用于存放驗證圖片
 
 3、文件train.txt,里面包含這每張圖片的名稱,及其對應的標簽。
 
 
 
   [python]?view plaincopy     
 <span?style="font-size:18px;">first_batch/train_female/992.jpg????1?? first_batch/train_female/993.jpg????1?? first_batch/train_female/994.jpg????1?? first_batch/train_female/995.jpg????1?? first_batch/train_female/996.jpg????1?? first_batch/train_female/997.jpg????1?? first_batch/train_female/998.jpg????1?? first_batch/train_female/999.jpg????1?? first_batch/train_male/1000.jpg?0?? first_batch/train_male/1001.jpg?0?? first_batch/train_male/1002.jpg?0?? first_batch/train_male/1003.jpg?0?? first_batch/train_male/1004.jpg?0?? first_batch/train_male/1005.jpg?0?? first_batch/train_male/1006.jpg?0?? first_batch/train_male/1007.jpg?0?? first_batch/train_male/1008.jpg?0</span>?? 
 
 
 
 上面的標簽編號:1,表示女。標簽:0,表示男。
 
 4、文件val.txt,同樣這個文件也是保存圖片名稱及其對應的標簽。
 
 這四個文件在上面的腳本文件中,都需要調用到。制作玩后,跑一下上面的腳本文件,就ok了,跑完后,即將生成下面兩個文件夾:
 
 
 
 
 文件夾下面有兩個對應的文件:
 
 
 
 
 制作完后,要看看文件的大小,有沒有問題,如果就幾k,那么正常是每做好訓練數據,除非你的訓練圖片就幾張。
 
 二、訓練
 
 1、直接訓練法
 
 
 
 
 
   [python]?view plaincopy     
 <span?style="font-size:18px;">?? TOOLS=../cafferead/build/tools?? $TOOLS/caffe?train?--solver=gender_solver.prorotxt??-gpu?all???? 
 
 
 -gpu 可以選擇gpu的id號,如果是 -gpu all表示啟用所有的GPU進行訓練。
 
 2、采用funing-tuning 訓練法
 
 
 
 
   [python]?view plaincopy     
 <span?style="font-size:18px;">$TOOLS/caffe?train?--solver=gender_solver.prorotxt?-weights?gender_net.caffemodel??? 
 
 加入-weights,這個功能很好用,也經常會用到,因為現在的CNN相關的文獻,很多都是在已有的模型基礎上,進行fine-tuning,因為我們大部分人都缺少訓練數據,不像谷歌、百度這些土豪公司,有很多人專門做數據標注,對于小公司而言,往往缺少標注好的訓練數據。因此我們一般使用fine-tuning的方法,在少量數據的情況下,盡可能的提高精度。我們可以使用:-weights 選項,利用已有的模型訓練好的參數,作為初始值,進行繼續訓練。
 
 三、調用python接口
 
 訓練完畢后,我們就可以得到caffe的訓練模型了,接著我們的目標就預測,看看結果了。caffe為我們提供了方便調用的python接口函數,這些都在模塊pycaffe里面。因此我們還需要知道如何使用pycaffe,進行測試,查看結果。下面是pycaffe的預測調用使用示例:
 
 
 
   [python]?view plaincopy     
 ?? import?os?? import?numpy?as?np?? from?matplotlib?import?pyplot?as?plt?? import?cv2?? import?shutil?? import?time?? ?? ?? def?showimage(im):?? ????if?im.ndim?==?3:?? ????????im?=?im[:,?:,?::-1]?? ????plt.set_cmap('jet')?? ????plt.imshow(im)?? ????plt.show()?? ?? ?? def?vis_square(data,?padsize=1,?padval=0):?? ????data?-=?data.min()?? ????data?/=?data.max()?? ?? ?????? ????n?=?int(np.ceil(np.sqrt(data.shape[0])))?? ????padding?=?((0,?n?**?2?-?data.shape[0]),?(0,?padsize),?(0,?padsize))?+?((0,?0),)?*?(data.ndim?-?3)?? ????data?=?np.pad(data,?padding,?mode='constant',?constant_values=(padval,?padval))?? ?? ?????? ????data?=?data.reshape((n,?n)?+?data.shape[1:]).transpose((0,?2,?1,?3)?+?tuple(range(4,?data.ndim?+?1)))?? ????data?=?data.reshape((n?*?data.shape[1],?n?*?data.shape[3])?+?data.shape[4:])?? ?? ????showimage(data)?? ?? ?? ?? caffe_root?=?'../../../caffe/'?? import?sys?? sys.path.insert(0,?caffe_root?+?'python')?? import?caffe?? ?? ?? ?? ?? ?? mean_filename='./imagenet_mean.binaryproto'?? proto_data?=?open(mean_filename,?"rb").read()?? a?=?caffe.io.caffe_pb2.BlobProto.FromString(proto_data)?? mean??=?caffe.io.blobproto_to_array(a)[0]?? ?? ?? gender_net_pretrained='./caffenet_train_iter_1500.caffemodel'?? gender_net_model_file='./deploy_gender.prototxt'?? gender_net?=?caffe.Classifier(gender_net_model_file,?gender_net_pretrained,mean=mean,?? ???????????????????????channel_swap=(2,1,0),?? ???????????????????????raw_scale=255,?? ???????????????????????image_dims=(256,?256))?? ?? ?? ?? gender_list=['Male','Female']?? input_image?=?caffe.io.load_image('1.jpg')?? ?? prediction_gender=gender_net.predict([input_image])?? ?? print?'params:'?? for?k,?v?in?gender_net.params.items():?? ????print?'weight:'?? ????print?(k,?v[0].data.shape)?? ????print?'b:'?? ????print?(k,?v[1].data.shape)?? ?? filters?=?gender_net.params['conv1'][0].data?? vis_square(filters.transpose(0,?2,?3,?1))?? ?? ''? ?? ?? print?'feature?maps:'?? for?k,?v?in?gender_net.blobs.items():?? ????print?(k,?v.data.shape);?? ????feat?=?gender_net.blobs[k].data[0,0:4]?? ????vis_square(feat,?padval=1)?? ?? ?? ?? ?? ?? ?? str_gender=gender_list[prediction_gender[0].argmax()]?? print?str_gender?? ?? plt.imshow(input_image)?? plt.title(str_gender)?? plt.show()?? 
 
 
上面的接口,同時包含了pycaffe加載訓練好的模型,進行預測及其特征可視化的調用方法。
 
 
 
 **********************作者:hjimce ? 時間:2015.10.6 ?聯系QQ:1393852684 ? 地址:http://blog.csdn.net/hjimce? ?原創文章,版權所有,轉載請保留本行信息********************
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
                            
總結
                            
                                以上是生活随笔為你收集整理的深度学习(六)caffe入门学习的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                            
                                如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。