深度学习Matlab工具箱代码注释——cnnbp.m
2015-09-22 21:45
579 查看
%%========================================================================= %函数名称:cnnbp() %输入参数:net,呆训练的神经网络;y,训练样本的标签,即期望输出 %输出参数:net,经过BP算法训练得到的神经网络 %主要功能:通过BP算法训练神经网络参数 %实现步骤:1)将输出的残差扩展成与最后一层的特征map相同的尺寸形式 % 2)如果是卷积层,则进行上采样 % 3)如果是下采样层,则进行下采样 % 4)采用误差传递公式对灵敏度进行反向传递 %注意事项:1)从最后一层的error倒推回来deltas,和神经网络的BP十分相似,可以参考“UFLDL的反向传导算法”的说明 % 2)在fvd里面保存的是所有样本的特征向量(在cnnff.m函数中用特征map拉成的),所以这里需要重新换回来特征map的形式, % d保存的是delta,也就是灵敏度或者残差 % 3)net.o .* (1 - net.o))代表输出层附加的非线性函数的导数,即sigm函数的导数 %%========================================================================= function net = cnnbp(net, y) n = numel(net.layers); %网络层数 net.e = net.o - y; %实际输出与期望输出之间的误差 net.L = 1/2* sum(net.e(:) .^ 2) / size(net.e, 2); %代价函数,采用均方误差函数作为代价函数 net.od = net.e .* (net.o .* (1 - net.o)); %输出层的灵敏度或者残差,(net.o .* (1 - net.o))代表输出层的激活函数的导数 net.fvd = (net.ffW' * net.od); %残差反向传播回前一层,net.fvd保存的是残差 if strcmp(net.layers{n}.type, 'c') %只有卷积层采用sigm函数 net.fvd = net.fvd .* (net.fv .* (1 - net.fv)); %net.fv是前一层的输出(未经过simg函数),作为输出层的输入 end %%%%%%%%%%%%%%%%%%%%将输出的残差扩展成与最后一层的特征map相同的尺寸形式%%%%%%%%%%%%%%%%%%%% sa = size(net.layers{n}.a{1}); %最后一层特征map的大小。这里的最后一层都是指输出层的前一层 fvnum = sa(1) * sa(2); %因为是将最后一层特征map拉成一条向量,所以对于一个样本来说,特征维数是这样 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 %对于输出层前面的层(与输出层计算残差的方式不同) if strcmp(net.layers{l}.type, 'c') %如果是卷积层,则进行上采样 for j = 1 : numel(net.layers{l}.a) %该层特征map的个数 %%========================================================================= %主要功能:卷积层的灵敏度误差传递 %注意事项:1)net.layers{l}.d{j} 保存的是 第l层 的 第j个 map 的 灵敏度map。 也就是每个神经元节点的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的个数 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中不同,这里的子采样层没有参数,也没有 % 激活函数,所以在子采样层是没有需要求解的参数的 %%========================================================================= 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保存的是误差对卷积核的导数%%%%%%%%%%%%%%%%%%%% 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 %%%%%%%%%%%%%%%%%%%%db保存的是误差对于bias基的导数%%%%%%%%%%%%%%%%%%%% 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工具箱代码注释——cnnff.m
- 深度学习Matlab工具箱代码注释——cnntrain.m
- 深度学习Matlab工具箱代码注释——cnnsetup.m
- 深度学习Matlab工具箱代码注释——MnistTest.m
- matlab截取图像
- matlab求取积分
- 用MATLAB将多个文件夹内的某些文件汇总到另一个文件夹
- Ubuntu14 32位系统下安装Matlab2012a步骤
- matlab笔记
- Matlab给曲线添加加参考线
- 分享:matlab实现分数阶傅里叶变换源程序
- 如何在python中读写和存储matlab的数据文件(*.mat)
- Matlab绘制阶梯形图
- 【Matlab学习笔记】【函数学习】eps
- matlab学习之数组学习
- matlab uigetfile()的使用
- matlab(3) Logistic Regression: 求cost 和gradient \ 求sigmoid的值
- matlab 图像保存函数及使用方法
- matlab | 与 || 的区别
- 我的Matlab 图像方面的学习历程(一)基础知识点