当前位置:网站首页>Deep Learning Matlab Toolbox Code Comments

Deep Learning Matlab Toolbox Code Comments

2022-08-11 06:55:00 Sherry shen

test_example_CNN.m

%%=========================================================================
% 主要功能:在mnist数据库上做实验,Verify the validity of the toolbox
% 算法流程:1)Load training samples and test samples
%          2)设置CNN参数,并进行训练
%          3)进行检测cnntest()
% 注意事项:1)Memory overflow due to direct input of all test samples,Therefore, the test method of testing only one training sample at a time is adopted.
%%=========================================================================
%%
%%%%%%%%%%%%%%%%%%%%加载数据集%%%%%%%%%%%%%%%%%%%%
% Convert the grayscale value of the image to0~1,Because this code usessigmoid激活函数
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');
 
%%
%%=========================================================================
%%%%%%%%%%%%%%%%%%%%Set Convolutional Neural Network Parameters%%%%%%%%%%%%%%%%%%%%
% 主要功能:训练一个6c-2s-12c-2sConvolutional Neural Networks of the form,The expected performance as follows:
%          1)Iterate once200秒左右,错误率大约为11%
%          2)The error rate after one hundred iterations is approximately1.2%
% 算法流程:1)Build and train a neural network,以CNNstored in the form of a structure
%          2)Test with known training samples
% 注意事项:1)Memory overflow was prompted when testing,Then, somehow, it didn't overflow again.,Estimated system memory threshold
%% The structure of the convolutional network is 6c-2s-12c-2s 
% 1 epoch 会运行大约200s, 错误率大约为11%.而 100 epochs The error rate is approximately1.2%.
%%=========================================================================
rand('state',0)%The specified state make each run produces random results are the same
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,it builds a completeCNN网络,并返回
cnn = cnnsetup(cnn, train_x, train_y);
% 学习率  % 梯度下降的步长
opts.alpha = 1;  
% Pick out one at a timebatchsize的batch来训练,That is, every timebatchsizeAdjust the weights once every sample,而不是  
% All samples are entered,Calculate the error of all samples before adjusting the weights once  
% 每次批处理50张图
opts.batchsize = 50;   
% 训练次数,with the same sample set.我训练的时候:  
% 1的时候 11.41% error  
% 5的时候 4.2% error  
% 10的时候 2.73% error  
opts.numepochs = 10;  
  
% Then start feeding it training samples,start training thisCNN网络  
cnn            = cnntrain(cnn, train_x, train_y, opts);
save CNN_5 cnn;
 
load CNN_5;
% Then use the test sample to test 
[er, bad]  = cnntest(cnn, test_x, test_y);
figure; plot(cnn.rL);
assert(er<0.12, 'Too big error');

cnnsetup

