深度學習Matlab工具箱DeepLearnToolbox代碼注釋(轉)

2017-01-16  by:CAE仿真在線  來源:互聯(lián)網

深度學習Matlab工具箱DeepLearnToolbox代碼注釋

----轉自csdn“陳俊嶺的程序員之路”

%%=========================================================================

% 主要功能:在mnist數(shù)據庫上做實驗,驗證工具箱的有效性

% 算法流程:1)載入訓練樣本和測試樣本

% 2)設置CNN參數(shù),并進行訓練

% 3)進行檢測cnntest()

% 注意事項:1)由于直接將所有測試樣本輸入會導致內存溢出,故采用一次只測試一個訓練樣本的測試方法

%%=========================================================================

%%

%%%%%%%%%%%%%%%%%%%%加載數(shù)據集%%%%%%%%%%%%%%%%%%%%

load mnist_uint8;

train_x = double(reshape(train_x',28,28,60000))/255;

test_x = double(reshape(test_x',28,28,10000))/255;

train_y = double(train_y');

test_y = double(test_y');

%%

%%=========================================================================

%%%%%%%%%%%%%%%%%%%%設置卷積神經網絡參數(shù)%%%%%%%%%%%%%%%%%%%%

% 主要功能:訓練一個6c-2s-12c-2s形式的卷積神經網絡,預期性能如下:

% 1)迭代一次需要200秒左右,錯誤率大約為11%

% 2)迭代一百次后錯誤率大約為1.2%

% 算法流程:1)構建神經網絡并進行訓練,以CNN結構體的形式保存

% 2)用已知的訓練樣本進行測試

% 注意事項:1)之前在測試的時候提示內存溢出,后來莫名其妙的又不溢出了,估計到了系統(tǒng)的內存臨界值

%%=========================================================================

rand('state',0)

cnn.layers = {

struct('type', 'i') %輸入層

struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %卷積層

struct('type', 's', 'scale', 2) %下采樣層

struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %卷積層

struct('type', 's', 'scale', 2) %下采樣層

};

cnn = cnnsetup(cnn, train_x, train_y);

opts.alpha = 1;

opts.batchsize = 50;

opts.numepochs = 5;

cnn = cnntrain(cnn, train_x, train_y, opts);

save CNN_5 cnn;

load CNN_5;

[er, bad] = cnntest(cnn, test_x, test_y);

figure; plot(cnn.rL);

assert(er<0.12, 'Too big error');

深度學習Matlab工具箱代碼注釋——cnnsetup.m

%%=========================================================================

% 函數(shù)名稱:cnnsetup

% 輸入參數(shù):net,待設置的卷積神經網絡;x,訓練樣本;y,訓練樣本對應標簽;

% 輸出參數(shù):net,初始化完成的卷積神經網絡

% 主要功能:對CNN的結構進行初始化

% 算法流程:1)

% 注意事項:1)isOctave這個語句是為了拋出一個程序在Octave平臺上運行時的一個BUG,在matlab平臺上可以直接注釋掉

% 2)net.layers中有五個struct類型的元素,實際上就表示CNN共有五層,這里范圍的是5

%%=========================================================================

function net = cnnsetup(net, x, y)

assert(~isOctave() || compare_versions(OCTAVE_VERSION, '3.8.0', '>='), ['Octave 3.8.0 or greater is required for CNNs as there is a bug in convolution in previous versions. See http://savannah.gnu.org/bugs/?39314. Your version is ' myOctaveVersion]);

inputmaps = 1; %初始化網絡輸入層數(shù)為1層

%%=========================================================================

% 主要功能:得到輸入圖像的行數(shù)和列數(shù)

% 注意事項:1)B=squeeze(A) 返回和矩陣A相同元素但所有單一維都移除的矩陣B,單一維是滿足size(A,dim)=1的維。

