网络结构(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反向传播算法公式的更多相关文章

  1. 卷积神经网络(CNN)反向传播算法

    在卷积神经网络(CNN)前向传播算法中,我们对CNN的前向传播算法做了总结,基于CNN前向传播算法的基础,我们下面就对CNN的反向传播算法做一个总结.在阅读本文前,建议先研究DNN的反向传播算法:深度 ...

  2. CNN反向传播更新权值

    背景 反向传播(Backpropagation)是训练神经网络最通用的方法之一,网上有许多文章尝试解释反向传播是如何工作的,但是很少有包括真实数字的例子,这篇博文尝试通过离散的数据解释它是怎样工作的. ...

  3. CNN反向传播算法过程

    主模块 规格数据输入(加载,调格式,归一化) 定义网络结构 设置训练参数 调用初始化模块 调用训练模块 调用测试模块 画图 初始化模块 设置初始化参数(输入通道,输入尺寸) 遍历层(计算尺寸,输入输出 ...

  4. CNN中卷积层 池化层反向传播

    参考:https://blog.csdn.net/kyang624823/article/details/78633897 卷积层 池化层反向传播: 1,CNN的前向传播 a)对于卷积层,卷积核与输入 ...

  5. CNN的反向传播

    在一般的全联接神经网络中,我们通过反向传播算法计算参数的导数.BP 算法本质上可以认为是链式法则在矩阵求导上的运用.但 CNN 中的卷积操作则不再是全联接的形式,因此 CNN 的 BP 算法需要在原始 ...

  6. CNN压缩:为反向传播添加mask(caffe代码修改)

    神经网络压缩的研究近三年十分热门,笔者查阅到相关的两篇博客,博主们非常奉献的提供了源代码,但是发发现在使用gpu训练添加mask的网络上,稍微有些不顺,特此再进行详细说明. 此文是在 基于Caffe的 ...

  7. 《神经网络的梯度推导与代码验证》之CNN前向和反向传播过程的代码验证

    在<神经网络的梯度推导与代码验证>之CNN的前向传播和反向梯度推导 中,我们学习了CNN的前向传播和反向梯度求导,但知识仍停留在纸面.本篇章将基于深度学习框架tensorflow验证我们所 ...

  8. CNN卷积层基础:特征提取+卷积核+反向传播

    本篇介绍卷积层的线性部分 一.与全连接层相比卷积层有什么优势? 卷积层可以节省参数,因为卷积运算利用了图像的局部相关性——分析出一小片区域的特点,加上Pooling层(汇集.汇聚),从附近的卷积结果中 ...

  9. 神经网络训练中的Tricks之高效BP(反向传播算法)

    神经网络训练中的Tricks之高效BP(反向传播算法) 神经网络训练中的Tricks之高效BP(反向传播算法) zouxy09@qq.com http://blog.csdn.net/zouxy09 ...

随机推荐

  1. stl_list复习

    #include <iostream>#include <list>#include <algorithm>using namespace std; //底层结构是 ...

  2. Dism++ 更新管理提示“无法连接服务器”

    Dism++ 更新管理提示"无法连接服务器" 下载wsusscn3.cab,放入Dism++安装目录下Config文件夹中.

  3. Python爬虫:urllib库的基本使用

    请求网址获取网页代码 import urllib.request url = "http://www.baidu.com" response = urllib.request.ur ...

  4. 吴裕雄--天生自然TensorFlow2教程:反向传播算法

  5. HDU 4699 Editor(模拟 对顶栈)

    题目大意: 给定一个整数序列 维护5种操作 次数<1e6 I x: 光标位置插入x 然后光标位于x之后 D: 删除光标前一个数 L: 光标左移 R: 光标右移 Q k: 询问位置k之前的最大前缀 ...

  6. 高级T-SQL进阶系列 (一)【上篇】:使用 CROSS JOIN 介绍高级T-SQL

    [译注:此文为翻译,由于本人水平所限,疏漏在所难免,欢迎探讨指正] 原文连接:传送门 这是一个新进阶系列的第一篇文章,我们将浏览Transact-SQL(T-SQL)的更多高级特性.这个进阶系列将会包 ...

  7. 自身经历 .NET转Java 的一些分享

    原因 楼主在二线城市从事.NET开发8年,当薪资达到15k想往20k跳的时候,发现一个残酷的现实.在招聘信息上给出这个薪资的一共10家,其中:2~3家给出的是假的薪资范围(吸引面试者),2家是总人数不 ...

  8. GlusterFS分布式文件系统概述

    一.GlusterFS概述 GlusterFS是一个开源的分布式文件系统,同时也是Scale-Out存储解决方案Gluster的核心,在存储数据方面有强大的横向扩展能力,通过扩展不同的节点可以支持PB ...

  9. 十二 INPUT逻辑视图的配置,回显错误信息

    Action接口中提供了五个逻辑视图的名称 SUCCESS ERROR LOGIN INPUT:input在某些拦截器会使用 NONE 配置逻辑视图:struts_demo2.xml,配置后出现错误信 ...

  10. C 语言入门第十二章---C语言文件操作

    C语言具有操作文件的能力,比如打开文件.读取和追加数据.插入和删除数据.关闭文件.删除文件等. 在操作系统中,为了同意对各种硬件的操作,简化接口,不同的硬件设备也都被看成一个文件.对这些文件的操作,等 ...