%%=========================================================================
% 函数名称:cnnsetup
% 输入参数:net,Convolutional Neural Network to be set up;x,训练样本;y,The training sample corresponding labels;
% 输出参数:net,Initialized Convolutional Neural Network
% 主要功能:对CNN的结构进行初始化
% 算法流程:1% 注意事项:1)isOctaveThis statement is intended to throw a program inOctaveA runtime platformBUG,在matlabCan be commented out directly on the platform
%          2)net.layers中有五个struct类型的元素,Actually saidCNN共有五层,The scope here is5
%%=========================================================================
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;    %Initialize the network input layers as1%%=========================================================================
% 主要功能:Get the number of rows and columns of the input image
% 注意事项:1)B=squeeze(A) 返回和矩阵AMatrix with the same elements but with all single dimensions removedB,A single dimension is satisfiedsize(A,dim)=1的维.
%             train_xThe image is stored in three-dimensionalreshape(train_x',28,28,60000),The first two dimensions represent the rows and columns of the image,
%             The third dimension represents how many images there are.这样squeeze(x(:, :, 1))It is equivalent to taking the first image sample after,Then the third dimension
%             移除,就变成了28x28的矩阵,that is to get an image,再sizeThe number of rows and columns of the training sample image is obtained at once
%%=========================================================================
mapsize   = size(squeeze(x(:, :, 1)));
%%%%%%%%%%%%%%%%%%%%Below is passed innetThis structure is built layer by layerCNN网络%%%%%%%%%%%%%%%%%%%%
for l = 1 : numel(net.layers)                    %对于每一层
    if strcmp(net.layers{
    l}.type, 's')           %If the current layer is a downsampling layer
 %%=========================================================================
 % 主要功能:Get features after downsamplingmap的尺寸
 % 注意事项:1)subsampling层的mapsize,最开始mapsizeIs the size of each figure28*28
 %  这里除以scale=2,就是poolingthe size of the image after,poolingNo overlap between domains,所以poolingThe image after is14*14
 %  Note the right heremapsizeAll the features of the previous layer are savedmap的大小,It will be continuously updated with the loop
 %%=========================================================================
        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          %For each feature map of the previous layer
            net.layers{
    l}.b{
    j} = 0;    %initialize the bias to zero
        end
    end
    
    if strcmp(net.layers{
    l}.type, 'c') %如果当前层是卷积层
        %%=========================================================================
        % 主要功能:Get the convolutional featuresmapThe size and the number of parameters of the convolution kernel to be learned in the current layer
        % 注意事项:1)旧的mapsizeAre stored on the features of a layermap的大小,Then if the moving step size of the convolution kernel is1,那用
        %     kernelsize*kernelsizeThe size of the convolution kernel convolves the features of the previous layermap后,得到的新的mapThe size is as follows
        %  2)fan_outOn behalf of the layer number of parameters in the need to learn.each featuremap是一个(The number of feature maps in the back layer)*(for convolutionpatch图的大小)
        %  Because it is done by using a kernel window in the previous featuremapmove in layers(The kernel window moves every time1个像素),iterate over the previous featuremap
        %  层的每个神经元.nuclear window bykernelsize*kernelsize个元素组成,Each element is an independent weight,所以
        %  就有kernelsize*kernelsizeweights to learn,add an offset.另外,Due to weight sharing,也就是
        %  say the same featuremapLayers use the same element with the same weightkernelsize*kernelsizethe kernel window to feel the input on the
        %  个特征mapEach neuron of the layer gets,So the same featuremap,its weight is the same,共享的,The weight only depends on
        %  nuclear window.然后,不同的特征mapExtract the previous feature of the inputmapLayer of different characteristics,So the kernel window used is different,也
        %It's just that the weights are different,所以outputmaps个特征map就有(kernelsize*kernelsize+1* outputmapsThat much weight
        %  但这里fan_outOnly save the weights of the convolution kernelW,偏置bSave it independently below
        %%=========================================================================
        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   %for each output of the convolutional layermap
            %%=========================================================================
            % 主要功能:Get the output of the convolutional layer and the previous layermapThe number of parameter chains that need to be linked between
            % 注意事项:1)fan_outWhat is saved is a feature for the previous layermap,I need this feature at this levelmap提取outputmaps种特征,
            %   Different convolution kernels are used to extract each feature,所以fan_outWhat is saved is the number of parameters that this layer needs to learn to output new features
            %   而,fan_in保存的是,I'm on this floor,To connect to a layer of all of the featuresmap,然后用fan_outSaved extracted features
            %   weights to extract their features.That is, for each current layer feature map,how many parameters are chained to the previous layer
            %%=========================================================================
            fan_in = inputmaps * net.layers{
    l}.kernelsize ^ 2;
            
            for i = 1 : inputmaps                 %For each output feature of the previous layermap(本层的输入map)
                %%=========================================================================
% 主要功能:Randomly initialize the weights of the convolution kernel,Then offset are initialized to zero
% 注意事项:1)随机初始化权值,也就是共有outputmaps个卷积核,For each feature of the upper layermap,All need to use so many convolution kernels to deconvolute to extract features.
%             rand(n)是产生n×n的 0-1Evenly between the numerical value of matrix,再减去0.5就相当于产生-0.50.5之间的随机数
%*2 就放大到 [-1, 1].Then multiply by the latter number,why?
% Anyway, initialize each element of the convolution kernel as[-sqrt(6 / (fan_in + fan_out)), sqrt(6 / (fan_in + fan_out))]
%             之间的随机数.Because there is a weight Shared,That is, for a featuremap,The convolution kernels at all receptive field positions are the same
%             So all you need to save is 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;    %In the convolutional layer, the output of each layer of the network is updatedmap数量
    end
end
%%=========================================================================
% 主要功能:Initialize the last layer,That is, the parameter value of the output layer
% 算法流程:1)fvnum is the number of neurons in the previous layer of the output layer.The layer above this layer is throughpoolingAfter the layer,包含有inputmaps个
%             特征map.每个特征map的大小是mapsize,所以,The number of neurons in this layer is inputmaps * (每个特征map的大小)  
%          2)onum 是标签的个数,That is, the number of neurons in the output layer.how many classes do you want,Naturally, how many output neurons are there?
%          3)net.ffb和net.ffWfor the last layer(全连接层)Bias and weights of
%%=========================================================================
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