% train_x中圖像的存放方式是三維的reshape(train_x',28,28,60000),前面兩維表示圖像的行與列,

% 第三維就表示有多少個圖像。這樣squeeze(x(:, :, 1))就相當于取第一個圖像樣本后,再把第三維

% 移除,就變成了28x28的矩陣,也就是得到一幅圖像,再size一下就得到了訓練樣本圖像的行數(shù)與列數(shù)了

%%=========================================================================

mapsize = size(squeeze(x(:, :, 1)));

%%%%%%%%%%%%%%%%%%%%下面通過傳入net這個結構體來逐層構建CNN網絡%%%%%%%%%%%%%%%%%%%%

for l = 1 : numel(net.layers) %對于每一層

if strcmp(net.layers{l}.type, 's') %如果當前層是下采樣層

%%=========================================================================

% 主要功能:獲取下采樣之后特征map的尺寸

% 注意事項:1)subsampling層的mapsize,最開始mapsize是每張圖的大小28*28

% 這里除以scale=2,就是pooling之后圖的大小,pooling域之間沒有重疊,所以pooling后的圖像為14*14

% 注意這里的右邊的mapsize保存的都是上一層每張?zhí)卣鱩ap的大小,它會隨著循環(huán)進行不斷更新

%%=========================================================================

mapsize = mapsize / net.layers{l}.scale;

assert(all(floor(mapsize)==mapsize), ['Layer ' num2str(l) ' size must be integer. Actual: ' num2str(mapsize)]);

for j = 1 : inputmaps %對于上一層的每個特征圖

net.layers{l}.b{j} = 0; %將偏置初始化為零

end

end

if strcmp(net.layers{l}.type, 'c') %如果當前層是卷基層

%%=========================================================================

% 主要功能:獲取卷積后的特征map尺寸以及當前層待學習的卷積核的參數(shù)數(shù)量

% 注意事項:1)舊的mapsize保存的是上一層的特征map的大小,那么如果卷積核的移動步長是1,那用

% kernelsize*kernelsize大小的卷積核卷積上一層的特征map后,得到的新的map的大小就是下面這樣

% 2)fan_out代表該層需要學習的參數(shù)個數(shù)。每張?zhí)卣鱩ap是一個(后層特征圖數(shù)量)*(用來卷積的patch圖的大小)

% 因為是通過用一個核窗口在上一個特征map層中移動(核窗口每次移動1個像素),遍歷上一個特征map

% 層的每個神經元。核窗口由kernelsize*kernelsize個元素組成,每個元素是一個獨立的權值,所以

% 就有kernelsize*kernelsize個需要學習的權值,再加一個偏置值。另外,由于是權值共享,也就是

% 說同一個特征map層是用同一個具有相同權值元素的kernelsize*kernelsize的核窗口去感受輸入上一

% 個特征map層的每個神經元得到的,所以同一個特征map,它的權值是一樣的,共享的,權值只取決于

% 核窗口。然后,不同的特征map提取輸入上一個特征map層不同的特征,所以采用的核窗口不一樣,也

% 就是權值不一樣,所以outputmaps個特征map就有(kernelsize*kernelsize+1)* outputmaps那么多的權值了

% 但這里fan_out只保存卷積核的權值W,偏置b在下面獨立保存

%%=========================================================================

mapsize = mapsize - net.layers{l}.kernelsize + 1;

fan_out = net.layers{l}.outputmaps * net.layers{l}.kernelsize ^ 2;

for j = 1 : net.layers{l}.outputmaps %對于卷積層的每一個輸出map

%%=========================================================================

% 主要功能:獲取卷積層與前一層輸出map之間需要鏈接的參數(shù)鏈個數(shù)

% 注意事項:1)fan_out保存的是對于上一層的一張?zhí)卣鱩ap,我在這一層需要對這一張?zhí)卣鱩ap提取outputmaps種特征,

% 提取每種特征用到的卷積核不同,所以fan_out保存的是這一層輸出新的特征需要學習的參數(shù)個數(shù)

% 而,fan_in保存的是,我在這一層,要連接到上一層中所有的特征map,然后用fan_out保存的提取特征

% 的權值來提取他們的特征。也即是對于每一個當前層特征圖,有多少個參數(shù)鏈到前層

%%=========================================================================

fan_in = inputmaps * net.layers{l}.kernelsize ^ 2;

