精华内容
下载资源
问答
  • 卷积神经网络 python代码 代码代码 代码。。。。。
  • 里面包含基于TensorFlow的mnist数据集卷积神经网络代码,从数据提取,到精度测试都有,适合初学者观看。
  • CNN实现MNIST分类,在测试集上实现准确率0.99,TensorFlow实现,容易上手
  • 多层前向卷积神经网络Python代码。Theano的CNN代码
  • 卷积神经网络python实现。 卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积或相关计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习(deep learning)的代表算法之...
  • 卷积神经网络python实现

    万次阅读 多人点赞 2018-12-18 12:02:10
    1、网络结构 2、各层详解 1)卷积层(conv) A、概念解释 B、实现过程 C、多维输入数据计算 D、卷积层代码实现 2)池化层(pooling) A、实现过程 B、池化层代码实现 3)激活层 A、sigmoid函数 B、阶跃...

    目录

    1、网络结构

    2、各层详解

    1)卷积层(conv)

    A、概念解释

    B、实现过程

    C、多维输入数据计算

    D、卷积层代码实现

    2)池化层(pooling)

    A、实现过程

    B、池化层代码实现

    3)激活层

    A、sigmoid函数

    B、阶跃函数

    C、relu函数

    4)affine层

    5)dropout层

    6)softmax-with-loss层

    A、损失函数介绍

    B、softmax-with-loss层结构介绍

    C、代码实现


    1、网络结构

    11层卷积网络结构如下:

    conv - relu - conv - relu - conv - relu - pool -

    conv - relu - conv - relu - conv - relu - pool -

    conv - relu - conv - relu - conv - relu - pool -

    affine - relu - dropout - affine - dropout – softmaxwithloss

    conv:卷积层

    relu:激活层

    pool:池化层

    affine:全连接层,实现输入数据和节点参数矩阵的相乘

    dropout:按照一定概率抛弃某些节点,防止过拟合

    softmax-with-loss:将输入数据正规化后输出,并输出交叉熵误差

    2、各层详解

    1)卷积层(conv)

    A、概念解释

    填充(pad):卷积运算前,想输入数据周围填入固定的数据(比如0),用P表示。

    步幅(stride):应用滤波器的窗口间隔大小。

    B、实现过程

    如图1

                                               图1

    假设待处理矩阵大小为 ( W , H ) ,卷积滤波器大小为 ( FW , FH ) ,填充为P,步幅为S,则输出矩阵大小为:

                                          

    C、多维输入数据计算

    实际应用中,输入多为三通道彩色图像,此时滤波器相应设为三通道,即:

     

    通过im2col函数将四维矩阵展开为二维矩阵进行运算,函数形式如下:

                             col = im2col(x, FH, FW, self.stride, self.pad)

    x为输入矩阵,输出矩阵的大小为

                                 ( OH * OW * N ,  FH * FW * C )

    D、卷积层代码实现

    2)池化层(pooling)

    A、实现过程

                                                                           图2

    池化层滤波器大小一般为(2 , 2),随着滤波器的移动,依次选择窗口内的最大值作为输出。

    B、池化层代码实现

    处理多维数组时,依然用im2col函数改变维度以方便计算。

    3)激活层

    激活函数一般用非线性函数,本节介绍常用的几种激活函数。

    A、sigmoid函数

    函数形式如下:

    Python代码实现:

    B、阶跃函数

    Python代码实现:

    C、relu函数

    函数形式如下:

    Python代码实现:

    本文所构建网络选用relu函数作为激活函数。

    4)affine层

    前文提到,affine层主要作用时实现矩阵的乘法运算。

                                                                  图3

    图3为affine层的计算图,X , W , B 分别为输入数据,节点参数,偏置。

    Affine层代码实现:

    5)dropout层

    Dropout是一种在学习的过程中随机删除神经元的方法。训练时,随机选出隐藏层的神经元,然后将其删除。被删除的神经元不再进行信号的传递,如图4所示。训练时,每传递一次数据,就会随机选择要删除的神经元。然后,测试时,虽然会传递所有的神经元信号,但是对于各个神经元的输出,要乘上训练时的删除比例后再输出。

                                                                     图4

    Dropout层python代码实现:

    6)softmax-with-loss层

    A、损失函数介绍

    常用的损失函数包括均方误差和交叉熵误差。均方误差的计算公式如下:

    这里,yk 是表示神经网络的输出,tk 表示监督数据,k表示数据的维数。E值越小,代表输出与监督数据越吻合。

    cross-entropy-error层的输出为交叉熵误差,计算公式如下:

    这里,log表示以e为底数的自然对数(log e )。yk 是神经网络的输出,tk 是正确解标签。并且,tk 中只有正确解标签的索引为1,其他均为0 。因此,上式实际上只计算对应正确解标签的输出的自然对数。比如,假设正确解标签的索引是“2”,与之对应的神经网络的输出是0.6,则交叉熵误差是−log0.6 = 0.51;若“2”对应的输出是0.1,则交叉熵误差为−log0.1 = 2.30。也就是说,交叉熵误差的值是由正确解标签所对应的输出结果决定的。

    B、softmax-with-loss层结构介绍

    该层的计算图如图5所示。softmax-with-loss层包括正向传播和反向传播,本节先介绍正向传播。

                                                                                  图5

    softmax-with-loss层由softmax、cross-entropy-error两个函数构成。Softmax层的作用为将输入正规化输出,计算公式如下:

    如图6,Softmax层将输入值正规化(将输出值的和调整为1)之后再输出。另外,因为手写数字识别要进行10类分类,所以向Softmax层的输入也有10个。

                                           图6

    Softmax层代码实现:

    C、代码实现

    展开全文
  • 卷积神经网络图像识别python代码
  • 请问哪里有3D卷积神经网络开源python代码吗?小白求学习?
  • CNN卷积神经网络PYTHON

    2018-10-26 19:02:39
    CNN卷积神经网络,包含数据,代码有标注,可以用来参考学习
  • 卷积神经网络图像识别python代码pdf;卷积神经网络图像识别python代码pdf
  • 基于Python卷积神经网络的图像分类,很适合初学者的学习使用
  • 越来越卷,教你使用Python实现卷积神经网络(CNN)

    千次阅读 多人点赞 2021-05-31 07:51:16
    Yann LeCun 和Yoshua Bengio在1995年引入了卷积神经网络,也称为卷积网络或CNN。CNN是一种特殊的多层神经网络,用于处理具有明显网格状拓扑的数据。其网络的基础基于称为卷积的数学运算。

    @Author:Runsen

    卷积神经网络

    Yann LeCun 和Yoshua Bengio在1995年引入了卷积神经网络,也称为卷积网络或CNN。CNN是一种特殊的多层神经网络,用于处理具有明显网格状拓扑的数据。其网络的基础基于称为卷积的数学运算。

    卷积神经网络(CNN)的类型
    以下是一些不同类型的CNN:

    • 1D CNN:1D CNN 的输入和输出数据是二维的。一维CNN大多用于时间序列。

    • 2D CNNN:2D CNN的输入和输出数据是三维的。我们通常将其用于图像数据问题。

    • 3D CNNN:3D CNN的输入和输出数据是四维的。一般在3D图像上使用3D CNN,例如MRI(磁共振成像),CT扫描(甲CT扫描或计算机断层扫描(以前称为计算机轴向断层或CAT扫描)是一种医学成像 技术中使用的放射学获得用于非侵入性详述的身体

    展开全文
  • 对于卷积神经网络(CNN)而言,相信很多读者并不陌生,该网络近年来在大多数领域都表现优异,尤其是在计算机视觉领域中。但是很多工作人员可能直接调用相关的深度学习工具箱搭建卷积神经网络模型,并不清楚其中具体...
  • 深度学习-卷积神经网络(python3代码实现)

    万次阅读 多人点赞 2018-03-26 16:50:58
    卷积神经网络(上) 作者:Bossof537 写这个也不容易,小哥哥小姐姐转载请注明出处吧,感谢! 1、简介 卷积神经网络与常规的神经网络十分相似,它们都由可以对权重和偏置进行学习的神经元构成。每个神经元接收...

    卷积神经网络(上)

    作者:Bossof537

    写这个也不容易,小哥哥小姐姐转载请注明出处吧,感谢!

    1、简介

    卷积神经网络与常规的神经网络十分相似,它们都由可以对权重和偏置进行学习的神经元构成。每个神经元接收一些输入,然后执行点积操作,再紧接一个可选的非线性函数。整个网络仍然表示为单可微分的评估函数,整个网络从一端输入原始图像像素,另一端输出类别的概率。其最后一层(全连接层)同样有损失函数,并且我们学习常规神经网络的方法和技巧在这里仍然奏效。

    那么卷积神经网络的不同之处是什么?首先卷积网络很明确地假设所有输入都为图像,这就允许我们在结构中对明确的属性进行编码。这就使得前向函数的实现更加高效,并且极大的减少了网络中参数的数量。

    2、结构概述

    回顾:正如我们所熟知的,常规神经网络接收一个输入(一维向量),并通过一系列的隐藏层对其进行转换。每个隐藏层由一组神经元构成,其中每个神经元都与前一层的全部神经元相连接,并且同一层的各个神经元都是独立工作的,它们的连接并不共享。位于最后一层的全连接层称为输出层,在分类模型中,它将表示类别的概率。

    常规的神经网络并不能很好的应用于完整的图像:在CIFAR-10(一个开源在线的图像数据集)中,图像的尺寸仅为32×32×3(宽度32,高度32,3个通道),因此一个常规神经网络的第一层隐藏层中的单个全连接的神经元将会有32×32×3=3072个权重(全连接网络中,输入向量有多少维,每个神经元就需要有多少个权重,这样才能做点积)。这个数量看起来还好,但是显然这种全连接的结构并不能扩展到更大尺寸的图像。例如:一个200×200×3的大尺寸图像,将会使神经元有200×200×3=120000个权重。并且我们几乎肯定会有好几个这样的神经元,因此参数的数量将会急剧增加。显然,这种全连接结构十分浪费,并且大量的参数将会很快导致过拟合。

    三维神经元:卷积神经网络充分利用了输入是由图像组成的这一事实,并以更加合理的方式对结构进行了约束。特别是,与常规网络不同,卷积网络各层的神经元具有三个维度,即宽度高度深度。例如:CIFAR-10中作为输入的图像是输入激活量,并且该激活量的大小为32×32×3(分别为宽度,高度,深度)。正如我们即将看到的,每一层的神经元仅与前一层的局部相连,而不是采用全连接的方式。此外,CIFAR-10的最终输出层的尺寸为1×1×10,因为在卷积网络结构的最后我们将会把完整的图像缩减为关于类别概率的一维向量,且该一维向量沿着深度维度排列。如图1所示:


    这里写图片描述

    左图:常规三层神经网络。右图:由具有三个维度的神经元构成的卷积网络(宽度,高度,深度)。卷积网络的每一层将三维输入激活量转换为经过神经元激活的三维输出激活量。在这个图例中,红色的输入层代表图像,因此它的宽度和高度就是图像的宽度和高度,而它的深度为3(红,绿,蓝三个通道)


    3、卷积网络的各层

    正如上文所描述的,一个简单的卷积网络由一系列的层所构成,并且卷积网络的每一层通过一个可微函数将一个激活量转换成另一个激活量。我们用三类主要的层来构造卷积网络:卷积层池化层以及全连接层。我们将通过堆叠这些层来形成一个完整的卷积网络结构。

    示例:接下来我们将讨论更多细节问题,一个用于对CIFAT-10进行分类的简单的卷积网络的结构是(输入层-卷积层-ReLu函数层-池化层-全连接层),详细来说:

    • 输入层(32×32×3)将保存图像的原始像素值,在本例中一个图像具有宽度32,高度32,以及三个颜色通道R,G,B。
    • 卷积层负责计算与输入层局部连接的神经元的输出,即分别计算每个神经元的权重与它们所连接的输入激活量的局部之间的点积。如果我们打算使用12个滤波器,那么将会得到大小为32×32×12的激活量。
    • ReLu层将会对每一个元素应用一个激活函数,例如以0为阈值的 max(0,x) m a x ( 0 , x ) ,这将使得激活量的尺寸保持不变,仍为32×32×12。
    • 池化层将会在二维面上(宽度,高度)执行降采样的操作,得到如16×16×12的激活量。
    • 全连接层将会计算类别的概率,得到1×1×10的激活量,其中10个数值分别对应每个类别的概率。全连接层,顾名思义该层和普通的神经网络一样,每一个神经元都将与之前激活量的全部数值相连接。

    通过这种方式,卷积网络将原始图像逐层地从原始像素值转换为最终的类别概率。注意,有些层包含一些参数,而有些层则不包含参数。尤其是卷积层和全连接层,其不仅有激活函数,也有参数(神经元的权重和偏置),二者共同对输入激活量执行变换操作。另一方面,ReLu层和池化层将执行一个具有固定功能的函数。卷积层和全连接层中的参数将使用梯度下降进行训练,以使卷积网络计算的类别概率与训练集中每个图像的标签一致。

    综上所述:

    • 一个卷积网络结构最简单的情况就是顺序排列各个层,以达到将图像激活量转换为输出量激活量的目的。
    • 共有几种不同类型的层(例如最流行的:卷积层,全连接层,ReLu层,池化层)。
    • 每一层接收一个三维激活量作为输入,并且通过可微函数将其转换为另一个三维激活量作为输出。
    • 每一层都可能包含或者不包含参数(例如:卷积层和全连接层有参数,ReLu层和池化层没有参数)。
    • 每一层都可能包含或者不包含超参数(例如:卷积层、全连接层、池化层有超参数,ReLu层没有超参数)。

    这里写图片描述


    现在,让我们来对每一层,及其超参数的细节以及其连接方式进行具体的描述。

    4、卷积层

    卷积层是一个卷积神经网络的核心组成部分,它负责完成大部分计算繁重的工作。

    概述以及直观认识:我们先来讨论卷积层是如何进行计算的,并且是从更加直观的角度来进行讨论,而不是将其类比为脑神经。首先,卷积层的参数由一组可以进行学习的滤波器组成。每一个滤波器都是一个小的二维面区域(沿宽度和高度),但却延伸到输入激活量的全部深度。例如:卷积网络第一层上的一个典型滤波器的尺寸可能为5×5×3(即,5个像素的宽度和高度,而3是由于图像的深度为3)。在正向传播期间,我们沿着输入方柱体的宽度和高度方向滑动(更确切地说是卷积)每个滤波器,并计算滤波器的端口与滤波器处于每个位置上的输入的点积。当我们将滤波器沿着输入激活量的高度和宽度滑过之后,将会得到一个二维的激活图,该图给出了滤波器在滑动过的每个位置上得到的结果。直观地说,网络将对滤波器进行学习,当他们看到某种类型的视觉特征时激活,例如第一层上某种方向的条棱或某种颜色的斑点,或者最终在网络的更高层上形成的整个蜂窝或轮状图案。


    • 举例来说:假设如下图所示,有一个5×5×1的输入激活量,而滤波器的尺寸为3×3×1,该滤波器共有3×3×1=9个端口,其值分别为(-1,0,1,-1,0,1,-1,0,1)。滤波器从输入激活量最左上角的3×3的二维区域位置开始,一次移动一个小格,最终移动到最右下角的位置,滤波器每移动到一个位置,就计算该区域内的输入值与滤波器端口的点积(在本图中,计算1×-1 + 0×0 + 2×1 + 5×-1 + 4×0 + 2×1 + 3×-1 + 4×0 + 5×1 = 0),并将得到的结果放在二维的激活图的相应位置上(在本图中,将点积得到的结果0放在激活图的第一行第二列上)。实际上,这里还需要加上一个偏置。再将最终结果放到二维激活图中。
      这里写图片描述

    接下来,我们将在每个卷积层上使用一整组的滤波器(即12个滤波器),其中每一个滤波器都将产生一个二维激活图。我们将这些激活图沿着深度堆叠起来,得到一个输出激活量。

    从脑神经角度理解:如果您喜欢把它与脑神经进行类比的话,那么三维的输出激活量的每个值也可以解释为神经元的输出值,该神经元只关注于输入的一小部分区域,并且与左右相邻的神经元共享参数(因为这些输出值都是来自同一个滤波器的结果)。接下来我们将讨论这些神经元的连接细节,它们在空间中的排列方式,以及它们的参数共享方案。

    局部连接:当处理例如图像这种高维输入时,正如我们上面看到的,将所有神经元进行全连接是不现实的。因此,我们将每个神经元只与输入激活量的部分相连接。这种连接的二维面上的范围是一个超参数,称之为神经元的接收域(相当于是过滤器的大小)。沿着深度方向的连接范围总是和输入激活量的深度相等。必须再次强调我们在处理二维面(宽度和高度)和深度维度上的不对称性。在二维面上是局部连接(沿着宽度和高度的),而沿着输入激活量的整个深度进行的几乎是全连接。

    • 例1:例如,假设输入激活量的尺寸是32×32×3。如果接收域(或者说滤波器的尺寸)是5×5,那么卷积层中的每个神经元将会有对应于输入激活量中5×5×3区域的权重,即每个神经元总共有5×5×3=75个权重(加上1个偏置参数)。值得注意的是,沿着深度轴的连接范围必须为3,因为这是输入激活量的深度。
    • 例2:假设一个输入激活量的尺寸为16×16×20,接收域的尺寸假设为3×3,卷积层中的每一个神经元与输入方柱体之间将会有3×3×20=180个连接。再次强调,连接在二维面上是局部的(即3×3),但是在输入深度上是全连接的(20)。

    这里写图片描述
    左图:浅红色所表示的是输入激活量(即32×32×3),而深红色表示第一层卷积层上的神经元所连接的局部激活量的示例。卷积层上的每个神经元只与输入激活量的局部相连接,但是在深度上是全连接的。注意,这里沿着深度方向有多个神经元(在本例中是5个),它们都注视着输入激活量的同一区域(参见后文提到的深度列)。右图:仍然计算神经元的权重和输入的点积,再紧接一个非线性函数,只是它们的连接现在被限制在局部区域内。


    空间排列:我们已经阐明了卷积层中的每个神经元与输入激活量之间的连接,但是我们还没有讨论神经元的个数以及它们如何进行排列的。三个超参数控制着输出激活量的尺寸:分别是深度步长以及零填充,接下来我们将对这些进行讨论:

    1. 首先,输出激活量的深度就是一个超参数:它对应于我们使用的滤波器的个数,每个滤波器都进行学习以从输入中寻找一些不同的东西。例如,第一个卷积层将原始图像作为输入,那么沿着深度维度的不同神经元可以在各种定向条棱或颜色斑点的存在时激活。我们称注视着输入的同一区域的一组神经元为深度列(有些人也喜欢叫纤维条)。
    2. 其次,我们必须指定我们滑动滤波器的步长。当步长为1时,我们将滤波器每次移动一个像素。当步长为2(或者3或者更多,虽然实际中并不常见)时,我们将滤波器一次跳跃2个像素来进行滑动。这样将产生二维面(宽度和高度)较小的输出激活量。
    3. 正如我们即将看到的,有时在边界周围用0填充输入激活量会很方便。零填充的大小是一个超参数。零填充的优点在于,它可以让我们控制输出激活量的二维面的大小(正如我们马上就要看到的,最常见的是,我们将使用它来精确地保留输入激活量的二维面的大小,以使输入和输出的宽度和高度是相同的)。

    我们可以根据输入激活量的大小 (W) ( W ) ,卷积层神经元的接收域的大小 (F) ( F ) ,它们所应用的步长 (S) ( S ) ,以及边界上使用的零填充的大小 (P) ( P ) ,来计算输出激活量的大小。您可以自己证明一下,计算有多少个神经元合适的公式为 (WF+2P)/S+1 ( W − F + 2 P ) / S + 1 。例如有一个7×7的输入,步长为1的3×3的滤波器,没有零填充即 P=0 P = 0 ,于是我们会得到5×5的输出。如果是2步长我们将会得到3×3的输出。让我们再来看一个图形化的例子:


    这里写图片描述
    如图所示:在这个例子中,只有一个空间维度(X轴),接收域F=3的神经元,输入大小为W=5,而零填充P=1。左边:神经元以1的步长滑过输入,给出的输出大小为(5 - 3 + 2)/ 1 + 1 = 5。右边:神经元的步长为S=2,给出的输出大小为(5 - 3 + 2)/ 2 + 1 = 3。而本例中的神经元的权重为1,0,-1(最右边的三个绿色方格所示),而偏置为0。这些权重在所有的黄色的神经元之间参数共享(参见下面的参数共享)。


    零填充的使用:在上面的例子中,左图中的输入大小是5,输出大小也是5。这是因为我们的接收域是3并且我们使用的零填充的大小为1。如果没有使用零填充,那么输出激活量的大小将是3。通常,在步长S = 1时,将零填充设置为P = (F - 1)/2 可以确保输入激活量与输出激活量具有相同大小的二维面(宽度和高度)。以这种方式使用零填充是非常常见的,我们将在讨论更多卷积网络的结构时对其充分原因进行探讨。

    步长的限制:需要再次注意,空间排列的超参数是相互约束的。例如,当输入大小 W=10 W = 10 ,不使用零填充即 P=0 P = 0 ,滤波器的大小为 F=3 F = 3 ,那么步长就不可能为2,因为 (WF+2P)/S+1=(103+0)/2+1=4.5 ( W − F + 2 P ) / S + 1 = ( 10 − 3 + 0 ) / 2 + 1 = 4.5 ,即结果为非整数,这显然不行。因此,这样设置超参数是无效的,神经网络库可能会抛出一个异常,或是对其余部分进行零填充,或是对输入进行剪裁,等等。正如我们将在神经网络结构部分看到的,适当调整神经网络的大小以使所有维度得到合理的解决可能是一件非常头疼的事情,因此使用零填充和某些设计准则将显著缓解这种压力。

    真实世界的例子: Krizhevsky等人赢得2012年ImageNet挑战赛的架构能够接受大小为227×227×3的图片输入。在第一层卷积层,使用的神经元的接收域大小为 F=11 F = 11 ,步长 S=4 S = 4 ,零填充 P=0 P = 0 。因为 (22711)/4+1=55 ( 227 − 11 ) / 4 + 1 = 55 ,并且由于卷积层深度 K=96 K = 96 ,因此卷积层的输出大小为55×55×96。55×55×96个神经元中的每一个都与输入激活量的大小为11×11×3的区域连接。此外,每一个深度列(纤维条)上的神经元都与同一个11×11×3的区域相连接,但每个神经元必然都有着不同的权重。

    参数共享:参数共享方案在卷积层中用于控制参数的数量。我们使用上述真实世界的例子,在第一层卷积层中共有55×55×96=290400个神经元,并且每一个神经元都有11×11×3=363个权重和一个偏置。将这些加在一起,那么仅在卷积网络的第一层上就有290400×364=105705600个参数。显然,这个数量非常大。事实证明,我们可以通过一个合理的假设来大大减少参数的数量:即一个特征如果在一些位置上( x,y x , y )可用于计算,那么在另一个位置上( x2,y2 x 2 , y 2 )也可用于计算。换句话说,将一个2维面切片表示为深度切片(例如:大小为55×55×96的激活量具有96个深度切片,每个深度切片大小为55×55)。我们将限制每个深度切片中的神经元具有相同的权重和偏置。有了这种参数共享方案,我们例子中的第一层卷积层中将只有96组不同的权重(每一组对应一个深度切片),总共有96×11×11×3=34848个权重,或者说是34944个参数(加上96个偏置)。或者说,每个深度切片中的55×55个神经元现在将使用相同的参数。在实际的反向传播过程中,激活量中的每个神经元都会计算其权重的梯度,但是这种梯度将叠加在每个深度切片上,并且仅更新每个切片的一组权重。


    这里写图片描述
    此图为Krizhebsky等人学习到的示例滤波器器,此处显示的96个滤波器中每个滤波器的大小为11×11×3,并且每个滤波器由一个深度切片中的55×55个神经元共享。注意,参数共享假设是相对比较合理的:即如果在图片中的某个位置检测到水平条棱很重要,那么由于图片的平移不变性,它也将在图片的其他位置直观地起到作用。因此不需要重新进行学习来检测卷积层输出激活量中每个55×55不同位置上的水平条棱。


    请注意,有时参数共享假设可能没有意义。当输入到卷积网络中的图像具有特定的中心结构时,尤其如此,例如,我们期望在图像的一侧学习到完全不同的特征而不是另一侧。一个实际的例子是,当输入的是在图像中居中的人脸图像时,你可能(而且应该)希望在不同的空间位置学习到眼部或头发的特定特征。在这种情况下,通常会放宽参数共享方案,而只将该层称之为局部连接层。

    Numpy实际举例:为了使以上的讨论更加具体,我们将同样的思想用具体例子的代码来进行表达。假设输入激活量是一个numpy arrayX,于是:

    • 一个在(x,y)位置上的深度列(或者说是纤维条)将是激活量X[x,y,:]
    • 一个深度切片,或者等效于一个在深度d位置上的激活映射图将是激活量X[:,:,d]

    假设输入激活量X的大小为X.shape:(11,11,4)。此外,假设我们使用零填充(即 P=0 P = 0 ),滤波器大小为 F=5 F = 5 ,并且步长为 S=2 S = 2 。因此输出激活量的大小将会是 (115)/2+1=4 ( 11 − 5 ) / 2 + 1 = 4 ,即给定一个宽度和高度都为4的激活量。输出激活量中的激活映射图(称之为V)如下所示(在该例中只对一部分元素进行计算)。

    • V[0,0,0] = np.sum(X[:5,:5,:] * W0) + b0
    • V[1,0,0] = np.sum(X[2:7,:5,:] * W0) + b0
    • V[2,0,0] = np.sum(X[4:9,:5,:] * W0) + b0
    • V[3,0,0] = np.sum(X[6:11,:5,:] * W0) + b0

    还记得在numpy中*操作表示array之间的每个元素相乘。同时注意到向量W0是神经元的权重向量,b0是神经元的偏置。这里假设W0的大小为W0.shape:(5,5,4),因为滤波器的大小为5×5,而输入激活量的深度为4。注意,在每个点上,我们都是像之前普通神经网络中那样进行点积,此外,正如我们看到的,我们使用相同的权重和偏置(由于参数共享),并且沿着宽度维度以2为单位递增(即步长)。要构建输出激活量中的第二个激活映射图,我们可以:

    • V[0,0,1] = np.sum(X[:5,:5,:] * W1) + b1
    • V[1,0,1] = np.sum(X[2:7,:5,:] * W1) + b1
    • V[2,0,1] = np.sum(X[4:9,:5,:] * W1) + b1
    • V[3,0,1] = np.sum(X[6:11,:5,:] * W1) + b1
    • V[0,1,1] = np.sum(X[:5,2:7,:] * W1) + b1(沿y滑动位置的例子)
    • V[2,3,1] = np.sum(X[4:9,6:11,:] * W1) + b1(既沿x又沿y滑动的例子)

    正如我们看到的,因为我们正在计算第二个激活映射图,故我们索引到V的第二层深度,并且我们使用了一组不同的参数W1。在上述例子中,我们为了简洁起见,只计算输出激活量 arrayV的一部分。此外,回想一下,这些激活映射图中的每个元素经常都会通过一个诸如ReLu函数之类的激活函数,但是这里并没有提及。

    总结:对卷积层进行一下总结。

    • 接收一个大小为 W1×H1×D1 W 1 × H 1 × D 1
    • 需要四个超参数

      1. 滤波器的数量 K K
      2. 滤波器的大小F
      3. 步长 S S
      4. 零填充数量P
    • 产生一个大小为 W2×H2×D2 W 2 × H 2 × D 2 的激活量,并且

      1. W2=(W1F+2P)/S+1 W 2 = ( W 1 − F + 2 P ) / S + 1
      2. H2=(H1F+2P)/S+1 H 2 = ( H 1 − F + 2 P ) / S + 1
      3. D2=K D 2 = K
    • 通过参数共享,它将为每个滤波器引入 FFD1 F ⋅ F ⋅ D 1 个权重,总共有 (FFD1)K ( F ⋅ F ⋅ D 1 ) ⋅ K 个权重和 K K 个偏置。

    • 在输出激活量中,第d个深度切片(大小为 W2×H2 W 2 × H 2 )是将第 d d 个滤波器在输入激活量上以步长S进行有效卷积,然后与偏置相加减得到的结果。

    一种比较常见的超参数的设置为 F=3,S=1,P=1 F = 3 , S = 1 , P = 1

    矩阵乘法的实现:注意,卷积运算本质上是将滤波器和输入激活量的局部区域进行点积。而卷积层的常见实现模式是利用这一事实并将卷积层的正向传播制定为如下的一个大矩阵乘法:

    1. 输入图像的局部区域在一个通常被称为im2col的操作中被拉伸成列。例如,如果输入激活量的大小为227×227×3并且由大小为11×11×3的滤波器以步长为4进行卷积,那么我们将在输入激活量中拿出11×11×3个像素的区块,并将每个区块拉伸为大小为11×11×3=363的列向量。在输入激活量上以4为步长沿着宽度或者高度滑动都有(227-11)/4+1=55个位置,故在输入激活量上迭代执行拉伸过程,将得到一个大小为363×3025的im2col输出矩阵X_col,其中每列都是一个被拉伸的接收域,因此总共有55×55=3025列。
    2. 卷积层的权重类似的拉伸成行。例如,如果有96个大小为11×11×3的滤波器,将会得到一个大小为96×363的矩阵W_row
    3. 卷积的结果现在相当于执行一个大矩阵乘法np.dot(W_row,X_col),它算出每个滤波器和其在每个位置上的接收域执行点积的结果值,在我们的例子中,该操作的输出矩阵大小为96×3025。
    4. 结果必须重新调整为适当的大小,即55×55×96。

    这种方法的缺点是浪费内存,因为输入激活量中的一些值在X_col中被复制了多次。然而,其好处是有很多非常有效的矩阵乘法的实现方式可以利用。此外,我们可以重复使用和im2col相同的思想来执行池化操作,我们将在下面的内容中来讨论该操作。

    反向传播:卷积操作(对于数据和权重)的反向传播也是卷积(但是,却是具有空间反转的滤波器)。这很容易用一个玩具例子在1维情况下推导出来(现在先不进行扩展)。

    1×1卷积:一些论文首先使用1×1卷积作为网络的研究工作。有些人一开始看到1×1卷积会感到有些困惑,尤其是当他们具有信号处理研究背景时。通常情况下,信号是2维的,所以1×1卷积是没有意义的(它只是逐点缩放)。然而,在卷积网络中情况并非如此,因为我们一定要记住,我们是在3维激活量上进行操作,并且滤波器始终是贯穿输入激活量的整个深度。例如,如果输入激活量是32×32×3,于是执行1×1卷积将会高效地执行3维点积(因为输入激活量的深度是3)

    扩张卷积:一项最近的研究发展打算向卷积层中再引入一个超参数(参见Fisher Yu 和 Vladlen Koltun的论文),称之为扩张度。到目前为止,我们只讨论了相连续的卷积滤波器。然而,我们也可以设置一个在每个单元格之间有空格的滤波器,称之为扩张。举例来说,假设在1维空间上一个大小为3的滤波器W对输入X进行计算可得:w[0]*x[0] + w[1]*x[1] + w[2]*x[2],即扩张度为0。若扩张度为1,我们将会计算:w[0]*x[0] + w[1]*x[2] + w[2]*x[4]。换句话说,滤波器的应用具有大小为1的间隔。在某些设置中,将其与0扩张滤波器结合使用,将会非常有用。因为它允许你更加积极地使用更少的图层将输入的空间信息进行合并。例如:如果您将两个3x3 的卷积层叠在一起,那么您可以说服自己,第二层上的神经元是输入激活量的5x5的补丁的函数(我们可以说这些神经元的有效接收域是5×5)。 如果我们使用扩张卷积,那么这个有效的接收域会增长得更快。

    5、池化层

    我不明白,也不需要明白,做一个傻子好不好………………..
    我不想要,也不重要,做一个傻子多么好…………

    展开全文
  • 人工神经网络 基于CNN卷积神经网络 基于Python 实现图片验证码的识别
  • 基于卷积神经网络的手写数字识别python代码实现 卷积神经网络(Convolutional Neural Network,CNN)中,卷积层的神经元只与前一层的部分神经元节点相连,即它的神经元间的连接是非全连接的,且同一层中某些神经元...
  • 首先介绍下卷积神经网络 输入层我就不讲了,我主要根据代码讲下卷积层,池化层,全连接层。 (一) 卷积层 ''' -1代表着矩阵行不确定我这里用n表示,[-1,28,28,1]的意思是n行28列, 它的子元素是一个28行1列...

    首先介绍下卷积神经网络
    在这里插入图片描述
    输入层我就不讲了,我主要根据代码讲下卷积层,池化层,全连接层。
    (一)
    卷积层

    '''
    -1代表着矩阵行不确定我这里用n表示,[-1,28,28,1]的意思是n行28列,
    它的子元素是一个28行1列的矩阵,例如
    [[[[1]], [[1]], [[1]], [[1]]],
     [[[1]], [[1]], [[1]], [[1]]]]
    可以表示为【2,4,1,1】它的子元素[[1]]为1行1列。在这里这个1也可以理解为通道数为1
    '''
    x_image = tf.reshape(x, [-1, 28, 28, 1])
    '''
    w_conv1代表着filter【5,5】为卷积核大小,1为通道数,32为卷积核的个数,卷积核个
    数的选取需要凭经验,也许有大神知道一定的规律,这里我讲一下卷积核的通道数为什么需
    要和输入的通道数一样,其实原理很简单,我们需要x_image和w_conv1相乘,也就需要它们两
    个的子元素相乘,上边已经说过x_image的子元素为【28,1】,要想两者相乘,则w_conv1
    子元素必须为【1,n]
    
    '''
    w_conv1 = weight_variable([5, 5, 1, 32])
    

    卷积的计算包括两部分,输入和filter
    卷积的计算(注意,下面蓝色矩阵周围有一圈灰色的框,那些就是上面所说到的填充值)
    在这里插入图片描述
    蓝色的矩阵(输入图像)对粉色的矩阵(filter)进行矩阵内积计算并将三个内积运算的结果与偏置值b相加(比如上面图的计算:2+(-2+1-2)+(1-2-2) + 1= 2 - 3 - 3 + 1 = -3),计算后的值就是绿框矩阵的一个元素。下面的动态图形象地展示了卷积层的计算过程:

    在这里插入图片描述
    代码中我们需要定义一个方法,来实现卷积

    def conv2d(x, w):
        b = tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME')
        return b
    

    这里有 tf.nn.conv2d函数的介绍,https://www.cnblogs.com/qggg/p/6832342.html
    我主要介绍下padding(卷积层的) = 'SAME’和padding(卷积层的) = 'VALUE’的区别
    之前在讨论卷积神经网络的时候,我们是使用filter来做元素乘法运算来完成卷积运算的。目的是为了完成探测垂直边缘这种特征。但这样做会带来两个问题。

    卷积运算后,输出图片尺寸缩小;
    越是边缘的像素点,对于输出的影响越小,因为卷积运算在移动的时候到边缘就结束了。中间的像素点有可能会参与多次计算,但是边缘像素点可能只参与一次。所以我们的结果可能会丢失边缘信息。
      那么为了解决这个问题,我们引入padding, 什么是padding呢,就是我们认为的扩充图片, 在图片外围补充一些像素点,把这些像素点初始化为0.

    ① SAME

    在这里插入图片描述
    输出大小等于输入大小除以步长向上取整,s是步长大小;
    我们这里的输入大小为2828的图像,filter 大小为55, 步长strides 为1所以输出大小也为2828,下面给出图解
    假设我们输入矩阵为
    在这里插入图片描述
    我们先把矩阵扩充为
    在这里插入图片描述
    然后再与filter进行卷积运算,这样做是为了保留边界信息,否则的话我们的边界只进行了一次运算,而内部进行了多次
    ② VALUE
    在这里插入图片描述
    输出大小等于输入大小减去滤波器大小加上1,最后再除以步长(f为滤波器的大小,s是步长大小)。假设我们输入大小为28
    28,步长为1,filter为55,那么输出大小为2424,图片有所缩小。

    **(二)**激励层
    把卷积层输出结果做非线性映射。
    在这里插入图片描述
    主要是增强输入输出之间的拟合性,
    CNN采用的激励函数一般为ReLU(The Rectified Linear Unit/修正线性单元),它的特点是收敛快,求梯度简单,但较脆弱。代码如下

    h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
    

    **(三)**池化层

    池化层夹在连续的卷积层中间, 用于压缩数据和参数的量,减小过拟合。
    简而言之,如果输入是图像的话,那么池化层的最主要作用就是压缩图像。

    这里再展开叙述池化层的具体作用。

    1. 特征不变性,也就是我们在图像处理中经常提到的特征的尺度不变性,池化操作就是图像的resize,平时一张狗的图像被缩小了一倍我们还能认出这是一张狗的照片,这说明这张图像中仍保留着狗最重要的特征,我们一看就能判断图像中画的是一只狗,图像压缩时去掉的信息只是一些无关紧要的信息,而留下的信息则是具有尺度不变性的特征,是最能表达图像的特征。

    2. 特征降维,我们知道一幅图像含有的信息是很大的,特征也很多,但是有些信息对于我们做图像任务时没有太多用途或者有重复,我们可以把这类冗余信息去除,把最重要的特征抽取出来,这也是池化操作的一大作用。

    3. 在一定程度上防止过拟合,更方便优化。

    在这里插入图片描述
    池化层用的方法有Max pooling 和 average pooling,而实际用的较多的是Max pooling。

    这里就说一下Max pooling,其实思想非常简单。
    在这里插入图片描述
    对于每个22的窗口选出最大的数作为输出矩阵的相应元素的值,比如输入矩阵第一个22窗口中最大的数是6,那么输出矩阵的第一个元素就是6,如此类推。

    (四)全连接层
    全连接层在我看来不大好理解,下面给出我自己的理解,全连接层的目的是将网络学习到的特征映射到样本的标记空间中。全连接层会把卷积输出的二维特征图(featureMap)转化成一个一维的向量。本案例中我们进行了2次卷积,最后得到了64个77的二维特征图(featureMap),我们需要把它转化为一维的,即77*64,代码如下

    h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])              #reshape成向量
    W_fc1 = weight_variable([7 * 7 * 64, 1024]) #1024代表卷积个数,我们可以任意取
    b_fc1 = bias_variable([1024])
    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
    

    这里我给个例子帮助你们理解tf.reshape(),请看代码

    import numpy as np
    import tensorflow as tf
    
    input = tf.Variable([[[[1]], [[1]], [[1]], [[1]]],
                        [[[1]], [[1]], [[1]], [[1]]]], dtype=float)
    b = tf.reshape(input, [1, 8])
    
    print(np.shape(input))
    print(np.shape(b))
    

    运行结果为, 从结果中我们可以看出,转换规则为,2411=18
    在这里插入图片描述
    同理,因为我们全连接层的输入,就是卷积层的输出,我们经过两次卷积后的输出为h_pool2= [-1, 7, 7, 64],为什么是-1,是因为我们最初的输入x_image = [-1, 28, 28, 1] , -1 代表着行数不确定。

    h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])              #reshape成向量
    

    我们就把 [-1, 7, 7, 64]转换为 [-1, 7764]。
    谨记,全连接层不是卷积层,所以这里是

    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
    

    我们用tf.matmul()只是把得到的特征值与权重w相乘再加上偏执b。
    最后我们需要加上,

    keep_prob = tf.placeholder("float")
    h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) 
    

    tf.nn.dropout()是tensorflow里面为了防止或减轻过拟合而使用的函数,它一般用在全连接层

    Dropout就是在不同的训练过程中随机扔掉一部分神经元。也就是让某个神经元的激活值以一定的概率p,让其停止工作,这次训练过程中不更新权值,也不参加神经网络的计算。但是它的权重得保留下来(只是暂时不更新而已),因为下次样本输入时它可能又得工作了。
    https://blog.csdn.net/yangfengling1023/article/details/82911306
    连接中有函数tf.nn.dropout的说明,很详细。

    最后给出我们整个运算过程并附上代码。

    在这里插入图片描述

    代码

    import tensorflow as tf
    import tensorflow.examples.tutorials.mnist.input_data as input_data
    
    mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
    x = tf.placeholder(tf.float32, [None, 784])  # 占位用,因为图片大小为28*28,所以为784,
    # 但是我们并不清楚有多少副,所以设为None,后续来添加
    y_actual = tf.placeholder(tf.float32, shape=[None, 10])  # 同理占位用,因为我们要测的是0-9一共10个数,即一共10个类别
    '''
     tf.truncated_normal(shape, mean, stddev) :shape表示生成张量的维度,mean是均值,stddev是标准差。
     这个函数产生正太分布,均值和标准差自己设定。就是说产生正太分布的值如果与均值的差值大于两倍的标准差,那就重新生成。
     和一般的正太分布的产生随机数据比起来,这个函数产生的随机数与均值的差距不会超过两倍的标准差,但是一般的别的函数是可能的。
     谨记 filter中的值是经过训练后确定的(代表着权重w)
    '''
    
    
    def weight_variable(shape):
        initial = tf.truncated_normal(shape, stddev=0.1)
        return tf.Variable(initial)
    
    
    # 偏置b
    
    
    def bias_variable(shape):
        initial = tf.constant(0.1, shape=shape)
        return tf.Variable(initial)
    
    
    # 卷积
    def conv2d(x, w):
    
        return tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME')
    
    
    # 池化层
    
    
    def max_pool(x):
    
        return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
    
    
    x_image = tf.reshape(x, [-1, 28, 28, 1])
    '''
    w_conv1代表着filter【5,5】为卷积核大小,1为通道数,32为卷积核的个数,卷积核个
    数的选取需要凭经验,也许有大神知道一定的规律,这里我讲一下卷积核的通道数为什么需
    要和输入的通道数一样,其实原理很简单,我们需要x_image和w_conv1,也就表示它们两
    个的子元素相乘,上边已经说过x_image的子元素为【28,1】,要想两者相乘,则w_conv1
    子元素必须为【1,n]
    
    '''
    w_conv1 = weight_variable([5, 5, 1, 32])
    b_conv1 = bias_variable([32])
    h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1)
    h_pool1 = max_pool(h_conv1)
    
    w_conv2 = weight_variable([5, 5, 32, 64])
    b_conv2 = bias_variable([64])
    h_conv2 = tf.nn.relu(conv2d(h_pool1, w_conv2) + b_conv2)
    h_pool2 = max_pool(h_conv2)
    
    '''
    7*7*64表示7*7的图片64个,也就表示一共有7*7*64个特征值(包含0),1024是实际上的特征值,使我们需要保留的
    '''
    
    w_fc1 = weight_variable([7*7*64, 1024])
    b_fc1 = bias_variable([1024])
    h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, w_fc1) + b_fc1)
    '''
    Dropout就是在不同的训练过程中随机扔掉一部分神经元。也就是让某个神经元的激活值以一定的概率p,
    让其停止工作,这次训练过程中不更新权值,也不参加神经网络的计算。但是它的权重得保留下来(只是暂时不更新而已),
    因为下次样本输入时它可能又得工作了,keep_prob表示丢弃的概率
    '''
    keep_prob = tf.placeholder("float")
    h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
    
    w_fc2 = weight_variable([1024, 10])
    b_fc2 = bias_variable([10])
    y_predict = tf.nn.softmax(tf.matmul(h_fc1_drop, w_fc2) + b_fc2)
    
    cross_entropy = -tf.reduce_sum(y_actual * tf.log(y_predict))  # 根据公式求和
    train_step = tf.train.GradientDescentOptimizer(1e-3).minimize(cross_entropy)  # 梯度下降法寻找最优解,训练时,不断的调整权重w
    correct_prediction = tf.equal(tf.argmax(y_predict, 1),
                                  tf.argmax(y_actual, 1))  # tf.equal返回的true或false,tf.argmax返回的是最大值的下标,
    # 0表示按列来,1表示按行来
    accuracy = tf.reduce_mean(
        tf.cast(correct_prediction, "float"))  # tf.cast dtype = float可以把bool(True or False)类型转化为float类型(数据),
    # tf.reduce_mean()求平均值,同样,0表示对列求平均,1表示对行求平均,既没有0也没有1的话对整个矩阵求平均
    sess = tf.InteractiveSession()
    sess.run(tf.global_variables_initializer())
    for i in range(20000):
        batch = mnist.train.next_batch(50)
        if i % 100 == 0:  # 训练100次,验证一次
            train_step.run(feed_dict={x: batch[0], y_actual: batch[1], keep_prob: 0.5})
    
    test_acc = accuracy.eval(feed_dict={x: mnist.test.images, y_actual: mnist.test.labels, keep_prob: 1.0})
    print("test accuracy %g" % test_acc)
    

    在此感谢博主http://www.cnblogs.com/skyfsm/p/6790245.html的宝贵经验。

    展开全文
  • Python实现卷积神经网络

    万次阅读 2018-01-16 22:16:04
    代码见https://github.com/rbtbecontinued/cnn。 目前尚未完全写好,支持随机梯度下降和批量梯度下降,激活函数仅支持sigmoid,输出层为softmax,池化核仅支持average,.../usr/bin/env python3 # -*- coding: utf-8
  • Python CNN卷积神经网络代码实现

    千次阅读 2018-11-22 18:33:00
     数据集为55000条,抽取训练集为100000,一层16个卷积核,二层32个卷积核,全连接层512,10分类:    2.训练集数据不变,增大卷积核数:  数据集为55000条,抽取训练集为1000,一层32个卷积核,二层64个...
  • 本篇文章主要介绍了PyTorch上实现卷积神经网络CNN的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 一、卷积神经网络 卷积神经网络(ConvolutionalNeuralNetwork,CNN)最初是...
  • 基于python卷积神经网络算法,程序运行在python2.7 64位机下,需要安装 numpy库,双击begin.py即可运行
  • 基于卷积神经网络CNN的人脸识别项目,主要代码包括对人脸数据的获取,对图像集的预处理,将图像加载到内存,构建并训练模型和识别人脸五个模块组成。
  • 今天小编就为大家分享一篇关于Python通过TensorFlow卷积神经网络实现猫狗识别,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
  • 使用卷积神经网络处理时间序列,属于最新的处理模型,非常适合处理时间序列
  • 本项目的所有代码均已在Python3.6及Pycharm平台调试通过,除了代码外,还提供《卷积神经网络(CNN)详解与代码实现》文档和《Notes on Convolutional Neural Networks》文档,其中:《卷积神经网络(CNN)详解与代码实现...
  • import numpy as np ... # 循环遍历图像以应用卷积运算 for r in np.uint16(np.arange(filter_size/2.0, img.shape[0]-filter_size/2.0+1)): for c in np.uint16(np.arange(filter_size/2.0, img.shape[1]-filter_s
  • 卷积神经网络的MATLAB代码,现有的代码大都是基于Python或者R编写的。
  • 超简明网课的CNN经典代码,实现了LeNet-5结构,相关博文链接可以参考如下:「https://blog.csdn.net/u013684446/article/details/105575942」。代码质量高,下载后直接运行即可

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 27,065
精华内容 10,826
关键字:

卷积神经网络python代码

python 订阅