cnntrain.m

%%=========================================================================
%函数名称:cnntrain()
%输入参数:net,神经网络;x,训练数据矩阵;y,label matrix for training data;opts,Relevant training parameters of the neural network
%输出参数:net,Trained Convolutional Neural Network
%算法流程:1)将样本打乱,Randomly selected for training;
%         2)取出样本,通过cnnff2()Function to calculate the current network weights and the output of the network under the network input
%         3)通过BPDerivative algorithm calculation error of network weights
%         4)After getting the derivative of the error with respect to the weight,Just update the weights through the weight update method
%注意事项:1)使用BP算法计算梯度
%%=========================================================================
function net = cnntrain(net, x, y, opts)
m = size(x, 3);                      %mSave the number of training samples
 % rem: Remainder after division. rem(x,y) is x - n.*y 相当于求余  
 % rem(numbatches, 1) is equivalent to taking the fractional part,如果为0,就是整数
disp(['样本总个数=' num2str(m)]);
numbatches = m / opts.batchsize;     %numbatchesIndicates the number of training samples selected in each iteration
if rem(numbatches, 1) ~= 0           %如果numbatches不是整数,则程序发生错误
    error('numbatches not integer');
end
 
%%=====================================================================
%主要功能:CNNIterative training of the network
%实现步骤:1)通过randperm()The function shuffles the original sample order,Pick out some more samples for training
%         2)取出样本,通过cnnff2()Function to calculate the current network weights and the output of the network under the network input
%         3)通过BPDerivative algorithm calculation error of network weights
%         4)After getting the derivative of the error with respect to the weight,Just update the weights through the weight update method
%注意事项:1)P = randperm(N),返回[1, N]a random sequence of all integers between,It is equivalent to shuffling the original sample arrangement.,
%            Pick out some more samples to train
%         2)Using the calculation method of cumulative error to evaluate the current network performance,The current error = previous error * 0.99 + 本次误差 * 0.01
%            Make the network converge to the global optimum as much as possible
%%=====================================================================
net.rL = [];                         %代价函数值,that is the error value
for i = 1 : opts.numepochs           %对于每次迭代
% disp(X) 打印数组元素.如果X是个字符串,then print this string       
    disp(['epoch ' num2str(i) '/' num2str(opts.numepochs)]);
    tic;              %使用tic和toc来统计程序运行时间tic 和 toc 是用来计时的,The amount of time spent on the calculation between these two statements  
    
    %%%%%%%%%%%%%%%%%%%%After take out the orderbatchsizesamples and corresponding labels %%%%%%%%%%%%%%%%%%%%
     % P = randperm(N) 返回[1, N]a random sequence of all integers between,例如  
     % randperm(6) 可能会返回 [2 4 5 6 1 3]  
     % This is equivalent to shuffling the original sample arrangement.,Pick out some more samples to train
    kk = randperm(m);               
    for l = 1 : numbatches
     % After take out the orderbatchsizesamples and corresponding labels 
        batch_x = x(:, :, kk((l - 1) * opts.batchsize + 1 : l * opts.batchsize));
        batch_y = y(:,    kk((l - 1) * opts.batchsize + 1 : l * opts.batchsize));
        
        %%%%%%%%%%%%%%%%%%%%Calculate the output of the network given the current network weights and network inputs(特征向量)%%%%%%%%%%%%%%%%%%%%
        net = cnnff(net, batch_x); %Feedforward Operation of Convolutional Neural Networks
        
        %%%%%%%%%%%%%%%%%%%%through the corresponding sample label withbpalgorithm to get the derivative of the error with respect to the network weights%%%%%%%%%%%%%%%%%%%%
        net = cnnbp(net, batch_y); %卷积神经网络的BP算法
        
        %%%%%%%%%%%%%%%%%%%%Update weights by weight update method%%%%%%%%%%%%%%%%%%%%
        net = cnnapplygrads(net, opts);
        
        if isempty(net.rL)
            net.rL(1) = net.L;     %代价函数值,That is, the mean squared error value ,在cnnbp.mCalculate the initial value in 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; %Calculate the cumulative error in a cumulative manner
    end
    toc;
end
end

cnnff.m