for i = 1 : inputmaps %對于上一層的每一個輸出特征map(本層的輸入map)

%%=========================================================================

% 主要功能:隨機初始化卷積核的權值,再將偏置均初始化為零

% 注意事項:1)隨機初始化權值,也就是共有outputmaps個卷積核,對上層的每個特征map,都需要用這么多個卷積核去卷積提取特征。

% rand(n)是產生n×n的 0-1之間均勻取值的數(shù)值的矩陣,再減去0.5就相當于產生-0.5到0.5之間的隨機數(shù)

% 再 *2 就放大到 [-1, 1]。然后再乘以后面那一數(shù),why?

% 反正就是將卷積核每個元素初始化為[-sqrt(6 / (fan_in + fan_out)), sqrt(6 / (fan_in + fan_out))]

% 之間的隨機數(shù)。因為這里是權值共享的,也就是對于一張?zhí)卣鱩ap,所有感受野位置的卷積核都是一樣的

% 所以只需要保存的是 inputmaps * outputmaps 個卷積核。

% 2)為什么這里是inputmaps * outputmaps個卷積核?

%%=========================================================================

net.layers{l}.k{i}{j} = (rand(net.layers{l}.kernelsize) - 0.5) * 2 * sqrt(6 / (fan_in + fan_out));

end

net.layers{l}.b{j} = 0;

end

inputmaps = net.layers{l}.outputmaps; %在卷積層會更新每層網絡的輸出map數(shù)量

end

end

%%=========================================================================

% 主要功能:初始化最后一層,也就是輸出層的參數(shù)值

% 算法流程:1)fvnum 是輸出層的前面一層的神經元個數(shù)。這一層的上一層是經過pooling后的層,包含有inputmaps個

% 特征map。每個特征map的大小是mapsize,所以,該層的神經元個數(shù)是 inputmaps * (每個特征map的大小)

% 2)onum 是標簽的個數(shù),也就是輸出層神經元的個數(shù)。你要分多少個類,自然就有多少個輸出神經元

% 3)net.ffb和net.ffW為最后一層(全連接層)的偏置和權重

%%=========================================================================

fvnum = prod(mapsize) * inputmaps;

onum = size(y, 1);

net.ffb = zeros(onum, 1);

net.ffW = (rand(onum, fvnum) - 0.5) * 2 * sqrt(6 / (onum + fvnum));

end

深度學習Matlab工具箱代碼注釋——cnntrain.m

%%=========================================================================

%函數(shù)名稱:cnntrain()

%輸入參數(shù):net,神經網絡;x,訓練數(shù)據矩陣;y,訓練數(shù)據的標簽矩陣;opts,神經網絡的相關訓練參數(shù)

%輸出參數(shù):net,訓練完成的卷積神經網絡

%算法流程:1)將樣本打亂,隨機選擇進行訓練;

% 2)取出樣本,通過cnnff2()函數(shù)計算當前網絡權值和網絡輸入下網絡的輸出

% 3)通過BP算法計算誤差對網絡權值的導數(shù)

% 4)得到誤差對權值的導數(shù)后,就通過權值更新方法去更新權值

%注意事項:1)使用BP算法計算梯度

%%=========================================================================

function net = cnntrain(net, x, y, opts)

m = size(x, 3); %m保存的是訓練樣本個數(shù)

disp(['樣本總個數(shù)=' num2str(m)]);

numbatches = m / opts.batchsize; %numbatches表示每次迭代中所選取的訓練樣本數(shù)

if rem(numbatches, 1) ~= 0 %如果numbatches不是整數(shù),則程序發(fā)生錯誤

error('numbatches not integer');

end

%%=====================================================================

%主要功能:CNN網絡的迭代訓練

%實現(xiàn)步驟:1)通過randperm()函數(shù)將原來的樣本順序打亂,再挑出一些樣本來進行訓練

% 2)取出樣本,通過cnnff2()函數(shù)計算當前網絡權值和網絡輸入下網絡的輸出

% 3)通過BP算法計算誤差對網絡權值的導數(shù)

