精华内容
下载资源
问答
  • 带有强大的自适应tikhonov正则的谱去卷积和特征提取
  • 这项研究研究了使用会话抖动策略的另一种去卷积方法(多速率稳态平均去卷积,MSAD),其中,在不同SOA处记录的稳态响应足以导出瞬态AEP。 方法。 建立了线性变换模型以解决反卷积问题,并通过奇异值分解探索了变换...
  • MATLAB中盲去卷积deconvblind函数的使用

    千次阅读 2018-06-11 11:01:12
    deconvblind:使用盲解卷积模糊图像。[J,PSF] = deconvblind(I,INITPSF)使用最大似然算法对图像I解卷积,返回模糊图像J和恢复的点扩散函数PSF。 生成的PSF是与INITPSF相同大小的正数组,归一,所以它的...

    deconvblind:使用盲解卷积的去模糊图像。

    [J,PSF] = deconvblind(I,INITPSF)使用最大似然算法对图像I解卷积,返回去模糊图像J和恢复的点扩散函数PSF。 生成的PSF是与INITPSF相同大小的正数组,归一化,所以它的总和增加到1。PSF的恢复受其初始猜测大小INITPSF的影响较大,而其值较小(一个数组是一个更安全的猜测)。

    I 可以是N维数组。

    为了改善恢复,可以传入附加参数(如果中间参数未知,则使用[]作为占位符):

    [J,PSF] = deconvblind(I,INITPSF,NUMIT)
    [J,PSF] = deconvblind(I,INITPSF,NUMIT,DAMPAR)
    [J,PSF] = deconvblind(I,INITPSF,NUMIT,DAMPAR,WEIGHT)

    [J,PSF] = deconvblind(I,INITPSF,NUMIT,DAMPAR,WEIGHT,READOUT).

    PSF的附加限制可以通过用户提供的功能来提供:

    [J,PSF] = deconvblind(...,FUN)

    FUN(可选)是描述PSF附加约束的函数。 FUN必须是FUNCTION_HANDLE。 FUN在每次迭代结束时被调用。 FUN必须接受PSF作为其第一个参数,并且可以接受附加参数P1,P2,...,PN。 FUN应该返回一个参数PSF,它与INITPSF的大小相同,并满足积极性和规范化约束。

    NUMIT(可选)是迭代次数(默认值为10)。

    DAMPAR(可选)是一个数组,用于指定图像I(根据泊松噪声的标准偏差)的结果图像的阈值偏差,低于此值会发生阻尼。 对于在DAMPAR值内偏离其原始值的像素,迭代被抑制。 这可以抑制这些像素中的噪音,并在其他地方保留必要的图像细节。 默认值为0(无阻尼)。

    WEIGHT(可选)分配给每个像素以反映相机的拍摄质量。 将一个坏像素分配给零权值,从而排除该像素。 您可以根据平场校正的数量来调整自己的体重,而不是给予好像素的权重。 默认值是与输入图像I大小相同的单位数组。

    READOUT(可选)是对应于附加噪声(例如,背景,前景噪声)和读出相机噪声方差的阵列(或值)。READOUT必须以图像为单位。 默认值是0。

    注意,输出图像J可能会出现由算法中使用的离散傅里叶变换引入的振铃。 在调用deconvblind之前,为了减少振铃使用         I = EDGETAPER(I,PSF)。

    还要注意,deconvblind允许您从较早的解卷积运行结果开始恢复解卷积。 要启动此语法,输入I和INITPSF必须以单元数组{IN}和{INITPSF}的形式传入。 然后输出J和PSF变成单元阵列,并可以作为输入数组传递给下一个解卷积调用。 输入单元格数组可以包含一个数字数组(在初始调用时)或四个数值数组(当它是上一次解除绑定运行的输出时)。输出J包含四个元素,其中J {1} = I,J {2}是上一次迭代产生的图像,J {3}是前一次迭代前的图像,J {4}是 通过迭代算法内部使用的数组。

    Class Support
     -------------
    I and INITPSF can be uint8, uint16, int16, double, or single. DAMPAR and READOUT must have the same class as the input image. Other inputs have to be double. The output image J (or the first array of the output cell) has the same class as the input image I. The output PSF is double.                                                                                                          I 和 INITPSF可以是uint8,uint16,int16,double或single。 DAMPAR和READOUT必须与输入图像具有相同的等级。 其他投入必须是double。 输出图像J(或输出单元的第一个阵列)与输入图像I具有相同的类别。输出PSF是double
     
    Example
      -------

           I = checkerboard(8);
           PSF = fspecial('gaussian',7,10);
           V = .0001;
           BlurredNoisy = imnoise(imfilter(I,PSF),'gaussian',0,V);
           WT = zeros(size(I));WT(5:end-4,5:end-4) = 1;
           INITPSF = ones(size(PSF));
           [J P] = deconvblind(BlurredNoisy,INITPSF,20,10*sqrt(V),WT);
           subplot(221);imshow(BlurredNoisy);
                          title('A = Blurred and Noisy');
           subplot(222);imshow(PSF,[]);
                          title('True PSF');
           subplot(223);imshow(J);
                          title('Deblurred Image');
           subplot(224);imshow(P,[]);
                          title('Recovered PSF');
     


    展开全文
  • 一种用于外周血的新的扩展细胞去卷积 执照:GPL-3 EPIC软件包包含来自免疫甲基组(Salas等人2021)的Illumina HumanMethylationEPIC DNA甲基微阵列数据,该数据由56个磁性分选的血细胞参考和12个样本组成,使用...
  • 点态SA-DCT正则卷积。 本文给出的所有结果,都是使用基于低复杂度SA-DCT的算法得到的,并且可以使用点态自适应DCT Demobox进行复制。 用于模糊,去噪,都有很好的效果。
  • 卷积神经网络CNN模块剖析

    千次阅读 2019-07-03 08:51:41
    本文简要介绍了深度学习的发展。然后对卷积神经网络的几个模块进行了剖分讲解,包括:卷积层,池化层,非线性激活函数,全连接层以及损失函数和优化方法。搞懂了这些模块之后,你就可以读文章啦!


    一、深度学习概述

    1.1 发展历程

    上世纪60年代,Hubel等人通过对猫视觉皮层细胞的研究,提出了感受野这个概念。
    到80年代,日本科学家福岛邦彦(Kunihiko Fukushima)提出Neocognitron(神经认知机),直接启发了后来的卷积神经网络。
    1998年,Yann LeCun提出的卷积神经LeNet,首次提出了多层级联的卷积结构,可对手写数字进行有效识别。
    2012年, Alex依靠卷积神经网络AlexNet夺得ILSVRC 2012比赛的冠军,吹响了卷积神经网络研究的号角。AlexNet成功应用了ReLu、Dropout、最大池化、LRN(Local Response Normalization,局部响应归一化)、GPU加速等新技术,启发了后续更多的技术创新,加速了卷积神经网络和深度学习的研究。从此,深度学习研究进入蓬勃发展的新阶段。
    2014年Google提出的GoogleNet,运用Inception Module这个可以反复堆叠高效的卷积网络结构,获得了当年的ImageNet ILSVRC比赛的冠军,同年的亚军VGGNet全程使用3×3的卷积,成功训练了深度达19层的网络。
    2015年,微软提出了ResNet,包含残差学习模块,成功训练了152层的网络,一举拿下当年ILSVRC比赛的冠军。
    2019年3月27日 ——ACM宣布,深度学习的三位创造者Yoshua Bengio, Yann LeCun, 以及Geoffrey Hinton获得了2018年的图灵奖。
    在这里插入图片描述
    Hinton最重要的贡献:1983年发明的玻尔兹曼机(Boltzmann Machines),1986年发明反向传播的论文“Learning Internal Representations by Error Propagation”,AlexNet,在计算机视觉领域掀起一场革命。

    Yann LeCun:代表贡献之一是卷积神经网络,拓展了神经网络的应用范围。

    Bengio的贡献:在1990年代发明的Probabilistic models of sequences。发表了划时代的论文“A Neural Probabilistic Language Model”,使用高维词向量来表征自然语言。

    1.2 深度学习的兴起

    传统方法的瓶颈:人工设计特征是浅层特征,无法有效刻画对象的变化,所采用的识别网络是浅层网络。

    浅层学习:2006年前,多种浅层机器学习模型被提出,如感知机、BP神经网络、支持向量机等。这些模型的结构基本上可以看成带有一层隐层节点,或没有隐层节点的神经网络结构。

    兴起的标志:2006后,深度学习之父Hinton在《科学》杂志提出神经网络的深度学习方法,自此开启了深度学习在学术界和工业界的浪潮。

    深度学习的动机:更复杂的分布往往需要更深层的网络结构。更深层次的网络具有更强的非线性拟合能力

    1.3 深度学习的特点

    1)与人脑相似的信息处理:从低层到高层的深层次特征抽象。
    2)深层结构实现更复杂的非线性拟合。其本质是解决思路为维度空间映射,深层结构能够实现更复杂的非线性拟合。
    3)深度特征的自动提取:利用反向传播自动学习深度特征。

    1.4 深度学习的优势

    1)更优的大数据学习能力:与传统机器学习算法相比,深度网络的结构可以随数据的增加而充分挖掘数据内在的分布规律,获得更优的性能。
    2)更高层的特征提取机制:经典的机器学习算法需要复杂的特征提取过程。而深度神经网络可自适应地学习特征提取器,降低人工参与。
    3)更优异的泛化性能:与传统的ML算法相比,深度学习可通过迁移学习实现不同图像域的域自适应学习能力,从而更容易适应不同的领域和应用。

    深度学习产业化的核心要素:数据+运算能力+神经网络

    二、卷积神经网络剖析

    一般的卷积神经网络由以下几个层组成:卷积层,池化层,非线性激活函数,全连接层。这四者构成了常见的卷积神经网络。当然,损失函数也至关重要,还有各种各样的网络的优化,使得网络准确率更高。
    在这里插入图片描述

    2.1 卷积层

    卷积层:卷积层是一个卷积神经网络最重要的部分,也是卷积神经网络得名的缘由。卷积层中每一个节点的输入是上一层神经网络的一小块,卷积层试图将神经网络中的每一个小块进行更加深入地分析从而得到抽象程度更高的特征。

    CNN正式通过卷积的方式实现输入特征的提取和变换映射,从而获得数据的特征表示。卷积层本质上执行的是相关计算。
    在这里插入图片描述
    步长:卷积核移动的距离(包括下和左)。步长为n,则每次移动n个数值。
    在这里插入图片描述
    卷积后数据大小变化了,不再是原来数据的尺寸,怎么办?
    在原始数据周围补充0,以保持卷积后的数据大小与输入数据一致。即为padding操作。
    在这里插入图片描述
    可根据需要设定补零的层数, 是一个可以设置的超参数, 但要根据卷积核的大小, 步幅, 输入矩阵的大小进行调整, 以使得卷积核恰好滑动到边缘。

    一般情况下, 输入的图片矩阵以及后面的卷积核, 特征图矩阵都是方阵, 这里设输入矩阵大小为 ww, 卷积核大小为 kk, 步幅为 ss, 补零层数为 pp, 则卷积后产生的特征图大小计算公式为:
    在这里插入图片描述
    通常卷积层会使用多个滤波器实现特征的提取,如果将不同滤波器的输出级联起来,卷积层的输出可以看成是三维矩阵。
    在这里插入图片描述
    生成数据的深度:由滤波器的数量决定。
    生成数据每一层的宽和高:由滤波器的大小和步长决定
    在这里插入图片描述
    在输出的某个位置(w,h)(w,h)沿着depth方向汇聚着不同滤波器提取的特征.
    随着网络层的深入,卷积层抽取的特征逐渐由底层细化的边缘信息向高层抽象的语义信息过渡。

    通常图片有红绿蓝(RGB)三个颜色通道(Channel),那一个滤波器也需要三层滤波器对每个颜色通道进行过滤,于是6x6x3的图片经过3x3x3的滤波器过滤之后最终会得到一个4x4x1的图片,此时输出层图片的深度就是1。

    思考:为什么用卷积?
    计算量更低,并能保证性能

    在这里插入图片描述
    局部连接实现权值共享、稀疏连接、等变表示。

    稀疏连接:卷积核的连线数量相比于全连接的连线数量极为稀疏。

    等变表示:处于卷积网络更深层中的单元,他们的接受域要比处于浅层单元的接收域更大。如果网络还包含类似步幅卷积或者池化之类的结构特征,这种效应会加强。

    局部感受野:由于图像的空间联系是局部的,每个神经元不需要对全部的图像做感受,只需要感受局部特征即可,然后在更高层将这些感受得到的不同的局部神经元综合起来就可以得到全局的信息了,这样可以减少连接的数目。

    权值共享:不同神经元之间的参数共享可以减少需要求解的参数,使用多种滤波器去卷积图像就会得到多种特征映射。权值共享其实就是对图像用同样的卷积核进行卷积操作,也就意味着第一个隐藏层的所有神经元所能检测到处于图像不同位置的完全相同的特征。其主要的能力就能检测到不同位置的同一类型特征,也就是卷积网络能很好的适应图像的小范围的平移性,即有较好的平移不变性(比如将输入图像的猫的位置移动之后,同样能够检测到猫的图像)

    2.2 池化层

    用滤波器进行窗口滑动过程中,实际上"重叠"计算了很多冗余的信息,而池化操作就是去除这些冗余信息,并加快运动。

    思考:池化层有什么作用?
    1)池化用于降低尺度,从而避免大尺度所带来的高计算负担。
    2)通过降低特征的分辨率使得特征对平移和其他形式变形的敏感度降低,增强特征的鲁棒性。
    3)此外,池化层还能够降低特征维度(相比使用所有提取得到的特征),改善网络输出(不容易过拟合)

    池化操作包括最大池化操作Max Pooling平均池化操作Mean Pooling
    在这里插入图片描述

    2.3 非线性激活函数

    通常需要对卷积层和全连接层的输出使用激活函数进行处理,提升CNN的性能。

    • 常用的非线性激活函数:
    在这里插入图片描述
    在这里插入图片描述

    1.整流线性单元(Relu)使用激活函数
    在这里插入图片描述
    整流线性单元易于优化,整流线性单元在其一半的定义域上输出为零。
    这使得只要整流线性单元处于激活状态,它的导数都能保持较大。它的梯度不但大而且一致,一阶导数处处为1。

    整流线性单元通常作用于仿射变换之上:
    在这里插入图片描述
    整流线性单元的一个缺陷是它们不能通过基于梯度的方法学习那些使它们激活为零的样本。

    整流线性单元的3个扩展:基于当 zi<0z_i<0时使用一个非零的斜率 αiα_i
    在这里插入图片描述
    1)绝对值整流:固定αi=1α_i=-1 来得到g(z)=zg(z)=|z|
    2)渗漏整流线性单元(Leaky ReLU):将αiα_i 固定成一个类似0.01的小值,
    3)参数化整流线性单元(parametric ReLU)或者 PReLU 将αiα_i作为学习的参数。

    2.maxout单元(maxout unit)进一步扩展了整流线性单元。maxout单元将z划分为每组具有k个值的组,
    在这里插入图片描述
    这里 G((i))G^((i)) 是组ii的输入索引集{(i1)k+1,,ik}\{(i-1)k+1,…,ik\}

    maxout单元具有抵抗一种被称为灾难遗忘(catastrophic forgetting)的现象,这个现象是说神经网络忘记了如何执行它们过去训练的任务.

    原因:每一组中可以容许一些冗余来保存之前训练的知识。

    3.logistic sigmoid与双曲正切函数
    之前,大多数神经网络使用 logistic sigmoid 激活函数:
    在这里插入图片描述
    或者是双曲正切激活函数
    在这里插入图片描述
    这些激活函数紧密相关,因为tanh(z)=2σ(2z)1tanh⁡(z)=2σ(2z)-1
    在这里插入图片描述
    sigmoid单元作为输出单元用来预测二值型变量取值为1的概率。sigmoid单元在其大部分定义域内都饱和——当z取绝对值很大的正值时,它们饱和到一个高值,当z取绝对值很大的负值时,它们饱和到一个低值,并且仅仅当z接近0时它们才对输入强烈敏感。sigmoid单元的广泛饱和性会使得基于梯度的学习变得非常困难。
    在这里插入图片描述
    tanh(0)=0tanh⁡(0)=0σ(0)=1/2σ(0)=1/2 的意义上,前者更像是单位函数。

    当必须要使用sigmoid激活函数时,双曲正切激活函数通常要比 logistic sigmoid函数表现更好。
    sigmoid 激活函数在除了前馈网络以外的情景中更为常见,如循环网络、许多概率模型以及一些自编码器。

    4:其他激活函数

    径向基函数(radial basis function, RBF):这个函数在z接近模板W:,iW_{:,i}时更加活跃。因为它对大部分xx都饱和到0,因此很难优化。

    softplus函数g(a)=ζ(a)=log(1+ea)g(a)=ζ(a)=log⁡(1+e^a)。这是整流线性单元的平滑版本,Glorot et al.比较了softplus和整流线性单元,发现后者的结果更好。
    在这里插入图片描述
    在这里插入图片描述
    硬双曲正切函数(hard tanh):它的形状和tanh以及整流线性单元类似,但是不同于后者,它是有界的,
    在这里插入图片描述
    上式最小为-1,最大为1。

    针对非线性激活函数的设计仍然是一个活跃的研究领域,许多有用的隐藏单元类型仍有待发现。

    2.4 全连接层

    全连接层把卷积层的输出拉直成向量,然后使用传统的神经网络实现特征变换。
    在这里插入图片描述

    全连接层的作用:
    • 把卷积层的输出转换为向量形式
    • 可以通过内积运算实现
    • 每个输出神经元与所有的输入神经元连接
    在这里插入图片描述
    通常情况下,全连接层常加在卷积层后,进行结果的预测。

    2.5 损失函数

    我们到目前为止看到的线性模型和神经网络的最大区别,在于神经网络的非线性导致大多数我们感兴趣的代价函数都变得非凸。这意味着神经网络的训练通常使用迭代的、基于梯度的优化,仅仅使得代价函数达到一个非常小的值;而不是像用于训练线性回归模型的线性方程求解器,或者用于训练逻辑回归或SVM的凸优化算法那样保证全局收敛。

    用于非凸损失函数的随机梯度下降没有这种收敛性保证,并且对参数的初始值很敏感。

    和其他的机器学习模型一样,为了使用基于梯度的学习方法我们必须选择一个代价函数,并且我们必须选择如何表示模型的输出。深度神经网络设计中的一个重要方面是代价函数的选择。

    在大多数情况下,我们的参数模型定义了一个分布p(yx;θ)p(y|x;θ)并且我们简单地使用最大似然原理。这意味着我们使用训练数据和模型预测间的损失作为代价函数。

    如果我们对于同一个随机变量x有两个单独的概率分布P(x)P(x)Q(x)Q(x),我们可以使用KL散度( Kullback-Leibler (KL) divergence)来衡量这两个分布的差异:
    在这里插入图片描述
    举例:P和Q分别代表目标标签和网络输出标签,则KL散度刻画两个分布的相似性。

    KL散度有很多有用的性质,最重要的是它是非负的。
    KL散度为0当且仅当P和Q在离散型变量的情况下是相同的分布,或者在连续型变量的情况下是“几乎处处”相同的。
    因为KL散度是非负的并且衡量的是两个分布之间的差异,它经常被用作分布之间的某种距离。
    然而,它并不是真的距离因为它不是对称的:对于某些PPQQ,DKL(PQ)DKL(QP)D_KL (P‖Q) \neq D_{KL} ( Q‖P)

    一个和KL散度密切联系的量是交叉熵(cross-entropy),即 H(P,Q)=H(P)+DKL(PQ)H(P,Q)=H(P)+D_{KL} (P‖Q),它和KL散度很像但是缺少左边一项:
    在这里插入图片描述
    在这里插入图片描述
    针对Q最小化交叉熵等价于最小化KL散度,因为Q并不参与被省略的那一项。

    理解:x(类)在P的分布很大(即为目标类),则期望Q(x)的分布也很大,即输出概率要大,与我们的训练吻合。

    在这里插入图片描述
    代价函数的具体形式随着模型而改变,取决于logpmodellog ⁡p_{model}的具体形式

    如果pmodel(yx)=N(y;f(x;θ),I)p_{model} (y│x)=N(y;f(x;θ),I),那么我们就重新得到了均方误差代价:
    在这里插入图片描述
    即:给定特征h,线性输出单元层产生一个向量y=wTh+by=w^T h+b。线性输出层经常被用来产生条件高斯分布的均值:
    在这里插入图片描述
    最大化其对数似然此时等价于最小均方误差。

    如果用Bernoulli输出,所对应的分布采用sigmoid单元

    sigmoid单元输出定义为:

    在这里插入图片描述
    我们可以认为sigmoid输出单元具有两个部分。首先,它使用一个线性层来计算z=wTh+bz=w^T h+b 。接着,它使用sigmoid激活函数将zz转化成概率。

    P(y)P(y)可由非归一化(和不为1)的概率分布p~(y)\tilde{p}(y)来得到。
    在这里插入图片描述
    这种在对数空间里预测概率的方法可以很自然地使用最大似然学习。因为用于最大似然的代价函数是logP(yx)-log⁡P(y|x),代价函数中的loglog抵消了sigmoid 中的expexp。它的损失函数为:
    在这里插入图片描述
    在这里插入图片描述
    通过将损失函数写成softplus函数的形式,我们可以看到它仅仅在(12y)z(1-2y)z取绝对值非常大的负值时才会饱和。因此饱和只会出现在模型已经得到正确答案时——当y=1y=1zz取非常大的正值时,或者y=0y=0zz取非常小的负值时。

    如果Multinoulli输出分布softmax单元
    看作是sigmoid函数的扩展,softmax函数最常用作分类器的输出,来表示 n 个不同类上的概率分布。

    softmax 函数的形式为:
    在这里插入图片描述
    交叉熵为:
    在这里插入图片描述
    其中:
    在这里插入图片描述
    多个样本下:
    在这里插入图片描述
    对输出xk(n)x_k^{(n)} 经过softmax处理后,每一个p^k(n)\hat{p}_k^{(n)}的取值范围被限定在 [0,1][0,1]之内,而且要满足k=1Kp^k(n)=1\sum_{k=1}^{K}\hat{p}_k^{(n)}=1。这时,某个p^k(n)\hat{p}_k^{(n)}的增大势必会导致其他p^k(n)\hat{p}_k^{(n)}减小。因此,在优化的时候只需要针对标签为kk的样本的输出值p^k(n)\hat{p}_k^{(n)}进行优化,使其增大。
    在这里插入图片描述
    Softmax Loss 在二分类情况下的特殊情形 :
    在这里插入图片描述

    2.6 反向传播

    反向传播是训练神经网络的常用方法,通过链式求导法则和梯度下降法,从最后一层到第一次,逐渐实现神经网络参数的训练。
    与 BP神经网络一样, CNN 也是通过梯度下降和反向传播算法进行训练的, 则全连接层的梯度公式与 BP网络完全一样, 这里就不重复了. 下面介绍卷积层和池化层的梯度公式。
    在这里插入图片描述
    现在的目标是求出 δijδ_{ij}vijwij\frac{∂v_{ij}}{ ∂w_{ij}}的表达式. 首先求 δijδ_{ij}, 从一个简单情况开始.

    设输入是 3×3的矩阵, 卷积核是 2×2 的矩阵.
    (1) 当步长为 1 时, 则可得到 2×2的特征图矩阵. 如下图所示:
    在这里插入图片描述
    绿色矩阵是第l1l−1层神经元, 红色的是第 ll 层, 黄色的是第 ll层的卷积核, 图中省略掉了第 l1l−1 层的卷积核.。每个矩阵的元素可以看成一个神经元, 于是和 BP网络一样, 可以对每个神经元定义局部梯度, 为了看着清楚, 把矩阵的元素换成 δδ. 神经网络中数值的传递也可以看成导数的传递. 假设已经求出了 δlδ^l, 则 δl1δ^{l−1}的计算公式为:
    在这里插入图片描述
    这是一个递归公式. δδ, ww, vv 是矩阵形式, 公式中 rot180() 函数表示将矩阵逆时针旋转 180180度, 参数 full 表示进行的完全的卷积运算, 这种运算形象的解释如下:
    在这里插入图片描述
    首先将特征图矩阵补一圈零, 然后用权重矩阵对补零后的特征图矩阵进行 vaild 型卷积运算.。这里补零的层数等于卷积核矩阵的大小减去 1, full型 卷积的内涵在于使卷积从边缘开始, 即先计算w11lδ11l{ w^{l}_{11}} δ_{11}^l, 然后是 w12lδ11l+w11lδ12l{ w^{l}_{12}} {δ_{11}^l}+{ w^{l}_{11}} δ_{12}^l, 以此类推。

    (2) 当滑动步幅大于 1 时
    在这里插入图片描述
    上图分别是步长为 1, 2 时的卷积过程, 可以发现步长为 1 是一个比较完全的卷积, 当步长增大时, 会跳过某些区域, 因此可以通过对特征图补零的方式将步幅为 2 时生成的特征图转换为步幅 1 的特征图, 然后直接利用前面推导的公式即可求出 δl1δ^{l−1}. 补零如下图所示:
    在这里插入图片描述
    (3) 当卷积核数目为 N 时, 与 BP 网络隐藏层神经元局部梯度计算类似, 每一个权重的改变, 都会影响到下一层每一个神经元输入的改变, 所以误差的反响传递需要把误差之和传到前一层, 则公式可简单地修改为
    在这里插入图片描述
    (4) 对于池化层的梯度传递, 情况就简单了一些, 下面以 Max Pooling 为例
    在这里插入图片描述
    图中滑动窗口大小为 2×2, 步幅为 2, 则得到一个 2×2 的特征图, Max Pooling 方法是选择最大的数值作为输出, 由于过程中没有任何运算, 不存在梯度的变化, 所以误差可以直接由第 ll 层传递到第 l1l−1 层, 如下图所示:
    在这里插入图片描述
    图中假设四个角上的元素值最大, 则对应位置的局部梯度可直接反向传递, 其它位置由于没有连接, 则梯度设为 0.

    如果池化类型是 Mean Pooling, 即取滑动窗口内的均值作为输出, 则将 ll 层的梯度的14\frac{1}{ 4} 反向传递到 l1l−1 层, 如下图所示:
    在这里插入图片描述
    到此为止已经推导出了不同情况下的 δδ 的递归公式, 下面推导 vijwij\frac{∂v_{ij}}{ ∂w_{ij}} 的表达式. 下图所示, 为了表达清楚, 将符号做一些替换, 相对于第 ll 层, 第 l1l−1层的输出变量符号可由 yy 变为 xx.
    在这里插入图片描述
    根据卷积的原理, 可以得到:
    在这里插入图片描述
    可以发现, 由于共享权重, 一个权重 wijwij 的改变, 会影响所有的 yy. 因而对某一个权重求梯度时, 需要运用全微分公式. 现在以 Ewijl\frac{∂E}{ ∂w_{ij}^l} 为例, 求得表达式:
    在这里插入图片描述
    同理可得:
    在这里插入图片描述
    根据得到的结果, 可以发现计算 Ewijl\frac{∂E}{ ∂w_{ij}^l} 的规律:
    在这里插入图片描述
    首先将前面的图中卷积核和特征图调换一下位置, 将特征图矩阵的元素替换为 δδ, 将卷积核矩阵的元素替换为 EEww 的偏导. 根据前面得到的偏导公式, 可以发现特征图对输入矩阵卷积可得到右边黄色的偏导矩阵. 即
    在这里插入图片描述
    公式中 ww,δδ, xx 是以矩阵形式表达的. 同时, 可得到
    在这里插入图片描述

    2.7 网络优化

    1 反向传播算法(Back Propagation Algorithm)

    反向传播是训练神经网络的常用方法,通过链式求导法则和梯度下降法,从最后一层到第一次,逐渐实现神经网络参数的训练。

    在这里插入图片描述
    基于梯度下降的参数更新算法:
    在这里插入图片描述

    使用最多的GD算法:Mini-batch SGD
    结合了GD和SGD,对小批量数据使用梯度下降,是一种有效的参数更新方法
    在这里插入图片描述
    算法
    在这里插入图片描述
    Mini-batch SGD 算法中,有两个需要预先设置的参数:权重衰减(weight decay),和动量系数(momentum)

    Weight Decay:与2-范数配合使用,避免网络过拟合。取值较小,通常设置为 0.0005。
    在这里插入图片描述
    2 梯度消失
    在这里插入图片描述
    对于sigmoid、tanh等激活函数,由于其导数值σx{\sigma }'(x)在某些情况下接近于 0 ,导致传到网络底层的梯度数值很小,造成网络参数更新缓慢,难以收敛。

    解决(减缓)办法:

    1)使用ReLU激活函数
    • ReLU激活函数的导数值非0即1
    • 避免传统sigmoid激活函数导数值过低的问题
    在这里插入图片描述
    2)Batch Normalization
    • 对每一层的计算结果进行尺度归一化
    • 收敛速度加速5~20倍
    • 作为一种正则化技术可以提高网络的泛化能力
    在这里插入图片描述
    在这里插入图片描述
    3)Dropout 连接方式提高网络性能
    • 训练阶段通过随机地选择神经元进行网络训练
    • 有效防止网络过拟合,提高泛化能力
    在这里插入图片描述
    在这里插入图片描述
    好啦,搞懂了每个模块之后,就可以去看懂文章啦!现在很多改进、优化的方法,就是在这些模块上的改进。

    三、项目实战

    项目实战请转至:tensorflow学习笔记(七):CNN手写体(MNIST)识别

    系列相关论文:
    1.BP神经网络的详细推导
    2.用于图像分类的经典的卷积神经网络CNN
    3.神经⽹络可以计算任何函数的可视化证明

    展开全文
  • 我们在前几节介绍过卷积网络的运算原理,以及通过代码实践,体验到了卷积网络对图片信息抽取的有效性...从2013年起,研究人员找到了不少有效的视觉方法研究卷积网络对图片信息的学习过程,通过视觉呈现,我们...

    我们在前几节介绍过卷积网络的运算原理,以及通过代码实践,体验到了卷积网络对图片信息抽取的有效性。现在一个问题在于,我们知道卷积网络的运算过程,但不知道为什么卷积运算过程就能有效的识别图片,也就是说我们知其然但不知其所以然,这节我们通过视觉化的方式看看卷积网络是怎么从图片中抽取出有效信息的。

    从2013年起,研究人员找到了不少有效的视觉化方法去研究卷积网络对图片信息的学习过程,通过视觉化呈现,我们人类可以有效的认识到卷积网络的学习过程。我们将通过视觉化的方式看看卷及网络的每一层是如何提取图片信息的,然后再通过视觉展现的方式看看Max Pooling层的作用。我们先看看我们自己构造的网络是怎么对图片进行学习的,卷积网络会对图片数据进行层层计算和过滤,我们把它过滤后的数据“画”出来看看,首先我们先把前两节训练好的网络加载进来:

    from keras.models import load_model
    #我们前几节在训练网络后,曾经以下面名字把训练后的网络存储起来,现在我们重新将它加载
    model = load_model('cats_and_dogs_small_2.h5')
    model.summary()

    大家可以翻看我们前几节的代码,那时在训练好网络后,我们会将其存储起来,现在我们把那时存储的网络重新加载到内存中。上面代码运行后结果如下:

    屏幕快照 2018-07-24 上午11.02.00.png

    从上面结果看到,我们的网络有好几个卷积层和Max pooling层,我们用一张图片传入网络,每一层会对图片进行计算,然后抽取信息,我们把每一层抽取的信息绘制出来看看。我们加载一张图片,对其做一些数据变换,然后把图片绘制出来看看:

    img_path = '/Users/chenyi/Documents/人工智能/all/cats_and_dogs_small/test/cats/cat.1700.jpg'
    
    from keras.preprocessing import image
    import numpy as np
    import matplotlib.pyplot as plt
    #把图片缩小为150*150像素
    img = image.load_img(img_path, target_size = (150,150))
    img_tensor = image.img_to_array(img)
    img_tensor = np.expand_dims(img_tensor, axis = 0)
    #把像素点取值变换到[0,1]之间
    img_tensor /= 255.
    print(img_tensor.shape)
    plt.figure()
    plt.imshow(img_tensor[0])

    上面代码运行后结果如下:

    屏幕快照 2018-07-24 上午11.18.05.png

    我们把网络中的前八层,也就是含有卷积和Max pooling的网络层单独抽取出来,代码如下:

    from keras import models
    import matplotlib.pyplot as plt
    '''
    我们把网络的前8层,也就是含有卷积和max pooling的网络层抽取出来,
    下面代码会把前八层网络的输出结果放置到数组layers_outputs中
    '''
    layer_outputs = [layer.output for layer in model.layers[:8]]
    activation_model = models.Model(inputs=model.input, outputs = layer_outputs)
    #执行下面代码后,我们能获得卷积层和max pooling层对图片的计算结果
    activations = activation_model.predict(img_tensor)
    #我们把第一层卷积网络对图片信息的识别结果绘制出来
    first_layer_activation = activations[0]
    print(first_layer_activation.shape)
    plt.figure()
    plt.matshow(first_layer_activation[0, :, : , 4], cmap = 'viridis')

    上面代码专门抽取出网络中包含卷积和max pooling的前八层,然后把上面的图片传入,这八层网络层会分别从图片中抽取信息,上面代码把第一次卷积层从图片中获取的信息绘制出来,上面代码运行结果如下:

    屏幕快照 2018-07-24 上午11.33.13.png

    大家看的上面图片就是第一层卷积网络从原图片中抽取出来的信息。网络层获得的信息表示是148*148*32,也就是抽取出的图像大小是148*148个像素,其中每个像素对应一个含有32个元素的向量,我们只把向量中前4个元素表示的信息视觉化,如果我们把前7个元素视觉化看看,其代码如下:

    plt.figure()
    plt.matshow(first_layer_activation[0, :, : , 7], cmap = 'viridis')

    上面代码运行结果如下,注意你自己运行结果跟我很可能不一样,因为网络对图像的学习结果与它所运行的环境相关,不是确定性的:

    屏幕快照 2018-07-24 上午11.41.45.png

    上面结果表明网络把绿色值高的像素点抽取出来了。接下来我们用代码把每一层卷积运算后所识别的图片信息绘制出来:

    layer_names = []
    for layer in model.layers[:8]:
        layer_names.append(layer.name)
    
    images_per_row = 16
    for layer_name, layer_activation in zip(layer_names, activations):
        #layer_activation的结构为(1, width, height, array_len)
        #向量中的元素个数
        n_features = layer_activation.shape[-1]
        #获得切片的宽和高
        size = layer_activation.shape[1]
        #在做卷积运算时,我们把图片进行3*3切片,然后计算出一个含有32个元素的向量,这32个元素代表着网络从3*3切片中抽取的信息
        #我们把这32个元素分成6列,绘制在一行里
        n_cols = n_features // images_per_row
        display_grid = np.zeros((size * n_cols, images_per_row * size))
        for col in range(n_cols):
            for row in range(images_per_row):
                channel_image = layer_activation[0, : , :, col * images_per_row  + row]
                #这32个元素中,不一定每个元素对应的值都能绘制到界面上,所以我们对它做一些处理,使得它能画出来
                channel_image -= channel_image.mean()
                channel_image /= channel_image.std()
                channel_image *= 64
                channel_image += 128
                channel_image = np.clip(channel_image, 0, 255).astype('uint8')
                display_grid[col * size : (col + 1) * size, row * size : (row + 1) * size] = channel_image
    
        scale = 1. / size
        plt.figure(figsize = (scale * display_grid.shape[1], scale * display_grid.shape[0]))
        plt.title(layer_name)
        plt.grid(False)
        plt.imshow(display_grid, aspect = 'auto', cmap = 'viridis')

    上面代码运行后,得到的部分结果如下:
    屏幕快照 2018-07-24 下午5.12.01.png

    上图表示的是,第一次卷积网络从图片中抽取处理的信息,它主要抽取猫的边缘,经过第一层后,原来图片的很多信息还保留着,这些信息将交由后面的卷积网络继续抽取,我再看看最后一层网络抽取出来的信息:

    屏幕快照 2018-07-24 下午5.15.27.png

    随着卷积网络的层次越高,它抽取出的信息就越抽象,就越难以被人的直觉所理解。我们把卷积层对图片的识别结果绘制出来,从中我们能观察到,网络层次越高,对图片所表示规律的抽取越深,它展现出来就越抽象,这些抽象特性可能表示所有猫所具备的共同特质,神经网络就如同信息抽取蒸馏管,每经过一处,图片中包含的噪音就去除掉一层,网络就越能得到越纯粹的该类图片所表示的共同信息。

    这个过程与人的认知过程很像,我们看几张猫图片后,就能够把世界上所有的猫都识别出来,我们并没有看到黑猫图片后,给一只白猫就认不出来,因此人通过视觉把图像传送到脑中后,脑神经通过层层运算,把图像中蕴含的本质信息抽取出来,于是人看到一张黑猫的图片,就把其中蕴含的“猫”的抽象信息获取,下次看到一只白猫时,大脑也把白猫所表示的“猫”的抽象信息获取到,两者一比对,大脑就知道,黑猫白猫本质上是同一类事物。加入让你绘制一个骑自行车的人,我们大多数人都会画出如下形式:

    屏幕快照 2018-07-24 下午5.28.57.png

    上面图案表示着我们对“人其自行车”的概念性,抽象认知,我们看到任何骑自行车的人,我们都会抽象出上面这幅图案,我们把各种无关的信息取出掉,例如背景,人的衣服,形态等,无关紧要的信息全部去光后,就会得到上面的信息。

    更详细的讲解和代码调试演示过程,请点击链接

    更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:
    这里写图片描述

    展开全文
  • 其实,让我们解释一个层数较少的简单神经网络工作原理并不难,但是当我们将计算机视觉项目中的神经网络层数增加到1000层时,它的可解释性就非常差了。现实情况是,我们的用户或者终端需要可解释性——他们想知道...

    摘要

    “你的神经网络是如何生成这个结果的?”这个问题也曾让许多数据科学家陷入了困境。其实,让我们去解释一个层数较少的简单神经网络工作原理并不难,但是当我们将计算机视觉项目中的神经网络层数增加到1000层时,它的可解释性就非常差了。

    现实情况是,我们的用户或者终端需要可解释性——他们想知道我们的模型是如何得到最终的结果的。但是,深度神经网络的工作原理没有办法通过文字被清楚地描述出来,这个时候深度神经网络就被打上了“黑盒子”的标签,那我们该如何摆脱这个标签呢?

    我们可以通过可视化来解决这个问题!当一个神经网络通过可视化的方式展示出来时,他的可解释性将会得到极大的提升,可视化可以将神经网络模型中处理数据的过程清晰展现。尤其当我们处理基于成千上万数据的卷积神经网络(CNN)时更是如此。

    3bb66018feba8fb3ba2a5e5a8a16b1d9.png

    在本文中,我们将介绍多种用于可视化卷积神经网络的技术。 此外,我们还可以从这些可视化中加深观察信息,以调整我们的CNN模型。

    内容表

    1.我们为什么要使用可视化解码神经网络?

    2.设置模型的体系结构

    3.访问CNN的每个层

    4.滤波器—可视化CNN的构成模块

    5.最大化激活—可视化模型所期望的内容

    6.遮挡贴图—可视化输入中的重要内容

    7.显著性贴图—可视化输入特征的贡献

    8.分类激活映射

    9.可视化分层输出—可视化过程

    我们为什么要使用可视化解码神经网络?

    除可视化之外,有很多方法可以帮助我们去理解神经网络是如何工作的,那么这篇文章为什么要转向可视化这种非常规途径呢?

    我们通过一个例子来回答这个问题。假设我们正在做一个对动物图片进行分类的项目,如分类雪豹与阿拉伯豹。从图片来看,我们可以使用图像背景来区分这两种动物。

    两种动物的栖息地可以形成鲜明的对比。大多数雪豹图像的背景里都会有雪,而大多数阿拉伯豹图片里都会有一片茫茫沙漠。

    fcb3113745593066159ae5d6b2ae4ebf.png

    问题来了——模型可以通过分类雪与沙漠的图像从而去分类雪豹与阿拉伯豹。那么,我们如何确保我们的模型正确地学习了这两种不同类型豹子的不同特征呢?可视化会给我们答案。

    可视化有助于我们了解哪些特征正在指导模型对图像进行分类的决策。

    将模型可视化有许多种方法,在本文中,我们将展示其中的一些。

    设置模型的体系结构

    实践是最好的学习方式之一。因此,我们立刻开始研究模型的代码。

    在本文中,我们在ImageNet数据集上使用VGG16架构模型和预训练权重。首先我们先将模型程序导入并开始理解其架构。

    我们将使用Keras中的'model.summary()'函数来可视化模型体系结构。在我们进入模型构建部分之前,这是非常重要的一步。我们需要确保输入和输出形状与我们的问题陈述相匹配,因此我们先可视化模型摘要。

    #importing required modules
    from keras.applications import VGG16
    #loading the saved model
    #we are using the complete architecture thus include_top=True
    model = VGG16(weights='imagenet',include_top=True)
    #show the summary of model
    model.summary()

    以下是上述代码生成的模型摘要:

    202392dc4005d10b2c2b25f20164b3d4.png

    e5ba133e8cebcaee8fe917bf5895abf5.png

    我们有了模型的详细架构以及每层的可训练参数的数量。上面的输出可以多花一点时间去浏览,这样才能了解我们现有的数据情况。

    我们仅训练模型层的一个子集(特征提取)是很重要的。 我们可以生成模型摘要,并确保不可训练参数的数量与我们不想训练的层匹配。

    此外,我们可以使用可训练参数的总数来检查我们的GPU是否能够为训练模型分配足够的内存。 这对于我们大多数在个人电脑上工作的人来说,是一个比较熟悉的挑战!

    访问CNN的每个层

    既然我们知道如何获得模型的整体架构,让我们深入探索并尝试探索每个独立的层。

    实际上,访问Keras模型的各个层并提取与每个层相关的参数非常容易。 这包括图层权重和其他信息,如滤波器的数量。

    现在,我们将创建将图层名称映射到其相应特征和图层权重的字典:

    #creating a mapping of layer name ot layer details
    #we will create a dictionary layers_info which maps a layer name to its charcteristics
    layers_info = {}
    for i in model.layers:
    layers_info[i.name] = i.get_config()
    #here the layer_weights dictionary will map every layer_name to its corresponding weights
    layer_weights = {}
    for i in model.layers:
    layer_weights[i.name] = i.get_weights()
    print(layers_info['block5_conv1'])

    上面的代码给出了以下输出,它由block5_conv1层的不同参数组成:

    {'name': 'block5_conv1',
    'trainable': True,
    'filters': 512,
    'kernel_size': (3, 3),
    'strides': (1, 1),
    'padding': 'same',
    'data_format': 'channels_last',
    'dilation_rate': (1, 1),
    'activation': 'relu',
    'use_bias': True,
    'kernel_initializer': {'class_name': 'VarianceScaling',
    'config': {'scale': 1.0,
    'mode': 'fan_avg',
    'distribution': 'uniform',
    'seed': None}},
    'bias_initializer': {'class_name': 'Zeros', 'config': {}},
    'kernel_regularizer': None,
    'bias_regularizer': None,
    'activity_regularizer': None,
    'kernel_constraint': None,
    'bias_constraint': None}

    不知你有没有注意到图层'block5_conv1'的可训练参数是否为真? 这意味着我们可以通过进一步训练模型来更新图层权重。

    滤波器—可视化CNN的构成模块

    滤波器是任何卷积神经网络的基本构建模块。不同的滤波器从图像中提取不同类型的特征。下面的GIF图非常清楚地说明了这一点:

    91ec61479ff2902f5fb8d51e04c49868.png

    如图所示,每个卷积层都由多个滤波器组成。查看我们在上一节中生成的输出 - 'block5_conv1'层由512个滤波器组成。这是对应的,是吧?

    让我们绘制每个VGG16块的第一个卷积层的第一个滤波器:

    layers = model.layers
    layer_ids = [1,4,7,11,15]
    #plot the filters
    fig,ax = plt.subplots(nrows=1,ncols=5)
    for i in range(5):
    ax[i].imshow(layers[layer_ids[i]].get_weights()[0][:,:,:,0][:,:,0],cmap='gray')
    ax[i].set_title('block'+str(i+1))
    ax[i].set_xticks([])
    ax[i].set_yticks([])

    fdc65579643f6e2ef98fdb8bb0123dfe.png

    我们可以在上面的输出中看到不同层的滤波器。由于VGG16仅使用3×3滤波器,因此所有滤波器都具有相同的形状。

    最大化激活—可视化模型所期望的内容

    我们使用下面的图片来理解最大化激活的概念:

    c0d796fed7e65a8b574ec8452176f7e0.png

    你认为对模型去识别大象来说哪些特征是重要的?下面是我想到的一些主要的特征:

    • 象牙
    • 象鼻
    • 象耳

    那就是我们在本能情况下如何识别大象的,对吧?现在,当我们看看当我们尝试优化任意分类大象图像的模型时,我们在过程中得到了什么。

    我们知道CNN中的每个卷积层都在前一层的输出中寻找相似的模式。当输入由它正在寻找的模式组成时,卷积层的激活被最大化。

    在最大化激活技术中,我们更新每层的输入,以便将最大化激活的损失降到最低。

    我们是如何做到这一点的?我们通过计算相对于输入的激活损失函数的梯度,然后相应得更新输入:

    下面是这个操作的代码:

    #importing the required modules
    from vis.visualization import visualize_activation
    from vis.utils import utils
    from keras import activations
    from keras import applications
    import matplotlib.pyplot as plt
    %matplotlib inline
    plt.rcParams['figure.figsize'] = (18,6)
    #creating a VGG16 model using fully connected layers also because then we can
    #visualize the patterns for individual category
    from keras.applications import VGG16
    model = VGG16(weights='imagenet',include_top=True)
    #finding out the layer index using layer name
    #the find_layer_idx function accepts the model and name of layer as parameters and return the index of respective layer
    layer_idx = utils.find_layer_idx(model,'predictions')
    #changing the activation of the layer to linear
    model.layers[layer_idx].activation = activations.linear
    #applying modifications to the model
    model = utils.apply_modifications(model)
    #Indian elephant
    img3 = visualize_activation(model,layer_idx,filter_indices=385,max_iter=5000,verbose=True)
    plt.imshow(img3)

    我们的模型使用随机输入对印度象进行分类,生成了以下输出:

    b89044974a9e773eafe0f7903d708075.png

    从上面的图像中,我们可以观察到该模型需要像牙齿,大眼睛和象牙这样的结构。现在,这些信息对于我们检查数据集的完整性非常重要。 因为印度象通常存在于长满树木或长草的栖息地中,所以模型可能会侧重于背景中的栖息地特征,而这是不对的。

    可视化输入中的重要内容—Occlusion Maps(遮挡贴图)

    激活最大化用于可视化在图像中的模型期望的输出。在另一方面,遮挡部分图,可以帮助我们找到对模型来说那个部分是重要的。

    现在,为了了解遮挡图后的模型是如何工作的,我们想根据制造商对汽车进行分类的模型,如丰田,奥迪等:

    d40d61a5b3fd22b300ceb66f3c7fe188.png

    你能知道是那家生产商制造了上面这辆车吗?很大程度上是不能的,因为放置公司标志的部分在图片里被遮挡了。我们是以分类为目的,所以被遮挡的这部分对我们来说很重要。

    类似地,因为这样的遮挡图的出现,我们遮挡图片的某些部分,然后计算出它属于哪一类的概率。如果概率降低,则意味着图像的被遮挡部分对于该类是重要的。否则,这就是不重要的。

    这里,我们根据图像每个部分的像素值做概率分配,然后将它标准化并生成热图:

    import numpy as np
    from keras.utils import np_utils
    from keras.models import Sequential
    from keras.layers import Dense, Dropout, Flatten, Activation, Conv2D, MaxPooling2D
    from keras.optimizers import Adam
    from keras.callbacks import EarlyStopping, ModelCheckpoint
    from keras.preprocessing.image import ImageDataGenerator
    from keras.activations import relu
    %matplotlib inline
    import matplotlib.pyplot as plt
    def iter_occlusion(image, size=8):
    occlusion = np.full((size * 5, size * 5, 1), [0.5], np.float32)
    occlusion_center = np.full((size, size, 1), [0.5], np.float32)
    occlusion_padding = size * 2
    # print('padding...')
    image_padded = np.pad(image, (
    (occlusion_padding, occlusion_padding), (occlusion_padding, occlusion_padding), (0, 0) ), 'constant', constant_values = 0.0)
    for y in range(occlusion_padding, image.shape[0] + occlusion_padding, size):
    for x in range(occlusion_padding, image.shape[1] + occlusion_padding, size):
    tmp = image_padded.copy()
    tmp[y - occlusion_padding:y + occlusion_center.shape[0] + occlusion_padding, x - occlusion_padding:x + occlusion_center.shape[1] + occlusion_padding]
    = occlusion
    tmp[y:y + occlusion_center.shape[0], x:x + occlusion_center.shape[1]] = occlusion_center
    yield x - occlusion_padding, y - occlusion_padding,
    tmp[occlusion_padding:tmp.shape[0] - occlusion_padding, occlusion_padding:tmp.shape[1] - occlusion_padding]

    上面的代码定义了一个函数iter_occlusion,它返回一个具有不同被遮挡部分的图像。

    现在,让我们导入图像并绘制它:

    from keras.preprocessing.image import load_img
    # load an image from file
    image = load_img('car.jpeg', target_size=(224, 224))
    plt.imshow(image)
    plt.title('ORIGINAL IMAGE')

    1b782f520180a7799637affcd7a492a7.png

    现在,我们将进行下面三个步骤:

    • 预处理原图像
    • 计算有不同遮挡部分的图片的概率
    • 生成热图

    from keras.preprocessing.image import img_to_array
    from keras.applications.vgg16 import preprocess_input
    # convert the image pixels to a numpy array
    image = img_to_array(image)
    # reshape data for the model
    image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
    # prepare the image for the VGG model
    image = preprocess_input(image)
    # predict the probability across all output classes
    yhat = model.predict(image)
    temp = image[0]
    print(temp.shape)
    heatmap = np.zeros((224,224))
    correct_class = np.argmax(yhat)
    for n,(x,y,image) in enumerate(iter_occlusion(temp,14)):
    heatmap[x:x+14,y:y+14] = model.predict(image.reshape((1, image.shape[0], image.shape[1], image.shape[2])))[0][correct_class]
    print(x,y,n,' - ',image.shape)
    heatmap1 = heatmap/heatmap.max()
    plt.imshow(heatmap)

    d5fd521b2259fafa4976c930fd15bda4.png

    这非常有意思。 我们现在将使用标准化的热图概率创建一个掩模并绘制它:

    import http://skimage.io as io
    #creating mask from the standardised heatmap probabilities
    mask = heatmap1 < 0.85
    mask1 = mask *256
    mask = mask.astype(int)
    io.imshow(mask,cmap='gray')

    baf93fae63e1fbe02d46b3a79952b97c.png

    最后,我们将遮挡码强加在输入图像上并绘制:

    import cv2
    #read the image
    image = cv2.imread('car.jpeg')
    image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
    #resize image to appropriate dimensions
    image = cv2.resize(image,(224,224))
    mask = mask.astype('uint8')
    #apply the mask to the image
    final = cv2.bitwise_and(image,image,mask = mask)
    final = cv2.cvtColor(final,cv2.COLOR_BGR2RGB)
    #plot the final image
    plt.imshow(final)

    627b8b5feff48c5564c272b8a72b98ed.png

    你能猜到为什么我们只看到图像的某些部分吗? 这其实是正确的 - 只有输入图像中对其输出类概率有重大贡献的那些部分才是可见的。 简而言之,这就是被遮挡图的全部内容。

    可视化输入特征的贡献—显著性贴图

    显著性图是另一种基于梯度的可视化技术。

    显着图计算每个像素值对模型输出的影响。 这涉及计算输出相对于输入图像的每个像素的梯度。这告诉我们如何根据输入图像像素的微小变化输出类别变化。梯度的所有正值意味着像素值的微小变化将增加输出值:

    这些梯度与图像形状相同(梯度是根据每个像素值计算的),为我们提供了直观的重点。让我们看看如何为任何图像生成显著性图。 首先,我们将使用以下代码段读取输入图像。

    64b97b0d4e015a061ae20d524688c68c.png

    现在,我们将使用VGG16模型为图像生成显著性图:

    # Utility to search for layer index by name.
    # Alternatively we can specify this as -1 since it corresponds to the last layer.
    layer_idx = utils.find_layer_idx(model, 'predictions')
    # Swap softmax with linear
    model.layers[layer_idx].activation = activations.linear
    model = utils.apply_modifications(model)
    #generating saliency map with unguided backprop
    grads1 = visualize_saliency(model, layer_idx,filter_indices=None,seed_input=image)
    #plotting the unguided saliency map
    plt.imshow(grads1,cmap='jet')

    7677c4a3afe23a03747b009808a53f54.png

    我们看到该模型更侧重于狗的面部部分。现在,让我们看看反向传播的结果:

    #generating saliency map with guided backprop
    grads2 = visualize_saliency(model, layer_idx,filter_indices=None,seed_input=image,backprop_modifier='guided')
    #plotting the saliency map as heatmap
    plt.imshow(grads2,cmap='jet')

    5d26d98a4730438c5c0dd801a841ab8a.png

    引导反向传播将所有负梯度截断为0,这意味着仅更新对分类概率具有正影响的像素。

    分类激活图(梯度加权)

    分类激活图也是一种神经网络可视化技术,它基于根据激活图的梯度或它们对输出的贡献来权衡激活图这样的想法。

    以下摘自Grad-CAM论文给出了该技术的要点:

    梯度加权分类激活映射(Grad-CAM),使用任何目标概念的梯度(比如“狗”或甚至是标题的对数),流入最终的卷积层以生成粗略的定位图,突出显示重要区域中的重要区域。用于预测概念的图像。

    从本质上来说,我们采用最后一层卷积层的特征映射,并使用相对于特征映射的输出的梯度对每个滤波器进行加权(乘)。 Grad-CAM涉及以下步骤:

    1.获取最终卷积层的输出要素图。对于VGG16,此功能图的形状为14x14x512; 2.计算输出相对于要素图的梯度 3.将全局平均池化应用于梯度 4.将要素图与相应的池化梯度相乘 我们可以在下面看到输入图像及其对应的分类激活图:

    1b782f520180a7799637affcd7a492a7.png

    现在,我们来给上面的图像生成分类激活图:

    f0558c5817db65fa55cb3a562362030c.png

    可视化过程—分层输出可视化

    CNN的起始层通常寻找像边缘这样的低级特征。随着我们的深入,功能也会发生变化。

    可视化模型的不同层的输出有助于我们看到在相应层突出显示图像的是哪些特征。此步骤对于针对我们的问题微调架构特别重要。为什么?因为我们可以看到哪些图层提供了哪种特征,然后决定我们要在模型中使用哪些图层。

    例如,可视化图层输出可以帮助我们比较神经样式转移问题中不同层的性能。

    让我们看看如何在VGG16模型的不同层获得输出:

    #importing required libraries and functions
    from keras.models import Model
    #defining names of layers from which we will take the output
    layer_names = ['block1_conv1','block2_conv1','block3_conv1','block4_conv2']
    outputs = []
    image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
    #extracting the output and appending to outputs
    for layer_name in layer_names:
    intermediate_layer_model = Model(inputs=model.input,outputs=model.get_layer(layer_name).output)
    intermediate_output = intermediate_layer_model.predict(image)
    outputs.append(intermediate_output)
    #plotting the outputs
    fig,ax = plt.subplots(nrows=4,ncols=5,figsize=(20,20))
    for i in range(4):
    for z in range(5):
    ax[i][z].imshow(outputs[i][0,:,:,z])
    ax[i][z].set_title(layer_names[i])
    ax[i][z].set_xticks([])
    ax[i][z].set_yticks([])
    plt.savefig('layerwise_output.jpg')

    7d810f7e40de340c41a7709a9c5611ad.png

    上图显示了VGG16的每一层从图像中提取的不同特征(模块5除外)。我们可以看到起始层对应于边缘等低级特征,而后面的层则看到汽车的车顶,排气等特征。

    结语

    可视化永远不会让我感到惊讶。有多种方法可以理解技术的工作原理,但可视化可以使它变得更加有趣。以下是您应该查看的几个资源:

    • 神经网络中的特征提取过程是一个活跃的研究领域,并导致了Tensorspace和Activation Atlases等令人敬畏的工具的开发。
    • TensorSpace也是一种支持多种模型格式的神经网络可视化工具。它允许您加载模型并以交互方式对其进行可视化。TensorSpace还有一个操作平台,可以使用多种架构进行可视化,您可以随意使用。

    如果您对本文有任何疑问或反馈,请与我们联系。 我很乐意参与讨论!

    展开全文
  • 在大部分人看来,卷积神经网络是一种黑盒技术,通过理论推导,以及梯度传播,不断逼近局部最优解。这也导致人们对于神经网络研究进展的缓慢,因为这种黑盒模型无法给出研究人员进行改进的思路。所幸的是,近几年来...
  • 图像卷积:利用2D卷积扫图像,主要是为了实现Blur,高斯滤波本质也是通过卷积来实现的,只不过他的卷积核内参数是符合高斯分布的。 图像二值:图像二值之后为黑白图像,相当于mask掩模,用于挖出图像中的非...
  • 卷积神经网络

    2019-07-02 10:10:18
    均值:把输入数据各个维度都中心到0 归一:幅度归一到同样的范围 PCA/白化:用PCA降维,白化是对数据每个特征轴上的幅度归一 卷积计算层/CONV layer 局部关联:每个神经元看作一个filter 窗口(receptive...
  • 卷积卷积的性质与应用

    万次阅读 2015-12-04 12:01:28
    卷积有一种模糊(粗粒度)的效果,这种模糊(忽视掉一些不必要的细节,在加上 maxpooling 的存在,又会捕捉最显著的特征,这种忽略次要目标,突出重要目标)。也就是 CNN 天然具有的性质,当其应用在 Text(文本...
  • ↑ 点击蓝字关注极市平台作者丨VincentLee来源丨晓飞的算法工程笔记编辑丨极市平台极市导读这篇论文提出用类特定控制门CSG来引导网络学习类特定的卷积核,并用正则方法来稀疏CSG矩阵。CSG的稀疏性能够引导卷积核...
  • 论文提出类特定控制门CSG来引导网络学习类特定的卷积核,并且加入正则方法来稀疏CSG矩阵,进一步保证类特定性。从实验结果来看,CSG的稀疏性能够引导卷积核与类别的强关联,在卷积核层面产生高度类相关的特征...
  • 文章目录1 Keras卷积层1.1 Conv2D1.2 SeparableConv2D1.3 Conv2DTranspose1.3.1 去卷积的例子11.3.2 去卷积的例子22 Keras参数初始2.1 正态分布2.2 均匀分布2.3 截尾正态分布2.4 常数2.5 Xavier/
  • 其实,让我们解释一个层数较少的简单神经网络工作原理并不难,但是当我们将计算机视觉项目中的神经网络层数增加到1000层时,它的可解释性就非常差了。 现实情况是,我们的用户或者终端需要可解释性——他们想知道...
  • 数据输入层/ Input layer卷积计算层/ CONV layer激励层 / ReLU layer池化层 / Pooling layer全连接层 / FC layer输入层(Input layer)输入数据,通常会作一些数据处理,例如:均值:把输入数据各个维度都中心到0...
  • 数据输入层/ Input layer卷积计算层/ CONV layer激励层 / ReLU layer池化层 / Pooling layer全连接层 / FC layer输入层(Input layer)输入数据,通常会作一些数据处理,例如:均值:把输入数据各个维度都中心到0...
  • 基于小波变换和卷积神经网络去除条纹噪声

    千次阅读 热门讨论 2020-03-24 21:21:53
    2.提出了一种directional regularizer(我在这里叫做定向正则,是一个损失函数),能够避免模型产生不规则的条纹,以及将条纹噪声和图像中的细节更准确的分开。 3.利用小波分解将图像转换成四个小波子带。每个子带...
  • 【深度学习】多通道图像卷积过程及计算方式

    万次阅读 多人点赞 2018-10-15 21:42:50
    之前,有写了一篇博文,【深度学习入门】——亲手实现图像卷积操作介绍卷积的相应知识,但那篇文章更多的是以滤波器的角度讲解卷积。但实际上是神经网络中该博文内容并不适应。 之前的文章为了便于演示,针对的是...
  • 3*3卷积核 5*5卷积核到底有多大区别

    万次阅读 2017-12-12 13:38:55
    为了比较3*3卷积核 和 5*5卷积核在性能上到底有多大区别设计了两个网络进行对比, 1.两个3*3的卷积核,2个池化层,2个全连接层 2.两个5*5的卷积核,2个池化层,2个全连接层 两个网络的收敛标准,权重的初始...
  • 卷积神经网络caffe

    2017-07-05 16:40:53
    卷积神经网络caffe 卷积神经网络是层级结构,但层的功能和形式做了变化,层包含: 数据输入层 input layer卷积计算层 conv layerRelu激励层 Relu layer池化层 ...均值: 把输入数据各个维度都中心到0 归一
  • 卷积神经网络基础

    2020-06-12 22:01:25
    卷积神经网络的层级结构 数据输入层/ Input layer 卷积计算层/ CONV layer ...归一:幅度归一到同样的范围,如下所示,即减少各维度数据取值范围的差异而带来的干扰,比如,我们有两个维度的特征A和B,A范围是0
  • CNN卷积神经网络

    2019-08-14 11:04:37
    1.卷积神经网络之层级结构 ...最左边是数据输入层,对数据做一些处理,比如均值(把输入数据各个维度都中心化为0,避免数据过多偏差,影响训练效果)、归一(把所有的数据都归一到同样的范围)、...
  • 在碎片阅读充斥眼球的时代,越来越少的人会关注每篇论文背后的探索和思考。在这个栏目里,你会快速 get 每篇精选论文的亮点和痛点,时刻紧跟 AI 前沿成果。点击本文底部的「阅读原文」即刻加入社区,查看更多...
  • 卷积过程类似于一个模板图像上寻找与它相似的区域,与卷积核模式越相似,激活值越高,从而实现特征提取 AlexNet 卷积核可视,发现卷积核学习到的是边缘,条纹,色彩这些细节模式 卷积维度:一般情况下,卷积核在...
  • 无法深入理解的事物,就不能更好地发掘与应用0.引子为什么要写这个文章?之前关注过笔者的朋友,应该知道笔者目前是一名深度学习算法工程师,主要的工作与研究方向是CV。最近在做目标检测任务的算法开发与优化,在...
  • 寻找适合的轮廓过滤器:计算机根据训练图片及其类别,自动寻找合适的轮廓过滤器,再使用该过滤器寻找图像轮廓用于判断新图片所属类别 最小输出损失函数的过程,也是寻找合适w的过程,即寻找合适的过滤器 1.3...
  • 无监督学习极大的发挥了神经网络的学习能力——摆脱人为的帮助,有望通过自动地学习特征,实现智能的应用。01 使用全连接神经网络来处理降噪上一篇文章介绍了一个用全连接神经网络去噪的案例。实现了把这样的含有...

空空如也

空空如也

1 2 3 4 5 ... 18
收藏数 350
精华内容 140
关键字:

去卷积化