%%=========================================================================
%函数名称:cnnff()
%输入参数:net,神经网络;x,训练数据矩阵;
%输出参数:net,Trained Convolutional Neural Network
%主要功能:Predict the input vector using the current neural network
%算法流程:1)将样本打乱,Randomly selected for training;
%         2)Sample input network,Layer-by-layer mapping to get the predicted value
%注意事项:1)使用BP算法计算梯度
%%=========================================================================
function net = cnnff(net, x)
n                  = numel(net.layers);      %层数
net.layers{
    1}.a{
    1} = x;                      %The first layer of the network's input,But here the input contains multiple training images
inputmaps          = 1;                      %A feature input layer onlymap,That is, the original input image
for l = 2 : n                                %对于每层(第一层是输入层,Ignore when looping)
    if strcmp(net.layers{
    l}.type, 'c')       %如果当前是卷积层
        for j = 1 : net.layers{
    l}.outputmaps %对每一个输入map,需要用outputmapsDifferent convolution kernels deconvolution image
            %%=========================================================================
            %主要功能:创建outmap的中间变量,即特征矩阵
            %实现步骤:Use this formula to generate a matrix of zeros,作为特征map
            %注意事项:1)For each feature of the previous layermap,Characteristics after the convolutionmap的大小是:(输入map宽 - 卷积核的宽 + 1* (输入map高 - 卷积核高 + 1%         2)Since each layer contains multiple featuresmap,Is the corresponding index is stored in each layermap的第三维,及变量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    %for each feature of the inputmap
                %%=========================================================================
                %主要功能:Each feature of the previous layer ismap(也就是这层的输入map)Convolve with the convolution kernel of this layer
                %实现步骤:1)进行卷积
                %         2)plus the base of the corresponding positionb,然后再用sigmoidThe function calculates the featuremapactivation value for each position in,as the output feature of this layermap
                %注意事项:1)A feature of the current layermap,is to use a convolution kernel to deconvolve all the features in the previous layermap,then all featuresmapthe sum of the convolution values ​​at the corresponding positions
                %         2)Some papers or practical applications,not all featuresmap链接的,Possible only with a few of the connection
                %%=========================================================================
                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});   %gaki(plus additive biasb)
        end
        inputmaps = net.layers{
    l}.outputmaps;                    %更新当前层的map数量;
        
    elseif strcmp(net.layers{
    l}.type, 's')                       %If the current layer is a downsampling layer
        for j = 1 : inputmaps
            %%=========================================================================
            %主要功能:对特征map进行下采样
            %实现步骤:1)进行卷积
            %         2)最终poolingThe result needs to be obtained from the convolution result obtained above withscale=2为步长,jumpmean pooling的值读出来
            %注意事项:1)例如我们要在scale=2The domain of the abovemean pooling,Then the convolution size can be2*2,每个元素都是1/4的卷积核
            %         2)因为convnThe default convolution stride for the function is1,而poolingThere is no overlapping operation domain,So for the above convolution result
            %         3)To implement sampling is the method of using convolution
            %%=========================================================================
            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
 
%%=========================================================================
%主要功能:输出层,Turn the features obtained by the last layer into a vector,As the final extracted feature vector
%实现步骤:1)Get each feature in the penultimate layermap的尺寸
%         2)用reshape函数将map转换为向量的形式
%         3)使用sigmoid(W*X + b)function computes sample output values,放到net成员o中
%注意事项:1)在使用sigmoid()函数是,are calculated at the same timebatchsizeA sample of the output value
%%=========================================================================
net.fv = [];                       %net.fvis the output of the penultimate layer of the neural networkmap
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))); %The final prediction output of the network is obtained through the mapping of the fully connected layer
end

cnnbp.m