% 4)得到誤差對權值的導數(shù)后,就通過權值更新方法去更新權值

%注意事項:1)P = randperm(N),返回[1, N]之間所有整數(shù)的一個隨機的序列,相當于把原來的樣本排列打亂,

% 再挑出一些樣本來訓練

% 2)采用累積誤差的計算方式來評估當前網絡性能,即當前誤差 = 以前誤差 * 0.99 + 本次誤差 * 0.01

% 使得網絡盡可能收斂到全局最優(yōu)

%%=====================================================================

net.rL = []; %代價函數(shù)值,也就是誤差值

for i = 1 : opts.numepochs %對于每次迭代

disp(['epoch ' num2str(i) '/' num2str(opts.numepochs)]);

tic; %使用tic和toc來統(tǒng)計程序運行時間

%%%%%%%%%%%%%%%%%%%%取出打亂順序后的batchsize個樣本和對應的標簽 %%%%%%%%%%%%%%%%%%%%

kk = randperm(m);

for l = 1 : numbatches

batch_x = x(:, :, kk((l - 1) * opts.batchsize + 1 : l * opts.batchsize));

batch_y = y(:, kk((l - 1) * opts.batchsize + 1 : l * opts.batchsize));

%%%%%%%%%%%%%%%%%%%%在當前的網絡權值和網絡輸入下計算網絡的輸出(特征向量)%%%%%%%%%%%%%%%%%%%%

net = cnnff(net, batch_x); %卷積神經網絡的前饋運算

%%%%%%%%%%%%%%%%%%%%通過對應的樣本標簽用bp算法來得到誤差對網絡權值的導數(shù)%%%%%%%%%%%%%%%%%%%%

net = cnnbp(net, batch_y); %卷積神經網絡的BP算法

%%%%%%%%%%%%%%%%%%%%通過權值更新方法去更新權值%%%%%%%%%%%%%%%%%%%%

net = cnnapplygrads(net, opts);

if isempty(net.rL)

net.rL(1) = net.L; %代價函數(shù)值,也就是均方誤差值 ,在cnnbp.m中計算初始值 net.L = 1/2* sum(net.e(:) .^ 2) / size(net.e, 2);

end

net.rL(end + 1) = 0.99 * net.rL(end) + 0.01 * net.L; %采用累積的方式計算累積誤差

end

toc;

end

end

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

%%=========================================================================

%函數(shù)名稱:cnnff()

%輸入參數(shù):net,神經網絡;x,訓練數(shù)據矩陣;

%輸出參數(shù):net,訓練完成的卷積神經網絡

%主要功能:使用當前的神經網絡對輸入的向量進行預測

%算法流程:1)將樣本打亂,隨機選擇進行訓練;

% 2)講樣本輸入網絡,層層映射得到預測值

%注意事項:1)使用BP算法計算梯度

%%=========================================================================

function net = cnnff(net, x)

n = numel(net.layers); %層數(shù)

net.layers{1}.a{1} = x; %網絡的第一層就是輸入,但這里的輸入包含了多個訓練圖像

inputmaps = 1; %輸入層只有一個特征map,也就是原始的輸入圖像

for l = 2 : n %對于每層(第一層是輸入層,循環(huán)時先忽略掉)

if strcmp(net.layers{l}.type, 'c') %如果當前是卷積層

for j = 1 : net.layers{l}.outputmaps %對每一個輸入map,需要用outputmaps個不同的卷積核去卷積圖像

%%=========================================================================

%主要功能:創(chuàng)建outmap的中間變量,即特征矩陣

%實現(xiàn)步驟:用這個公式生成一個零矩陣,作為特征map

%注意事項:1)對于上一層的每一張?zhí)卣鱩ap,卷積后的特征map的大小是:(輸入map寬 - 卷積核的寬 + 1)* (輸入map高 - 卷積核高 + 1)

% 2)由于每層都包含多張?zhí)卣鱩ap,則對應的索引則保存在每層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)與該層的卷積核進行卷積

%實現(xiàn)步驟:1)進行卷積

% 2)加上對應位置的基b,然后再用sigmoid函數(shù)算出特征map中每個位置的激活值,作為該層輸出特征map

