DAGNN 是Directed acyclic graph neural network 縮寫,也就有向圖非循環神經網絡。我使用的是由MatConvNet 提供的DAGNN API。選擇這套API做爲工具的緣由有三點,第一:這是matlab的API,相對其餘語言我對Matlab比較熟悉;第二:有向圖非循環的網絡能夠實現RPN,Network in Network 等較爲複雜的功能,能夠隨意的引出各層的輸入和輸出,有利於針對三維視覺任務改造網絡結構。MNIST 是手寫數字的圖片集,也是機器學習網絡最簡單的試金石。數據庫
1 conv_layer1 = dagnn.Conv('size',single([5,5,1,30]),'hasBias',true); 2 relu_layer2 = dagnn.ReLU(); 3 4 conv_layer3 = dagnn.Conv('size',single([5,5,30,16]),'hasBias',true); 5 relu_layer4 = dagnn.ReLU(); 6 pooling_layer5 = dagnn.Pooling('poolSize',[2,2],'stride',[2 2]); 7 8 fullConnet_layer6 = dagnn.Conv('size',single([4,4,16,256]),'hasBias',true); 9 relu_layer7 = dagnn.ReLU(); 10 fullConnet_layer8 = dagnn.Conv('size',single([1,1,256,10]),'hasBias',true); 11 SoftMat_layer9 = dagnn.SoftMax(); 12 Loss_layer = dagnn.Loss();
首先是利用API構造各層網絡,定義網絡結構類型。全部的Layer 都繼承自dagnn.Layer類,子類中定義了輸入輸出,前向傳播,反向傳播的行爲。網絡
其中包括卷積層,激活層,池化層,Softmax 分類層,以及計算Loss層。值得注意的是全鏈接層是經過大卷積層來實現的。本質上全鏈接就是「輸入的等尺寸卷積」。全鏈接層的做用是將卷積層提取的特徵進行高度非線性的映射,將其映射到輸出空間中。機器學習
1 mynet = dagnn.DagNN(); 2 mynet.addLayer('conv1',conv_layer1,{'input'},{'x2'},{'filters_conv1','bias_conv1'}); 3 mynet.addLayer('relu1',relu_layer2,{'x2'},{'x3'}); 4 mynet.addLayer('pool1',pooling_layer5,{'x3'},{'x4'}); 5 6 mynet.addLayer('conv2',conv_layer3,{'x4'},{'x5'},{'filters_conv2','bias_conv2'}); 7 mynet.addLayer('relu2',relu_layer4,{'x5'},{'x6'}); 8 mynet.addLayer('pool2',pooling_layer5,{'x6'},{'x7'}); 9 10 mynet.addLayer('full1',fullConnet_layer6,{'x7'},{'x8'},{'filters_fc1','bias_fc1'}); 11 mynet.addLayer('relu3',relu_layer7,{'x8'},{'x9'}); 12 mynet.addLayer('full2',fullConnet_layer8,{'x9'},{'x10'},{'filters_fc2','bias_fc2'}); 13 mynet.addLayer('Cls1',SoftMat_layer9,{'x10'},{'pred'}); 14 mynet.addLayer('Loss',Loss_layer,{'pred','label'},{'loss'}); 15 mynet.initParams(); 16 mynet.meta.inputs = {'data',[28,28,1,1]}; 17 mynet.meta.classes.name = {1,2,3,4,5,6,7,8,9,10}; 18 mynet.meta.normalization.imageSize = [28,28,1,1]; 19 mynet.meta.interpolation = 'bicubic';
定義網絡調用了addLayer方法,與其餘API的網絡構建方法不一樣的是,DAGNN的API須要針對每層定義輸入和輸出,以及網絡中的待求得參數。固然,做爲初學者我先實現了鏈式網絡,在下週的工做中會嘗試實現Faster R-CNN。ide
net.addLayer('full1',fullConnet_layer6,{'x7'},{'x8'},{'filters_fc1','bias_fc1'});函數
以此爲例,表明該層的名字是full1 , 該層的結構是fullConnect_layer6,輸入爲x七、輸出x8,參數名爲filters_fc1 和 bias_fc1。其中loss 層最爲特殊,其具備來自softmax層的pred 和 label (ground truth) 兩種輸入。工具
最重要的是必定要initParams()!!!!這會生成初始參數。學習
爲了訓練網絡,咱們須要定義一個輸入函數。數據量小,可存在內存中,但當數據量大的時候所有存在內存裏是不現實的,這就須要一個數據輸入函數來對你定義的數據庫進行操做。本例中我僅使用5000幅圖片進行訓練,因此能夠把圖片放在內存中。getBatch函數以下所示:測試
1 function inputs = getBatch(imdb, batch) 2 % -------------------------------------------------------------------- 3 images = imdb.images.data(:,:,:,batch) ; 4 labels = imdb.images.labels(1,batch) ; 5 6 % images = gpuArray(images) ; 7 8 inputs = {'input', images, 'label', labels} ;
其中 imdb 是image data base. 其中包括:spa
imdb.images.data 圖片 W*H*C*N 的4-D single Arraycode
imdb.images.label 標籤 N*1 的 single Array
imdb.images.data_mean 圖片平均值 用於預處理時去中心
imdb.images.set 集合號 N*1 的 single Array, 其中1 表明訓練集 2 表明測試集 3 表明驗證集
imdb.meta 存放類型名稱等和訓練關係不太密切的東西
直接調用 cnn_train_dag 的API 開始對整個集合進行訓練,注意getBatch 輸入的是函數句柄。
cnn_train_dag(mynet,imdb_sub,@getBatch);
訓練了30個epoch,可是learningRate好像給過高了,掉局部最小裏了。。。。。。。不過結果不錯,在驗證集中拿到了4998/5000.