%%=========================================================================
%函数名称:cnnbp()
%输入参数:net,dumb trained neural network;y,训练样本的标签,即期望输出
%输出参数:net,经过BPThe neural network trained by the algorithm
%主要功能:通过BPAlgorithm to train neural network parameters
%实现步骤:1)The output of the residual expanded into and the characteristics of the last layermapsame size form
%         2)如果是卷积层,upsampling
%         3)If it is under sampling layer,downsampling
%         4)Sensitivity is reversely transferred using the error transfer formula
%注意事项:1)从最后一层的error倒推回来deltas,和神经网络的BP十分相似,可以参考“UFLDLbackpropagation algorithm”的说明
%         2)在fvdIt stores the eigenvectors of all samples(在cnnff.mUsing characteristic functionmapdrawn),So here you need to switch back to the featuremap的形式,
%            d保存的是delta,Sensitivity or residual
%         3)net.o .* (1 - net.o))On behalf of the output layer added the derivative of nonlinear function,即sigm函数的导数
%%=========================================================================
function net = cnnbp(net, y)
n     = numel(net.layers);                         %网络层数
net.e = net.o - y;                                 %Error between actual output and expected output
net.L = 1/2* sum(net.e(:) .^ 2) / size(net.e, 2);  %代价函数,Use the mean squared error function as the cost function
net.od = net.e .* (net.o .* (1 - net.o));          %The sensitivity or residual of the output layer,(net.o .* (1 - net.o))represents the derivative of the activation function of the output layer
net.fvd = (net.ffW' * net.od);                     %The residuals are back-propagated back to the previous layer,net.fvdResiduals are saved
if strcmp(net.layers{
    n}.type, 'c')                 %Only using convolution layersigm函数
    net.fvd = net.fvd .* (net.fv .* (1 - net.fv)); %net.fv是前一层的输出(未经过simg函数),作为输出层的输入
end
%%%%%%%%%%%%%%%%%%%%The output of the residual expanded into and the characteristics of the last layermapsame size form%%%%%%%%%%%%%%%%%%%%
sa    = size(net.layers{
    n}.a{
    1});           %最后一层特征map的大小.In this case, the last layer is the layer before the output layer
fvnum = sa(1) * sa(2);                      %Because it is the last layer of featuresmappull into a vector,So for a sample,The feature dimension is like this
for j = 1 : numel(net.layers{
    n}.a)          %最后一层的特征map的个数
    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                    %For layers preceding the output layer(And the output layer calculated residual in different ways)
    if strcmp(net.layers{
    l}.type, 'c')      %如果是卷积层,upsampling
        for j = 1 : numel(net.layers{
    l}.a)  %Features of this layermap的个数
            %%=========================================================================
            %主要功能:Convolution layer, the sensitivity of error transfer
            %注意事项:1)net.layers{
    l}.d{
    j} 保存的是 第l层 的 第j个 map 的 灵敏度map. That is, each neuron node'sdelta的值
            %            expandoperation is equivalent tol+1layer sensitivitymap进行上采样.Then the previous operation is equivalent to the input to the layera进行sigmoid求导
            %            Please refer to this formula 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')            %If it is under sampling layer,downsampling
        %%=========================================================================
        %主要功能:Sensitivity Error Propagation for Downsampling Layers
        %注意事项:1)Please refer to this formula Notes on Convolutional Neural Networks
        %%=========================================================================
        for i = 1 : numel(net.layers{
    l}.a)            %第i层特征map的个数
            z = zeros(size(net.layers{
    l}.a{
    1}));
            for j = 1 : numel(net.layers{
    l + 1}.a)    %第l+1层特征map的个数
                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
%%=========================================================================
%主要功能:计算梯度
%实现步骤:
%注意事项:1)这里与Notes on Convolutional Neural Networks中不同,Here the subsampling layer has no parameters,也没有
%            激活函数,So there are no parameters to solve in the subsampling layer
%%=========================================================================
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)
                
                %%%%%%%%%%%%%%%%%%%%dkSave the error derivative of convolution kernels%%%%%%%%%%%%%%%%%%%%
                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
            
            %%%%%%%%%%%%%%%%%%%%dbSaved is the error forbiasDerivative of the basis%%%%%%%%%%%%%%%%%%%%
            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

cnnapplygrads.m

%%=========================================================================
%函数名称:cnnapplygrads(),权值更新函数
%输入参数:net,The convolutional neural network whose weights are to be updated;opts,Relevant parameters for neural network training
%输出参数:
%算法流程:First update the parameters of the convolutional layer,Then update the parameters of the fully connected layer
%注意事项:
%%=========================================================================
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)
                
                %这里没什么好说的,It is the formula of ordinary weight update:W_new = W_old - alpha * de/dW(Error vs. Weight Derivative)
                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

cnntest.m

function [er, bad] = cnntest(net, x, y)    
    %  feedforward    
    net = cnnff(net, x); % 前向传播得到输出    
    % [Y,I] = max(X) returns the indices of the maximum values in vector I    
    [~, h] = max(net.o); % Find the label corresponding to the largest output    
    [~, a] = max(y);     % Find the largest expected output corresponding index    
    bad = find(h ~= a);  % find the number of them that are not identical,the number of errors    
    
    er = numel(bad) / size(y, 2); % 计算错误率    
end    
原网站

版权声明
本文为[Sherry shen]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/223/202208110515295178.html