%注意事項:1)當前層的一張?zhí)卣鱩ap,是用一種卷積核去卷積上一層中所有的特征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數(shù)量;

elseif strcmp(net.layers{l}.type, 's') %如果當前層是下采樣層

for j = 1 : inputmaps

%%=========================================================================

%主要功能:對特征map進行下采樣

%實現(xiàn)步驟:1)進行卷積

% 2)最終pooling的結果需要從上面得到的卷積結果中以scale=2為步長,跳著把mean pooling的值讀出來

%注意事項:1)例如我們要在scale=2的域上面執(zhí)行mean pooling,那么可以卷積大小為2*2,每個元素都是1/4的卷積核

% 2)因為convn函數(shù)的默認卷積步長為1,而pooling操作的域是沒有重疊的,所以對于上面的卷積結果

% 3)是利用卷積的方法實現(xiàn)下采樣

%%=========================================================================

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

%%=========================================================================

%主要功能:輸出層,將最后一層得到的特征變成一條向量,作為最終提取得到的特征向量

%實現(xiàn)步驟:1)獲取倒數(shù)第二層中每個特征map的尺寸

% 2)用reshape函數(shù)將map轉換為向量的形式

% 3)使用sigmoid(W*X + b)函數(shù)計算樣本輸出值,放到net成員o中

%注意事項:1)在使用sigmoid()函數(shù)是,是同時計算了batchsize個樣本的輸出值

%%=========================================================================

net.fv = []; %net.fv為神經網絡倒數(shù)第二層的輸出map

for j = 1 : numel(net.layers{n}.a) %最后一層的特征map的個數(shù)

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

深度學習Matlab工具箱代碼注釋——cnnbp.m

%%=========================================================================

%函數(shù)名稱:cnnbp()

%輸入參數(shù):net,呆訓練的神經網絡;y,訓練樣本的標簽,即期望輸出

%輸出參數(shù):net,經過BP算法訓練得到的神經網絡

%主要功能:通過BP算法訓練神經網絡參數(shù)

%實現(xiàn)步驟:1)將輸出的殘差擴展成與最后一層的特征map相同的尺寸形式

% 2)如果是卷積層,則進行上采樣

% 3)如果是下采樣層,則進行下采樣

% 4)采用誤差傳遞公式對靈敏度進行反向傳遞

%注意事項:1)從最后一層的error倒推回來deltas,和神經網絡的BP十分相似,可以參考“UFLDL的反向傳導算法”的說明

% 2)在fvd里面保存的是所有樣本的特征向量(在cnnff.m函數(shù)中用特征map拉成的),所以這里需要重新?lián)Q回來特征map的形式,

% d保存的是delta,也就是靈敏度或者殘差

% 3)net.o .* (1 - net.o))代表輸出層附加的非線性函數(shù)的導數(shù),即sigm函數(shù)的導數(shù)

%%=========================================================================

function net = cnnbp(net, y)

n = numel(net.layers); %網絡層數(shù)

net.e = net.o - y; %實際輸出與期望輸出之間的誤差

net.L = 1/2* sum(net.e(:) .^ 2) / size(net.e, 2); %代價函數(shù),采用均方誤差函數(shù)作為代價函數(shù)

net.od = net.e .* (net.o .* (1 - net.o)); %輸出層的靈敏度或者殘差,(net.o .* (1 - net.o))代表輸出層的激活函數(shù)的導數(shù)

