深度學習Matlab工具箱代碼註釋——cnnff.m

%%=========================================================================
%函數名稱:cnnff()
%輸入參數:net,神經網絡;x,訓練數據矩陣;
%輸出參數:net,訓練完成的卷積神經網絡
%主要功能:使用當前的神經網絡對輸入的向量進行預測
%算法流程:1)將樣本打亂,隨機選擇進行訓練;
%         2)講樣本輸入網絡,層層映射得到預測值
%注意事項:1)使用BP算法計算梯度
%%=========================================================================
function net = cnnff(net, x)
n                  = numel(net.layers);      %層數
net.layers{1}.a{1} = x;                      %網絡的第一層就是輸入,但這裏的輸入包含了多個訓練圖像
inputmaps          = 1;                      %輸入層只有一個特徵map,也就是原始的輸入圖像
for l = 2 : n                                %對於每層(第一層是輸入層,循環時先忽略掉)
    if strcmp(net.layers{l}.type, 'c')       %如果當前是卷積層
        for j = 1 : net.layers{l}.outputmaps %對每一個輸入map,需要用outputmaps個不同的卷積核去卷積圖像
            %%=========================================================================
            %主要功能:創建outmap的中間變量,即特徵矩陣
            %實現步驟:用這個公式生成一個零矩陣,作爲特徵map
            %注意事項:1)對於上一層的每一張特徵map,卷積後的特徵map的大小是:(輸入map寬 - 卷積核的寬 + 1)* (輸入map高 - 卷積核高 + 1)
            %         2)由於每層都包含多張特徵map,則對應的索引則保存在每層map的第三維,及變量Z中
            %%=========================================================================
            z = zeros(size(net.layers{l - 1}.a{1}) - [net.layers{l}.kernelsize - 1 net.layers{l}.kernelsize - 1 0]);

            for i = 1 : inputmaps    %對於輸入的每個特徵map
                %%=========================================================================
                %主要功能:將上一層的每一個特徵map(也就是這層的輸入map)與該層的卷積核進行卷積
                %實現步驟:1)進行卷積
                %         2)加上對應位置的基b,然後再用sigmoid函數算出特徵map中每個位置的激活值,作爲該層輸出特徵map
                %注意事項:1)當前層的一張特徵map,是用一種卷積核去卷積上一層中所有的特徵map,然後所有特徵map對應位置的卷積值的和
                %         2)有些論文或者實際應用中,並不是與全部的特徵map鏈接的,有可能只與其中的某幾個連接
                %%=========================================================================
                z = z + convn(net.layers{l - 1}.a{i}, net.layers{l}.k{i}{j}, 'valid');
            end
            net.layers{l}.a{j} = sigm(z + net.layers{l}.b{j});   %加基(加上加性偏置b)
        end
        inputmaps = net.layers{l}.outputmaps;                    %更新當前層的map數量;

    elseif strcmp(net.layers{l}.type, 's')                       %如果當前層是下采樣層
        for j = 1 : inputmaps
            %%=========================================================================
            %主要功能:對特徵map進行下采樣
            %實現步驟:1)進行卷積
            %         2)最終pooling的結果需要從上面得到的卷積結果中以scale=2爲步長,跳着把mean pooling的值讀出來
            %注意事項:1)例如我們要在scale=2的域上面執行mean pooling,那麼可以卷積大小爲2*2,每個元素都是1/4的卷積核
            %         2)因爲convn函數的默認卷積步長爲1,而pooling操作的域是沒有重疊的,所以對於上面的卷積結果
            %         3)是利用卷積的方法實現下采樣
            %%=========================================================================
            z = convn(net.layers{l - 1}.a{j}, ones(net.layers{l}.scale) / (net.layers{l}.scale ^ 2), 'valid');
            net.layers{l}.a{j} = z(1 : net.layers{l}.scale : end, 1 : net.layers{l}.scale : end, :);   %跳讀mean pooling的值
        end
    end
end

%%=========================================================================
%主要功能:輸出層,將最後一層得到的特徵變成一條向量,作爲最終提取得到的特徵向量
%實現步驟:1)獲取倒數第二層中每個特徵map的尺寸
%         2)用reshape函數將map轉換爲向量的形式
%         3)使用sigmoid(W*X + b)函數計算樣本輸出值,放到net成員o中
%注意事項:1)在使用sigmoid()函數是,是同時計算了batchsize個樣本的輸出值
%%=========================================================================
net.fv = [];                       %net.fv爲神經網絡倒數第二層的輸出map
for j = 1 : numel(net.layers{n}.a) %最後一層的特徵map的個數
    sa = size(net.layers{n}.a{j}); %第j個特徵map的大小
    net.fv = [net.fv; reshape(net.layers{n}.a{j}, sa(1) * sa(2), sa(3))];
end
net.o = sigm(net.ffW * net.fv + repmat(net.ffb, 1, size(net.fv, 2))); %通過全連接層的映射得到網絡的最終預測結果輸出
end

原文鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章