CNN反向传播算法公式
网络结构(6c-2s-12c-2s):
初始化:
\begin{align}\notag
W \sim U(- \frac{\sqrt{6}}{\sqrt{n_j+n_{j+1}}} , \frac{\sqrt{6}}{\sqrt{n_j+n_{j+1}}})
\end{align}
\begin{align}\notag
Var(W_i) = \frac{1}{n_i} ; Var(W_i) = \frac{1}{n_{i+1}} ; Var(W_i) = \frac{1}{n_i + n_{i+1}}
\end{align}
偏置 $ b $ 统一初始化为 $ 0 $ ,权重 $ W $ 设置为 $ random(-1,1)\sqrt{\frac{6}{fan_{in} + fan_{out}}} \sim U(- \frac{\sqrt{6}}{\sqrt{n_j+n_{j+1}}} , \frac{\sqrt{6}}{\sqrt{n_j+n_{j+1}}}) $ , $ n_j $ 表示神经网络的大小, $ fan_{in} = 输入通道数\times卷积核size $ , $ fan_{out} = 输出通道数\times卷积核size $ 。
for l = 1 : numel(net.layers) % layer
if strcmp(net.layers{l}.type, 's')
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')
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 % output map
fan_in = inputmaps * net.layers{l}.kernelsize ^ 2;
for i = 1 : inputmaps % input map
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;
end
end
% 'onum' is the number of labels, that's why it is calculated using size(y, 1). If you have 20 labels so the output of the network will be 20 neurons.
% 'fvnum' is the number of output neurons at the last layer, the layer just before the output layer.
% 'ffb' is the biases of the output neurons.
% 'ffW' is the weights between the last layer and the output neurons. Note that the last layer is fully connected to the output layer, that's why the size of the weights is (onum * fvnum)
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));
前向传播:
\begin{align}\notag
x_j^l = f(\sum_ {i\in M_j} x_i^{l-1} * k_{ij}^l + b_j^l)
\end{align}
% !!below can probably be handled by insane matrix operations
for j = 1 : net.layers{l}.outputmaps % for each output map
% create temp output map
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 input map
% convolve with corresponding kernel and add to temp output map
z = z + convn(net.layers{l - 1}.a{i}, net.layers{l}.k{i}{j}, 'valid');
end
% add bias, pass through nonlinearity
net.layers{l}.a{j} = sigm(z + net.layers{l}.b{j});
end
% set number of input maps to this layers number of outputmaps
inputmaps = net.layers{l}.outputmaps;
前向传播:
\begin{align}\notag
x_j^l = f(\beta_j^l down(x_j^{l-1}) + b_j^l)
\end{align}
% downsample
for j = 1 : inputmaps
z = convn(net.layers{l - 1}.a{j}, ones(net.layers{l}.scale) / (net.layers{l}.scale ^ 2), 'valid'); % !! replace with variable
net.layers{l}.a{j} = z(1 : net.layers{l}.scale : end, 1 : net.layers{l}.scale : end, :);
end
前向传播:
% concatenate all end layer feature maps into vector
net.fv = [];
for j = 1 : numel(net.layers{n}.a)
sa = size(net.layers{n}.a{j});
net.fv = [net.fv; reshape(net.layers{n}.a{j}, sa(1) * sa(2), sa(3))];
end
% feedforward into output perceptrons
net.o = sigm(net.ffW * net.fv + repmat(net.ffb, 1, size(net.fv, 2)));
sigmoid函数求导:
\begin{align}\notag
f(x) = \frac{1}{1+e^{-x}} ; f^\prime(x) = \frac{e^{-x}}{(1+e^{-x})^2} = f(x) \cdot [1 - f(x)]
\end{align}
对网络的最后一层输出层,计算输出值和样本值得残差:
\begin{align}\notag
\delta^n = -(y-a^n)\cdot f^\prime(z^n)
\end{align}
% error
net.e = net.o - y;
%% backprop deltas
net.od = net.e .* (net.o .* (1 - net.o)); % output delta
对于隐层 $ l = n-1,n-2,n-3,...,2 $ ,计算各节点残差:
\begin{align}\notag
\delta^l = ({(W^l)}^T \delta^{l+1}) \cdot f^\prime(z^l)
\end{align}
% concatenate all end layer feature maps into vector
net.fv = [];
for j = 1 : numel(net.layers{n}.a)
sa = size(net.layers{n}.a{j});
net.fv = [net.fv; reshape(net.layers{n}.a{j}, sa(1) * sa(2), sa(3))];
end
net.fvd = (net.ffW' * net.od); % feature vector delta
if strcmp(net.layers{n}.type, 'c') % only conv layers has sigm function
net.fvd = net.fvd .* (net.fv .* (1 - net.fv));
end
反向传播:
\begin{align}\notag
\delta_j^l = f^\prime(u_j^l)\circ conv2(\delta_j^{l+1},rot180(k_j^{l+1}),'full')
\end{align}
for i = 1 : numel(net.layers{l}.a)
z = zeros(size(net.layers{l}.a{1}));
for j = 1 : numel(net.layers{l + 1}.a)
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
反向传播:
\begin{align}\notag
\delta_j^l = \beta_j^{l+1}(f^\prime(u_j^l) \circ up(\delta_j^{l+1}))
\end{align}
for j = 1 : numel(net.layers{l}.a)
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
计算最终需要的偏导数值:
\begin{align}\notag
\nabla_{W^l}J(W,b;x,y) = \delta^{l+1}(a^l)^T
\end{align}
\begin{align}\notag
\nabla_{b^l}J(W,b;x,y) = \delta^{l+1}
\end{align}
\begin{align}\notag
\nabla_{W^l}J(W,b) = [\frac{1}{m}\sum_{i=1}^m\nabla_{W^l}J(W,b;x,y)]+\lambda W_{ij}^l
\end{align}
\begin{align}\notag
\nabla_{b^l}J(W,b) = \frac{1}{m}\sum_{i=1}^m\nabla_{b^l}J(W,b;x,y)
\end{align}
\begin{align}\notag
\frac{\partial E}{\partial k_{ij}^l} = rot180(conv2(x_i^{l-1},rot180(\delta_j^l),'valid'))
\end{align}
\begin{align}\notag
\frac{\partial E}{\partial b_j} = \sum_{u,v}(\delta_j^l)_{uv}
\end{align}
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)
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
net.layers{l}.db{j} = sum(net.layers{l}.d{j}(:)) / size(net.layers{l}.d{j}, 3);
end
end
end
net.dffW = net.od * (net.fv)' / size(net.od, 2);
net.dffb = mean(net.od, 2);
CNN反向传播算法公式的更多相关文章
- 卷积神经网络(CNN)反向传播算法
在卷积神经网络(CNN)前向传播算法中,我们对CNN的前向传播算法做了总结,基于CNN前向传播算法的基础,我们下面就对CNN的反向传播算法做一个总结.在阅读本文前,建议先研究DNN的反向传播算法:深度 ...
- CNN反向传播更新权值
背景 反向传播(Backpropagation)是训练神经网络最通用的方法之一,网上有许多文章尝试解释反向传播是如何工作的,但是很少有包括真实数字的例子,这篇博文尝试通过离散的数据解释它是怎样工作的. ...
- CNN反向传播算法过程
主模块 规格数据输入(加载,调格式,归一化) 定义网络结构 设置训练参数 调用初始化模块 调用训练模块 调用测试模块 画图 初始化模块 设置初始化参数(输入通道,输入尺寸) 遍历层(计算尺寸,输入输出 ...
- CNN中卷积层 池化层反向传播
参考:https://blog.csdn.net/kyang624823/article/details/78633897 卷积层 池化层反向传播: 1,CNN的前向传播 a)对于卷积层,卷积核与输入 ...
- CNN的反向传播
在一般的全联接神经网络中,我们通过反向传播算法计算参数的导数.BP 算法本质上可以认为是链式法则在矩阵求导上的运用.但 CNN 中的卷积操作则不再是全联接的形式,因此 CNN 的 BP 算法需要在原始 ...
- CNN压缩:为反向传播添加mask(caffe代码修改)
神经网络压缩的研究近三年十分热门,笔者查阅到相关的两篇博客,博主们非常奉献的提供了源代码,但是发发现在使用gpu训练添加mask的网络上,稍微有些不顺,特此再进行详细说明. 此文是在 基于Caffe的 ...
- 《神经网络的梯度推导与代码验证》之CNN前向和反向传播过程的代码验证
在<神经网络的梯度推导与代码验证>之CNN的前向传播和反向梯度推导 中,我们学习了CNN的前向传播和反向梯度求导,但知识仍停留在纸面.本篇章将基于深度学习框架tensorflow验证我们所 ...
- CNN卷积层基础:特征提取+卷积核+反向传播
本篇介绍卷积层的线性部分 一.与全连接层相比卷积层有什么优势? 卷积层可以节省参数,因为卷积运算利用了图像的局部相关性——分析出一小片区域的特点,加上Pooling层(汇集.汇聚),从附近的卷积结果中 ...
- 神经网络训练中的Tricks之高效BP(反向传播算法)
神经网络训练中的Tricks之高效BP(反向传播算法) 神经网络训练中的Tricks之高效BP(反向传播算法) zouxy09@qq.com http://blog.csdn.net/zouxy09 ...
随机推荐
- 强化学习-Q-learning学习笔记
Q学习动作探索策略中的ep-greepy,以ep的概率进行随机探索,以1-ep的概率以最大值策略进行开发,因为设定的迭代次数比较多,所以肯定存在一定的次数去搜索不同的动作. 1)Python版本 b站 ...
- VBA 学习笔记 - 输入框
学习资料 https://www.yiibai.com/vba/vba_input_box.html 输入框 InputBox 函数说明 提示用户输入值.当输入值后,如果用户单击确定 按钮或按下键盘上 ...
- Python中Numpy.nonzero()函数
Numpy.nonzero()返回的是数组中,非零元素的位置.如果是二维数组就是描述非零元素在几行几列,三维数组则是描述非零元素在第几组中的第几行第几列. 举例如下: 二维数组: a = np.arr ...
- PB 数据窗口点击标题不能排序的一个原因
标题必须和数据行名称一致,如 数据行列名为:num ,标题行必须为 num_t 才可以
- WinForm开发(6)——C#/winform程序打包部署时,如何把SQL数据库一起打包进去
打包数据库到安装程序中 方法1. 备份/恢复先备份数据库:backup database 数据库 to disk='c:\备份.bak' 将备份文件打包到安装程序中. 在第一次运行程序的时候,进行数据 ...
- C - Water The Garden
It is winter now, and Max decided it's about time he watered the garden. The garden can be represent ...
- Cisco AP-如何调整LAP信道
GUI方法: CLI的方法:根据对应的接口去调整信道,信道带宽,传输功率等信息吧.(Cisco Controller) >config slot 0 antenna Configures the ...
- js屏幕上下滚动条
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- 关于cctype头⽂件⾥的⼀些函数
本文摘录柳神笔记: 刚刚在头⽂件那⼀段中也提到, #include 本质上来源于C语⾔标准函数库中的头⽂件 #include ,其实并不属于C++新特性的范畴,在刷PAT⼀些字符串逻辑题的时候也经常⽤ ...
- leetcode 0206
目录 ✅ 292. Nim 游戏 ✅ 933. 最近的请求次数 ✅ 942. 增减字符串匹配 仍旧有需要思考的地方 py尝试 ✅ 977. 有序数组的平方 ✅ 292. Nim 游戏 https:// ...