net.fvd = (net.ffW' * net.od); %殘差反向傳播回前一層,net.fvd保存的是殘差

if strcmp(net.layers{n}.type, 'c') %只有卷積層采用sigm函數(shù)

net.fvd = net.fvd .* (net.fv .* (1 - net.fv)); %net.fv是前一層的輸出(未經過simg函數(shù)),作為輸出層的輸入

end

%%%%%%%%%%%%%%%%%%%%將輸出的殘差擴展成與最后一層的特征map相同的尺寸形式%%%%%%%%%%%%%%%%%%%%

sa = size(net.layers{n}.a{1}); %最后一層特征map的大小。這里的最后一層都是指輸出層的前一層

fvnum = sa(1) * sa(2); %因為是將最后一層特征map拉成一條向量,所以對于一個樣本來說,特征維數(shù)是這樣

for j = 1 : numel(net.layers{n}.a) %最后一層的特征map的個數(shù)

net.layers{n}.d{j} = reshape(net.fvd(((j - 1) * fvnum + 1) : j * fvnum, :), sa(1), sa(2), sa(3));

end

for l = (n - 1) : -1 : 1 %對于輸出層前面的層(與輸出層計算殘差的方式不同)

if strcmp(net.layers{l}.type, 'c') %如果是卷積層,則進行上采樣

for j = 1 : numel(net.layers{l}.a) %該層特征map的個數(shù)

%%=========================================================================

%主要功能:卷積層的靈敏度誤差傳遞

%注意事項:1)net.layers{l}.d{j} 保存的是 第l層 的 第j個 map 的 靈敏度map。 也就是每個神經元節(jié)點的delta的值

% expand的操作相當于對l+1層的靈敏度map進行上采樣。然后前面的操作相當于對該層的輸入a進行sigmoid求導

% 這條公式請參考 Notes on Convolutional Neural Networks

%%=========================================================================

net.layers{l}.d{j} = net.layers{l}.a{j} .* (1 - net.layers{l}.a{j}) .* (expand(net.layers{l + 1}.d{j}, [net.layers{l + 1}.scale net.layers{l + 1}.scale 1]) / net.layers{l + 1}.scale ^ 2);

end

elseif strcmp(net.layers{l}.type, 's') %如果是下采樣層,則進行下采樣

%%=========================================================================

%主要功能:下采樣層的靈敏度誤差傳遞

%注意事項:1)這條公式請參考 Notes on Convolutional Neural Networks

%%=========================================================================

for i = 1 : numel(net.layers{l}.a) %第i層特征map的個數(shù)

z = zeros(size(net.layers{l}.a{1}));

for j = 1 : numel(net.layers{l + 1}.a) %第l+1層特征map的個數(shù)

z = z + convn(net.layers{l + 1}.d{j}, rot180(net.layers{l + 1}.k{i}{j}), 'full');

end

net.layers{l}.d{i} = z;

end

end

end

%%=========================================================================

%主要功能:計算梯度

%實現(xiàn)步驟:

%注意事項:1)這里與Notes on Convolutional Neural Networks中不同,這里的子采樣層沒有參數(shù),也沒有

% 激活函數(shù),所以在子采樣層是沒有需要求解的參數(shù)的

%%=========================================================================

for l = 2 : n

if strcmp(net.layers{l}.type, 'c')

for j = 1 : numel(net.layers{l}.a)

for i = 1 : numel(net.layers{l - 1}.a)

%%%%%%%%%%%%%%%%%%%%dk保存的是誤差對卷積核的導數(shù)%%%%%%%%%%%%%%%%%%%%

net.layers{l}.dk{i}{j} = convn(flipall(net.layers{l - 1}.a{i}), net.layers{l}.d{j}, 'valid') / size(net.layers{l}.d{j}, 3);

end

%%%%%%%%%%%%%%%%%%%?保存的是誤差對于bias基的導數(shù)%%%%%%%%%%%%%%%%%%%%

net.layers{l}.db{j} = sum(net.layers{l}.d{j}(:)) / size(net.layers{l}.d{j}, 3);

end

end

end

%%%%%%%%%%%%%%%%%%%%最后一層perceptron的gradient的計算%%%%%%%%%%%%%%%%%%%%

net.dffW = net.od * (net.fv)' / size(net.od, 2);

net.dffb = mean(net.od, 2);

function X = rot180(X)

X = flipdim(flipdim(X, 1), 2);

end

end

深度學習Matlab工具箱代碼注釋——cnnapplygrads.m

%%=========================================================================

%函數(shù)名稱:cnnapplygrads(),權值更新函數(shù)

%輸入參數(shù):net,權值待更新的卷積神經網絡;opts,神經網絡訓練的相關參數(shù)

%輸出參數(shù):

%算法流程:先更新卷積層的參數(shù),再更新全連接層參數(shù)

%注意事項:

%%=========================================================================

function net = cnnapplygrads(net, opts)

for l = 2 : numel(net.layers)

if strcmp(net.layers{l}.type, 'c')

for j = 1 : numel(net.layers{l}.a)

for ii = 1 : numel(net.layers{l - 1}.a)

%這里沒什么好說的,就是普通的權值更新的公式:W_new = W_old - alpha * de/dW(誤差對權值導數(shù))

net.layers{l}.k{ii}{j} = net.layers{l}.k{ii}{j} - opts.alpha * net.layers{l}.dk{ii}{j};

end

net.layers{l}.b{j} = net.layers{l}.b{j} - opts.alpha * net.layers{l}.db{j};

end

end

end

net.ffW = net.ffW - opts.alpha * net.dffW;

net.ffb = net.ffb - opts.alpha * net.dffb;

end

%%=========================================================================

% 主要功能:在mnist數(shù)據庫上做實驗,驗證工具箱的有效性

% 算法流程:1)載入訓練樣本和測試樣本

% 2)設置CNN參數(shù),并進行訓練

% 3)進行檢測cnntest()

% 注意事項:1)由于直接將所有測試樣本輸入會導致內存溢出,故采用一次只測試一個訓練樣本的測試方法

%%=========================================================================

%%

%%%%%%%%%%%%%%%%%%%%加載數(shù)據集%%%%%%%%%%%%%%%%%%%%

load mnist_uint8;

train_x = double(reshape(train_x',28,28,60000))/255;

test_x = double(reshape(test_x',28,28,10000))/255;

train_y = double(train_y');

test_y = double(test_y');

%%

%%=========================================================================

%%%%%%%%%%%%%%%%%%%%設置卷積神經網絡參數(shù)%%%%%%%%%%%%%%%%%%%%

% 主要功能:訓練一個6c-2s-12c-2s形式的卷積神經網絡,預期性能如下:

% 1)迭代一次需要200秒左右,錯誤率大約為11%

% 2)迭代一百次后錯誤率大約為1.2%

% 算法流程:1)構建神經網絡并進行訓練,以CNN結構體的形式保存

% 2)用已知的訓練樣本進行測試

% 注意事項:1)之前在測試的時候提示內存溢出,后來莫名其妙的又不溢出了,估計到了系統(tǒng)的內存臨界值

%%=========================================================================

rand('state',0)

cnn.layers = {

struct('type', 'i') %輸入層

struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %卷積層

struct('type', 's', 'scale', 2) %下采樣層

struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %卷積層

struct('type', 's', 'scale', 2) %下采樣層

};

cnn = cnnsetup(cnn, train_x, train_y);

opts.alpha = 1;

opts.batchsize = 50;

opts.numepochs = 5;

cnn = cnntrain(cnn, train_x, train_y, opts);

save CNN_5 cnn;

load CNN_5;

[er, bad] = cnntest(cnn, test_x, test_y);

figure; plot(cnn.rL);

assert(er<0.12, 'Too big error');



開放分享:優(yōu)質有限元技術文章,助你自學成才

相關標簽搜索:深度學習Matlab工具箱DeepLearnToolbox代碼注釋(轉) MatLab培訓 MatLab培訓課程 MatLab在線視頻教程 MatLab技術學習教程 MatLab軟件教程 MatLab資料下載 MatLab代做 MatLab基礎知識 Fluent、CFX流體分析 HFSS電磁分析 Ansys培訓 Abaqus培訓 

編輯
在線報名:
  • 客服在線請直接聯(lián)系我們的客服,您也可以通過下面的方式進行在線報名,我們會及時給您回復電話,謝謝!
驗證碼

全國服務熱線

1358-032-9919

廣州公司:
廣州市環(huán)市中路306號金鷹大廈3800
電話:13580329919
          135-8032-9919
培訓QQ咨詢:點擊咨詢 點擊咨詢
項目QQ咨詢:點擊咨詢
email:kf@1cae.com