精华内容
下载资源
问答
  • 利用MATLAB里的反卷积和反池化实现 王同学,想请你帮我思考一下做个东西:不知道你看过那个visualizing and understanding cnn那篇文章没有。你可以看到,他的可视化是通过上采样以及反卷积把某层的冲激响应映射会...
  • [CNN] 卷积、反卷积、池化、反池化

    万次阅读 多人点赞 2018-11-28 17:03:55
    之前一直太忙,没时间整理,这两天抽出点时间整理一下卷积、反卷积、池化、反池化的内容。 一、卷积 1、卷积的简单定义 卷积神经网络中的卷积操作可以看做是输入和卷积核的内积运算。其运算过程非常容易理解,...

    之前一直太忙,没时间整理,这两天抽出点时间整理一下卷积、反卷积、池化、反池化的内容,也希望自己对一些比较模糊的地方可以理解的更加清晰。

    一、卷积

    1、卷积的简单定义

    卷积神经网络中的卷积操作可以看做是输入和卷积核的内积运算。其运算过程非常容易理解,下面有举例。

    2、举例解释

    (1)为了方便直接解释,我们首先以一个通道(若是彩图,则有RGB的颜色,所以是三个通道)为例进行讲解,首先明确概念:

    1) 输入是一个5*5的图片,其像素值如下:
    [ 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 1 1 0 0 1 1 0 0 ] \begin{bmatrix} 1 & 1 &1 & 0 & 0\\ 0 & 1 & 1 &1 & 0\\ 0 & 0 & 1 & 1 & 1\\ 0 & 0 & 1 & 1 &0 \\ 0 &1 &1 & 0 &0 \end{bmatrix} 1000011001111110111000100
    2)卷积核(kernel)是需要训练的参数,这里为了讲解卷积运算的操作,所以最开始我们假设卷积核的值如下:
    [ 1 0 1 0 1 0 1 0 1 ] \begin{bmatrix} 1 & 0 &1 \\ 0 & 1 & 0 \\ 1 & 0 & 1 \\ \end{bmatrix} 101010101
    3)通过窗口和卷积核的内积操作得到的结果叫做feature map。

    (2)如下图所示(对应的是上面提到的数据),我们在输入图片上框出一个和卷积核相同大小的区域,基于此计算子区域和卷积核对应元素乘积之和:
    注: 本节图形来自对FCN及反卷积的理解

    1 ∗ 1 + 1 ∗ 0 + 1 ∗ 1 + 0 ∗ 0 + 1 ∗ 1 + 1 ∗ 0 + 0 ∗ 1 + 0 ∗ 0 + 1 ∗ 1 = 4 1*1 + 1*0+1*1+0*0+1*1+1*0+0*1+0*0+1*1=4 11+10+11+00+11+10+01+00+11=4
    所以feature map的第一个元素值为4。

    (3)接着计算第二个子区域和卷积核的对应元素乘积之和,如下图所示:

    1 ∗ 1 + 1 ∗ 0 + 0 ∗ 1 + 1 ∗ 0 + 1 ∗ 1 + 1 ∗ 0 + 0 ∗ 1 + 1 ∗ 0 + 1 ∗ 1 = 3 1*1+1*0+0*1+1*0+1*1+1*0+0*1+1*0+1*1=3 11+10+01+10+11+10+01+10+11=3
    所以feature map的第二个元素值为3。

    (4)接着计算第三个子区域和卷积核的对应元素乘积之和,如下图所示:

    1 ∗ 1 + 0 ∗ 0 + 0 ∗ 1 + 1 ∗ 0 + 1 ∗ 1 + 0 ∗ 0 + 1 ∗ 1 + 1 ∗ 0 + 1 ∗ 1 = 4 1*1+0*0+0*1+1*0+1*1+0*0+1*1+1*0+1*1=4 11+00+01+10+11+00+11+10+11=4
    所以feature map的第三个元素值为4。

    (5)接着计算第四个子区域和卷积核的对应元素乘积之和,如下图所示:

    0 ∗ 1 + 1 ∗ 0 + 1 ∗ 1 + 0 ∗ 0 + 0 ∗ 1 + 1 ∗ 0 + 0 ∗ 1 + 0 ∗ 0 + 1 ∗ 1 = 2 0*1+1*0+1*1+0*0+0*1+1*0+0*1+0*0+1*1=2 01+10+11+00+01+10+01+00+11=2
    所以feature map的第四个元素值为2。

    (6)以此类推,不断执行,最后得到的feature map如下:

    [ 4 3 4 2 4 3 2 3 4 ] \begin{bmatrix} 4 & 3&4 \\ 2 & 4 & 3 \\ 2& 3 & 4 \\ \end{bmatrix} 422343434
    (7)下面的动图可以连贯的展示上面的过程,可以帮助更直观的理解:

    3、多个输入通道

    若输入含有多个通道,则对于某个卷积核,分别对每个通道求feature map后将对应位置相加得到最终的feature map,如下图所示:

    4、多个卷积核

    若有多个卷积核,则对应多个feature map,也就是下一个输入层有多个通道。如下图所示:

    5、步数的大小

    上述展示的步长为1的情况,若步长为2,则滑动窗口每2步产生一个,如下图所示:

    输入大小为 5 ∗ 5 5*5 55,卷积核的大小为 3 ∗ 3 3*3 33,第一个滑动窗口为红色部分,第二个滑动窗口为绿色部分,第三个滑动窗口为紫色部分,第四个滑动窗口为蓝色部分,所以最后的feature map的大小为 2 ∗ 2 2*2 22

    若假设输入大小是 n ∗ n n*n nn,卷积核的大小是 f ∗ f f*f ff,步长是 s s s,则最后的feature map的大小为 o ∗ o o*o oo,其中 o o o如下:
    o = ⌊ n − f s ⌋ + 1 o=\left \lfloor \frac{n-f}{s} \right \rfloor+1 o=snf+1

    6、三种模式:Full,Same和Valid

    如上图所示,3种模式的主要区别是从哪部分边缘开始滑动窗口卷积操作,区别如下:

    Full模式:第一个窗口只包含1个输入的元素,即从卷积核(fileter)和输入刚相交开始做卷积。没有元素的部分做补0操作。
    Valid模式:卷积核和输入完全相交开始做卷积,这种模式不需要补0。
    Same模式:当卷积核的中心C和输入开始相交时做卷积。没有元素的部分做补0操作。

    在之前讲到的内容使用的是Valid的模式。

    6、Full,Same和Valid下的feature map的大小

    (1)若输入大小是 n ∗ n n*n nn,卷积核大小为 f ∗ f f*f ff,步长为 s s s,若采用Full或Same模式,假设填充大小为 p p p p p p为一边填充的大小,举例:如果输出 5 ∗ 5 5*5 55,卷积核 3 ∗ 3 3*3 33,采用Full模式,则 p = 2 p=2 p=2),则feature map的大小是: ( ⌊ n + 2 p − f s ⌋ + 1 ) ∗ ( ⌊ n + 2 p − f s ⌋ + 1 ) (\left \lfloor \frac{n+2p-f}{s} \right \rfloor+1)*(\left \lfloor \frac{n+2p-f}{s} \right \rfloor+1) (sn+2pf+1)(sn+2pf+1)
    (2)若输入大小是 n ∗ n n*n nn,卷积核大小为 f ∗ f f*f ff,步长为 s s s,若不补0,即Valid模式下,feature map的大小为: ( ⌊ n − f s ⌋ + 1 ) ∗ ( ⌊ n − f s ⌋ + 1 ) (\left \lfloor \frac{n-f}{s} \right \rfloor+1)*(\left \lfloor \frac{n-f}{s} \right \rfloor+1) (snf+1)(snf+1)
    (3)Same模式下,feature map的维度和输入维度相同。

    注意:卷积核大小一般为奇数,原因如下:

    ①当卷积核为偶数时,p不为整数,假设是Same模式,若想使得卷积之后的维度和卷积之前的维度相同,则需要对图像进行不对称填充,较复杂。
    ②当kernel为奇数维时,有中心像素点,便于定位卷积核。

    5、卷积特点

    (1)局部视野
    卷积操作在运算的过程中,一次只考虑一个窗口的大小,因此其具有局部视野的特点,局部性主要体现在窗口的卷积核的大小。
    (2)参数减少
    比如,在上述输入为 5 ∗ 5 5*5 55,卷积核为 3 ∗ 3 3*3 33,输出为 3 ∗ 3 3*3 33的例子中,如果是使用NN,则其参数个数为 ( 5 ∗ 5 ) ∗ ( 3 ∗ 3 ) (5*5)*(3*3) (55)(33)。而在CNN中,其参数个数为卷积核的大小 3 ∗ 3 3*3 33
    这只是简单的情况,若输入非常大,卷积核通常不是很大,此时参数量的差距将会非常明显。
    (3)权重共享
    从上面的讲解可以看到,对一个输入为 5 ∗ 5 5*5 55,卷积核为 3 ∗ 3 3*3 33的情况下,对于每一个滑动窗口,使用的都是同一个卷积核,所以其参数共享。
    (4)多个卷积核可以发现不同角度的特征,多个卷积层可以捕捉更全局的特征(处于卷积网络更深的层或者能够的单元,他们的接受域要比处在浅层的单元的接受域更大)。详见下图(图片来源:花书):

    可以看到, h 2 h_2 h2的接受域是 x 1 , x 2 , x 3 x_1, x_2,x_3 x1,x2,x3,而 g 3 g_3 g3的接受域是 x 1 , x 2 , x 3 , x 4 , x 5 x_1, x_2,x_3,x_4,x_5 x1,x2,x3,x4,x5

    二、反卷积

    为了更深度的了解反卷积,现在还来看下卷积的数学操作。

    1、卷积的数学操作
    上述是比较直观的图形展示的例子,如果把卷积操作写成矩阵相乘,则对于 4 ∗ 4 4*4 44的输入和 3 ∗ 3 3*3 33的卷积核的结果如下:

    [ c 11 c 12 c 13 0 c 21 c 22 c 23 0 c 31 c 32 c 33 0 0 0 0 0 0 c 11 c 12 c 13 0 c 21 c 22 c 23 0 c 31 c 32 c 33 0 0 0 0 0 0 0 0 c 11 c 12 c 13 0 c 21 c 22 c 23 0 c 31 c 32 c 33 0 0 0 0 0 0 c 11 c 12 c 13 0 c 21 c 22 c 23 0 c 31 c 32 c 33 ] [ x 11 x 12 x 13 x 14 x 21 x 22 x 23 x 24 x 31 x 32 x 33 x 34 x 41 x 42 x 43 x 44 ] = [ y 11 y 12 y 21 y 22 ] \begin{bmatrix} c_{11} & c_{12} &c_{13} & 0 & c_{21} & c_{22} & c_{23} & 0 & c_{31} & c_{32} & c_{33} & 0 & 0 &0 & 0 & 0\\ 0 & c_{11} & c_{12} &c_{13} & 0 & c_{21} & c_{22} & c_{23}& 0 & c_{31} & c_{32} & c_{33} & 0 & 0 &0 & 0 \\ 0 & 0 &0 & 0 & c_{11} & c_{12} &c_{13} & 0 & c_{21} & c_{22} & c_{23}& 0 & c_{31} & c_{32} & c_{33} & 0 \\ 0 & 0 &0 & 0 & 0 & c_{11} & c_{12} &c_{13}& 0 & c_{21} & c_{22} & c_{23} & 0 & c_{31} & c_{32} & c_{33} \end{bmatrix}\begin{bmatrix} x_{11}\\ x_{12}\\ x_{13}\\ x_{14}\\ x_{21}\\ x_{22}\\ x_{23}\\ x_{24}\\ x_{31}\\ x_{32}\\ x_{33}\\ x_{34}\\ x_{41}\\ x_{42}\\ x_{43}\\ x_{44} \end{bmatrix}=\begin{bmatrix} y_{11}\\ y_{12}\\ y_{21}\\ y_{22} \end{bmatrix} c11000c12c1100c13c12000c1300c210c110c22c21c12c11c23c22c13c120c230c13c310c210c32c31c22c21c33c32c23c220c330c2300c31000c32c3100c33c32000c33x11x12x13x14x21x22x23x24x31x32x33x34x41x42x43x44=y11y12y21y22
    最后得到一个 4 ∗ 1 4*1 41的矩阵,可以reshape成 2 ∗ 2 2*2 22的矩阵,便是最后卷积的结果。

    2、反卷积的数学操作
    反卷积的操作就相当于对上述 y y y左乘 c T c^T cT,维度如下: c T c^T cT的维度是 16 ∗ 4 16*4 164 y y y的维度是 4 ∗ 1 4*1 41,故 c T y c^Ty cTy的维度是 16 ∗ 1 16*1 161,可以将其reshape成 4 ∗ 4 4*4 44便变回了原来的维度。

    3、反卷积和卷积的关系
    反卷积就是特殊的卷积,是使用Full模式的卷积操作,便可以将输入还原,在tensorFlow中,反卷积的操作也是卷积操作。
    注意:
    在卷积操作中: c x = y cx=y cx=y
    在反卷积操作中: c T y = x c^Ty=x cTy=x,这里并不是严格意义上的等于,而只是维度的相等,因为 c c c c T c^T cT都是训练,并不是直接取转置。

    三、池化

    池化的定义比较简单,最直观的作用便是降维,常见的池化有最大池化、平均池化和随机池化。
    池化层不需要训练参数。

    1、三种池化示意图

    最大池化是对局部的值取最大;平均池化是对局部的值取平均;随机池化是根据概率对局部的值进行采样,采样结果便是池化结果。概念非常容易理解,其示意图如下所示:

    2、三种池化的意义

    (1)最大池化可以获取局部信息,可以更好保留纹理上的特征。如果不用观察物体在图片中的具体位置,只关心其是否出现,则使用最大池化效果比较好。
    (2)平均池化往往能保留整体数据的特征,能凸出背景的信息。
    (3)随机池化中元素值大的被选中的概率也大,但不是像最大池化总是取最大值。随机池化一方面最大化地保证了Max值的取值,一方面又确保了不会完全是max值起作用,造成过度失真。除此之外,其可以在一定程度上避免过拟合。

    3、重叠池化

    一般在CNN中使用的池化都是不重叠的,但是池化也可以重叠,重叠池化和卷积操作类似,可以定义步长等参数,其和卷积的不同在于:卷积操作将窗口元素和卷积核求内积,而池化操作求最大值/平均值等,窗口的滑动等原理完全相同。

    四、反池化

    池化操作中最常见的最大池化和平均池化,因此最常见的反池化操作有反最大池化和反平均池化,其示意图如下:

    反最大池化需要记录池化时最大值的位置,反平均池化不需要此过程。

    五、参考文章:

    [1] A guide to convolution arithmetic for deep learning
    [2] 深度学习(书)
    [3] deeplearning(ng)
    [4] https://github.com/vdumoulin/conv_arithmetic
    [5] 深度理解反卷积操作

    展开全文
  •   前面两篇笔记写了卷积神经网络的两个部件,即卷积层与反卷积层,这篇笔记写池化层与反池化层。池化是一种很重要的下采样方法,它像水池一样汇集一个小区域加粗样式内的值,并总结浓缩成一个值输出,常用的有最大...

    前言


      前面两篇笔记写了卷积神经网络的两个部件,即卷积层与反卷积层,这篇笔记写池化层与反池化层。池化是一种很重要的下采样方法,它像水池一样汇集一个小区域内的值,并总结浓缩成一个值输出,常用的有最大池化Maxpooling——选择最大值输出,和平均池化Avepooling——取平均值作为输出。反池化,是一种和转置卷积类似的上采样方法,在分割任务中会用到。分组卷积是一种使模型轻量化的方法,本笔记也将浅浅的记录。本笔记的知识框架主要来源于深度之眼,并依此作了内容的丰富拓展,拓展内容主要源自对torch文档的翻译,对孙玉林等著的PyTorch深度学习入门与实战的参考和自己的粗浅理解,所用数据来源于网络。发现有人在其他平台照搬笔者笔记,不仅不注明出处,有甚者更将其作为收费文章,因此笔者将在文中任意位置插入识别标志。

       笔记是笔者根据自己理解一字一字打上去的,还要到处找合适的图片,有时为了便于理解还要修图,原创不易,转载请注明出处,文中笔者哪怕是引图也注明了出处的

      结果可视化见:深度之眼Pytorch打卡(十):Pytorch数据预处理——数据统一与数据增强(上)

      卷积操作见:深度之眼Pytorch打卡(十四):Pytorch卷积神经网络部件——卷积操作与卷积层、转置卷积操作与转置卷积层(反卷积)(对卷积转置卷积细致动图分析)

      转置卷积操作见:深度之眼Pytorch打卡(十五):Pytorch卷积神经网络部件——转置卷积操作与转置卷积层(对转置卷积操作全网最细致分析,转置卷积的stride与padding,转置与反卷积名称论证)


    池化与池化层


    • 池化操作

       池化(pooling)是一种下采样方法,其能在保持数据空间特征的同时减少数据大小1,进而减少冗余信息,降低训练时的运算量。最常用的主要包括最大池化和平均池化,即对区域内的值进行总结的方法是取最大值和取平均值。池化没有参数,故一般不算入卷积神经网络层数,它常常放在连续的卷积操作中间,卷积-池化-卷积-池化是较为典型的结构。

       最大池化:

      用区域内的最大值(响应)来代表该区域的所有值(响应),移位过程有点像卷积,但它是非线性运算,并且相邻两次移动到的区域一般不重叠,即stride=kernel_size,操作过程如图1所示,其摘自国外的文章:Convolution Neural Networkkernel_size=2,stride=2是最常用的池化超参数

    最大池化Maxpooling

    图1.Maxpooling过程

       平均池化:

      用区域内的平均值(响应)来代表该区域的所有值(响应),操作过程如图2所示,其摘自国外的文章:Convolution Neural Network。平均池化是线性运算

    平均池化Avgpooling

    图2.Avgpooling过程
    • Pytorch池化层

      最大池化层:

      Pytorch的最大池化层有三个,即nn.MaxPool1d()、nn.MaxPool2d()、nn.MaxPool2d()。这里只单独学习最最常用的nn.MaxPool2d(),其他的都类似或者相同。

      MaxPool2d()

    CLASS torch.nn.MaxPool2d(kernel_size: Union[int, Tuple[int, ...]], 
                             stride: Union[int, Tuple[int, ...], None] = None, 
                             padding: Union[int, Tuple[int, ...]] = 0, 
                             dilation: Union[int, Tuple[int, ...]] = 1, 
                             return_indices: bool = False, 
                             ceil_mode: bool = False)
                           
    # (CSDN意疏原创笔记:https://blog.csdn.net/sinat_35907936/article/details/107833112)
    

      return_indices: 如果为True,该函数类除了返回池化结果外,还会返回输入中每个最大值所在位置的索引(indices。 在用MaxUnpool2d做上采样(反池化)时需要该参数。

      ceil_mode: 输出尺寸取整方式,默认向下取整(floor),当ceil_modeTrue时向上取整。如输入尺寸5x5,取stride=2,kernel_size=2,则默认情况下输出尺寸为2x2ceil_modeTrue时输出尺寸为3x3

      平均池化层:

      Pytorch的平均池化层也有三个,即nn.AvgPool1d()、nn.AvgPool2d()、nn.AvgPool2d()。这里也只单独学习最最常用的nn.AvgPool2d(),其他的都类似或者相同。

      AvgPool2d()

    CLASS torch.nn.AvgPool2d(kernel_size: Union[int, Tuple[int, int]], 
                             stride: Union[int, Tuple[int, int], None] = None, 
                             padding: Union[int, Tuple[int, int]] = 0, 
                             ceil_mode: bool = False, 
                             count_include_pad: bool = True, 
                             divisor_override: bool = None)
                           
     #(CSDN意疏原创笔记:https://blog.csdn.net/sinat_35907936/article/details/107833112)
    

      count_include_pad: 计算均值时是否把padding的像素值算在内。
      divisor_override: 除法因子更改,如果设置了该值,则在求均值时不再除以kernel覆盖的像素个数,而是除以该值。

      池化层使用

      代码:transform_inverse()函数定义见此文,池化过程不改变通道数。

    import torch
    from PIL import Image
    import torch.nn as nn
    import matplotlib.pyplot as plt
    import torchvision.transforms as transforms
    from tools.transform_inverse import transform_inverse
    
    MaxPool_layer = nn.MaxPool2d((2, 2), 2)
    AvgPool_layer = nn.AvgPool2d((2, 2), 2)
    
    # 4个元素,除法因子应该为4,此处改为8,输出会黯淡一倍
    AvgPool_layer1 = nn.AvgPool2d((2, 2), 2, divisor_override=8)
    
    pil_img = Image.open('data/lenna.jpg').convert('RGB')
    img = transforms.ToTensor()(pil_img)
    print(img.size())
    c = img.size()[0]
    h = img.size()[1]
    w = img.size()[2]
    img = torch.reshape(img, [1, c, h, w])
    
    MaxPool_out = MaxPool_layer(img)
    AvgPool_out = AvgPool_layer(img)
    AvgPool_out1 = AvgPool_layer1(img)
    
    MaxPool_out = torch.squeeze(MaxPool_out)
    AvgPool_out = torch.squeeze(AvgPool_out)
    AvgPool_out1 = torch.squeeze(AvgPool_out1)
    
    print(MaxPool_out.size())
    MaxPool_pil = transform_inverse(MaxPool_out, None)
    AvgPool_pil = transform_inverse(AvgPool_out, None)
    AvgPool_pil1 = transform_inverse(AvgPool_out1, None)
    
    plt.figure(0)
    ax = plt.subplot(2, 2, 1)
    ax.set_title('input img')
    ax.imshow(pil_img)
    ax = plt.subplot(2, 2, 2)
    ax.set_title('MaxPool_out img')
    ax.imshow(MaxPool_pil)
    ax = plt.subplot(2, 2, 3)
    ax.set_title('Avgpool_out img')
    ax.imshow(AvgPool_pil)
    ax = plt.subplot(2, 2, 4)
    ax.set_title('AvgPool_out with divisor_override=8')
    ax.imshow(AvgPool_pil1)
    plt.show()
    
    
     #(CSDN意疏原创笔记:https://blog.csdn.net/sinat_35907936/article/details/107833112)
    

      结果:用kernel_size = 2,stride = 2的池化层,可以将输入尺寸缩减一半,但是大部分的信息都没有丢失,如图3所示。所以池化操作可以减少冗余,进而减小后续的计算量。平均池化,可以通过修改除法因子来修改池化结果,除法因子是根据实际情况的需要的修改的,一般保持默认值。

    torch.Size([3, 440, 440])
    torch.Size([3, 220, 220])
    

    最大池化与平均池化作用结果

    图3.最大池化与平均池化作用结果

    反池化与反池化层


    • 反池化操作

      反池化是一种上采样技术,常用在图像分割任务中。如图4,就是反池化在经典的编码-解码图像分割网络中,与转置卷积共同作用,进行上采样的图示,图源

    反池化在图像分割任务中的应用

    图4.反池化在图像分割任务中的应用
      

      最大池化的反池化。在进行最大池化时,记录下输入的最大值所在位置的索引。在进行反池化时,将输入值根据其所在位置分别放到索引指示的地方,其他位置补零,流程如图5所示,图源。可以看出,两者是一个对称的过程,即池化输入尺寸等于反池化输出尺寸,池化输出尺寸等于反池化输入尺寸,正是应为这样,索引才能对应上。

    最大池化与最大反池化过程

    图5.最大池化与最大反池化过程
    • 反池化层

      MaxUnpool2d()

    CLASS torch.nn.MaxUnpool2d(kernel_size: Union[int, Tuple[int, int]], 
                               stride: Union[int, Tuple[int, int], None] = None, 
                               padding: Union[int, Tuple[int, int]] = 0)
    

      stride: 笔者觉得官方文档的解释有问题,以下是笔者理解:输入的一个元素在输出中对应区域的宽高,如stride=2,则表示MaxUnpool2d输入的一个元素,在输出中对应2*2的一个区域。一般取stride=kernel_size
      padding: 笔者觉得官方文档的解释有问题,以下是笔者理解:输入计算尺寸被缩减的值。如输入尺寸是3*3,若padding=1,则表示输入计算尺寸被缩减到(3-1)*(3-1),即2*2,若此时stride=2,则可得输出尺寸是4*4。因为并且索引必须与输入同尺寸,即3*3,所以最后输出就是4*4的张量中有9个点有值,其他均为零。如下代码所示。

      代码:

    import torch
    import torch.nn as nn
    
    MaxUnpool_layer = nn.MaxUnpool2d((2, 2), 2, padding=0)
    MaxUnpool_layer1 = nn.MaxUnpool2d((2, 2), 2, padding=1)
    
    In = torch.randn(1, 1, 3, 3)
    print(In)
    idx = torch.tensor([[0, 5, 3],
                       [8, 6, 11],
                        [12, 13, 14]])   # 4*4的张量被拉成一维张量后的序号
    print(idx)
    idx = torch.reshape(idx, [1, 1, 3, 3])
    MaxunPool_out = MaxUnpool_layer(In, indices=idx)
    MaxunPool_out1 = MaxUnpool_layer1(In, indices=idx)
    print(MaxunPool_out)
    print(MaxunPool_out1)
    

      结果:

    
    # input
    tensor([[[[ 2.0394, -0.0362,  0.0612],
              [-0.3057, -0.3779,  0.2984],
              [-0.4500,  1.2419,  0.1124]]]])
    
    # indices
    tensor([[ 0,  5,  3],
            [ 8,  6, 11],
            [12, 13, 14]])
    
    # padding=0,输出6*6的张量
    
    tensor([[[[ 2.0394,  0.0000,  0.0000,  0.0612,  0.0000, -0.0362],
              [-0.3779,  0.0000, -0.3057,  0.0000,  0.0000,  0.2984],
              [-0.4500,  1.2419,  0.1124,  0.0000,  0.0000,  0.0000],
              [ 0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
              [ 0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
              [ 0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000]]]])
              
    # padding=1,输出4*4的张量          
    tensor([[[[ 2.0394,  0.0000,  0.0000,  0.0612],
              [ 0.0000, -0.0362, -0.3779,  0.0000],
              [-0.3057,  0.0000,  0.0000,  0.2984],
              [-0.4500,  1.2419,  0.1124,  0.0000]]]])
    

      MaxPoolMaxUnPool配合使用,此时MaxUnPool不要用Padding,否则会报如下错误:RuntimeError: Found an invalid max index。

    MaxPool_out, idx1 = MaxPool_layer(In)
    MaxunPool_out = MaxUnpool_layer(MaxPool_out, indices=idx1)
    

    其他层


    • 非线性激活函数层

      很多非线性激活函数在这篇笔记中已经梳理,此处不赘述。


    参考


    1. https://yjjo.tistory.com/8 ↩︎

    展开全文
  • 1.2 池化的分类1.3 池化的特点1.3 池化的意义1.4 其它池化方式1.5 池化和卷积的比较1.6 卷积和池化的组合使用二: 反池化2.1 反平均池化2.2 反最大池化 一、池化 1.1 什么是池化?      ...


    一、池化

    1.1 什么是池化?

    在这里插入图片描述
           pooling的结果是使得数据特征减少,参数减少,加快计算速度。但pooling的目的并不仅在于此。pooling目的是为了保持某种不变性(旋转、平移、伸缩等)

    1.2 池化的分类

    (1)mean-pooling(对领域内特征点只求平均值)
    在这里插入图片描述
    (2)max-pooling(对领域内特征点取最大值)

    在这里插入图片描述

    1.3 池化的特点

           mean-pooling能更多的保留图像的背景信息,更加关注背景,一般使用在网络结尾。
           max-pooling能更多的保留图像的纹理信息,更加关注前景,一般使用在网络层中。

    1.3 池化的意义

    (1)池化就是把某一区域当作一个水池,然后,挑出这个水池中的代表性特征,平均值或者是最大值,即mean-pooling 和max-pooling。

    (2)对输入的特征图进行压缩,方便使特征图变小, 简化网络计算复杂度;一方面进行特征压缩,提取主要特征。

    (3)图像具有一种“静态性”的属性,这也就意味着在一个图像区域有用的特征极有可能在另一个区域同样适用。因此,为了描述大的图像,对不同位置的特征进行聚合统计,例如,人们可以计算图像一个区域上的某个特定特征的平均值(或最大值)来代表这个区域的特征。

    1.4 其它池化方式

    (1)中值池化
           与中值滤波特别相似,但是用的非常少,中值池化也具有学习边缘和纹理结构的特性,抗噪声能力比较强。

    (2)重叠池化
           相对于传统的no-overlapping pooling,采用Overlapping Pooling不仅可以提升预测精度,同时重叠池化使特征丢失的更严重。一定程度上可以减缓过拟合。

    (3)全局池化
           Global Pooling就是池化窗口的大小=整张特征图的大小。这样,每个WXHXC的特征图输入就会被转化为1X1XC的输出,也等同于每个位置权重都为1/(WXH)的全连接层操作。

    (4)组合池化
           组合池化则是同时利用最大值池化与均值池化两种的优势而引申的一种池化策略。常见组合策略有两种:Cat与Add。常常被当做分类任务的一个trick,其作用就是丰富特征层,max pool更关注重要的局部特征,而average pooling更关注全局特征。

    (5)空间金字塔池化
    在这里插入图片描述
           将不同深度的特征图拼到一起再进行输出。这样全局特征和局部特征就都拿到了。输入大小任意,输出大小固定。

    (6)随机池化
    在这里插入图片描述
           Stochastic pooling是一种 简单有效的正则化CNN的方法,能够降低max pooling的过拟合现象,提高泛化能力。对于pooling层的输入,根据输入的多项式分布随机选择一个值作为输出。训练阶段和测试阶段的操作略有不同。

    训练阶段:

    1. 前向传播:先将池化窗口中的元素全部除以它们的和,得到概率矩阵;再按照概率随机选中的方格的值,作为该区域池化后的值。
    2. 反向传播:求导时,只需保留前向传播中已经被选中节点的位置的值,其它值都为0,类似max-pooling的反向传播。

    测试阶段:
           在测试时也使用Stochastic Pooling会对预测值引入噪音,降低性能。取而代之的是使用概率矩阵加权平均。比使用Average Pooling表现要好一些。在平均意义上,与Average Pooling近似,在局部意义上,服从Max Pooling准则。

    1.5 池化和卷积的比较

    (1)池化层是没有超参,如果都用卷积的话,参数量会比较大的,建议使用池化层,池化层不增加参数量。
    (2)卷积更多的是去做一些线性变换,而池化层,就单纯的相当于resize了输出的feature map。
    (3)卷积之后数据结构会发生变化,但是池化不会。

    1.6 卷积和池化的组合使用

    在这里插入图片描述
           连续卷积或池化的本质就是对图像的特征继续提取特征。从特征提取特征,会获得图像更高维度的特征,得到的信息更加抽象。

    在这里插入图片描述
           卷积或池化在采样图尺寸不够的情况下会停止滑动滤波器:

    二: 反池化

    2.1 反平均池化

    在这里插入图片描述
           平均池化的反池化是把池化后的平均数字结果分布到池化前图像上的每个像素格子上。

    2.2 反最大池化

    在这里插入图片描述
           最大池化的反池化是把池化后的最大数字结果填充到池化前图像上对应的像素格子上,而其他格子则填充o。

    展开全文
  • 演示反池化的操作

    千次阅读 2018-05-13 16:46:50
    TensorFlow中目前还没有反池化操作的函数。对于最大池化层,也不支持输出最大激活值得位置,但是同样有个池化的反向传播函数tf.nn.max_pool_with_argmax()。该函数可以找出位置,需要开发者利用这个函数做一些改动,...
    TensorFlow中目前还没有反池化操作的函数。对于最大池化层,也不支持输出最大激活值得位置,但是同样有个池化的反向传播函数tf.nn.max_pool_with_argmax()。该函数可以找出位置,需要开发者利用这个函数做一些改动,自己封装一个最大池化操作,然后再根据mask写出反池化函数。
    def max_pool_with_argmax(net,stride):
    '''
    重定义一个最大池化函数,返回最大池化结果以及每个最大值的位置(是个索引,形状和池化结果一致)
    args:
    net:输入数据 形状为[batch,in_height,in_width,in_channels]
    stride:步长,是一个int32类型,注意在最大池化操作中我们设置窗口大小和步长大小是一样的
    '''
    #使用mask保存每个最大值的位置 这个函数只支持GPU操作
    _, mask = tf.nn.max_pool_with_argmax( net,ksize=[1, stride, stride, 1], strides=[1, stride, stride, 1],padding='SAME')
    #将反向传播的mask梯度计算停止
    mask = tf.stop_gradient(mask)
    #计算最大池化操作
    net = tf.nn.max_pool(net, ksize=[1, stride, stride, 1],strides=[1, stride, stride, 1], padding='SAME')
    #将池化结果和mask返回
    return net,mask
    
    
    
    def un_max_pool(net,mask,stride):
    '''
    定义一个反最大池化的函数,找到mask最大的索引,将max的值填到指定位置
    args:
    net:最大池化后的输出,形状为[batch, height, width, in_channels]
    mask:位置索引组数组,形状和net一样
    stride:步长,是一个int32类型,这里就是max_pool_with_argmax传入的stride参数
    '''
    ksize = [1, stride, stride, 1]
    input_shape = net.get_shape().as_list()
    # calculation new shape
    output_shape = (input_shape[0], input_shape[1] * ksize[1], input_shape[2] * ksize[2], input_shape[3])
    # calculation indices for batch, height, width and feature maps
    one_like_mask = tf.ones_like(mask)
    batch_range = tf.reshape(tf.range(output_shape[0], dtype=tf.int64), shape=[input_shape[0], 1, 1, 1])
    b = one_like_mask * batch_range
    y = mask // (output_shape[2] * output_shape[3])
    x = mask % (output_shape[2] * output_shape[3]) // output_shape[3]
    feature_range = tf.range(output_shape[3], dtype=tf.int64)
    f = one_like_mask * feature_range
    # transpose indices & reshape update values to one dimension
    updates_size = tf.size(net)
    indices = tf.transpose(tf.reshape(tf.stack([b, y, x, f]), [4, updates_size]))
    values = tf.reshape(net, [updates_size])
    ret = tf.scatter_nd(indices, values, output_shape)
    return ret
    
    #定义一个形状为4x4x2的张量
    img = tf.constant([
    [[0.0,4.0],[0.0,4.0],[0.0,4.0],[0.0,4.0]],
    [[1.0,5.0],[1.0,5.0],[1.0,5.0],[1.0,5.0]],
    [[2.0,6.0],[2.0,6.0],[2.0,6.0],[2.0,6.0]],
    [[3.0,7.0],[3.0,7.0],[3.0,7.0],[3.0,7.0]],
    ])
    img = tf.reshape(img,[1,4,4,2])
    #最大池化操作
    pooling1 = tf.nn.max_pool(img,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
    #带有最大值位置的最大池化操作
    pooling2,mask = max_pool_with_argmax(img,2)
    #反最大池化
    img2 = un_max_pool(pooling2,mask,2)
    with tf.Session() as sess:
    print('image:')
    image = sess.run(img)
    print(image)
    #默认的最大池化输出
    result = sess.run(pooling1)
    print('max_pool:\n',result)
    #带有最大值位置的最大池化输出
    result,mask2 = sess.run([pooling2,mask])
    print('max_pool_with_argmax:\n',result,mask2)
    #反最大池化输出
    result = sess.run(img2)
    print('un_max_pool',result)
    这里我们自己定义了两个函数,一个是带有最大值位置的最大池化函数,一个反最大池化函数,程序运行后,我们应该可以看到自己定义的最大池化与原来的版本输出是一样的,由于tf.nn.max_pool_with_argmax()函数只支持GPU操作,不能在CPU机器上运行,所以我没法运行这段程序。mask的值是将整个数组flat后的索引,并保持与池化结果一致的shape。
    参考
    展开全文
  • 反池化原理

    千次阅读 2018-05-13 16:29:48
    反池化是池化的逆操作,是无法通过池化的结果还原出全部的原始数据。因为池化的过程就只保留了主要信息,舍去部分信息。如果想从池化后的这些主要信息恢复出全部信息,则存在信息缺失,这时只能通过补位来实现最大...
  • CNN中的卷积、反卷积与反池化

    万次阅读 2018-06-28 20:29:46
    1 卷积DeConvolution 卷积(Deconvolution)的概念第一次出现是Zeiler在2010年发表的论文Deconvolutional networks中,但是并没有指定卷积这个名字,卷积这个术语正式的使用是在其之后的工作中(Adaptive ...
  • Tensorflow反池化操作

    千次阅读 2018-12-12 14:55:11
    TensorFlow中目前还没有反池化操作的函数。对于最大池化, 也不支持输出最大激活值的位置,但是同样有个池化的反向传播函数tf.nn.max_pool_with_argmax。该函数可以输出位置, 需要开发者利用这个函数做一些改动, ...
  • 说明卷积反卷积池化反池化 1. 说明 上采样和反卷积不一样. https://blog.csdn.net/qq_27871973/article/details/82973048 上采样:指的是任何可以让图像变成更高分辨率的技术。最简单的方式是重采样和插值:将输入...
  • TensorFlow实现反池化

    千次阅读 2019-04-29 16:28:51
    TensorFlow实现2×2反池化 2×2反池化 如下图,将输入的尺寸扩大为原来两倍,输入值填充到新的每个2×2网格的左上角,其余三个填0。 代码实现 TensorFlow中没有反池化函数,以下是代码实现。 # 2x2反池化 def ...
  • 【SegNet搭建-pytorch】加载预训练权重+利用反池化上采样记录indices 说明:该文章为个人笔记,存在不完整,敬请谅解~~~ 论文地址:https://arxiv.org/pdf/1511.00561.pdf 1 掌握 1、加载与训练权重 2、采用...
  • 1.反卷积(转置卷积):...2.反池化:对于最大池化,记录元素的位置信息,反池化后的图像大小与原图相等,用0填充其余位置。不需要学习参数。 3.上采样:保留数据的位置信息,复制这些元素填充其余位置的元素。 ...
  • 有3种常见的方法: 双线性插值(bilinear) ...反池化(Unpooling) pytorch 上采样: https://pytorch.org/docs/stable/_modules/torch/nn/modules/upsampling.html 双线性插值 (bilinear) import torch.nn as nn nn....
  • 返回主目录 返回 CNN 卷积神经网络目录 上一章:深度篇—— CNN 卷积神经网络(一)细说 cnn 卷积神经...本小节,细说 池化 与 反池化,下一小节细说 关于 ROI 与 插值 二. 池化层 (pooling layer) 1. 池化...
  • 原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9579108.html ... 一.池化 ... 大家学过神经网络的都知道,在神经网络中有一层是pooling层也就是池化层,通过池化对特征进行提取并且...
  • 实现了tensorflow和numpy的卷积、池化与反池化、反卷积。反卷积不是卷积的逆过程,只是恢复了卷积的尺寸。 import tensorflow as tf import numpy as np import matplotlib.pyplot as plt def cov(n,m): w,h=m....
  • 池化操作中最常见的最大池化和平均池化,因此最常见的反池化操作有反最大池化和反平均池化,其示意图如下: 反最大池化:在池化过程中记录最大激活值的坐标位置,然后在反池化时,只把池化过程中最大激活值所在位置...
  • 反池化 编码器中每一个最大池化层的索引都存储起来,用于之后在编码器中使用那些存储的索引来对相应特征图进行去池化操作。这有助于保持高频信息的完整性,但当对低分辨率的特征图进行反池化时,他也会忽略邻近的...
  • 卷积是指,通过测量输出和已知输入重构未知输入的过程。在神经网络中,卷积过程并不具备学习的能力,仅仅是用于可视化一个已经训练好的卷积神经网络,没有学习训练的过程。卷积有着许多特别的应用,一般可以...
  • 举个例子:假如你想要查看Alexnet 的conv5提取到了什么东西,我们就用conv5的特征图后面接一个反卷积网络,然后通过:反池化、反激活、反卷积,这样的一个过程,把本来一张13*13大小的特征图(conv5大小为13*13),...
  • PyTorch框架学习十——基础网络层(卷积、转置卷积、池化、线性、激活函数)一、卷积层二、转置卷积层三、池化层 上次笔记介绍了PyTorch中如何进行网络搭建,是从宏观上来学习,这次笔记介绍一个网络内部的具体网络...
  • 凭什么相信你,我的CNN模型?(篇一:CAM和Grad-CAM):https://www.jianshu.com/p/1d7b5c4ecb93 凭什么相信你,我的CNN模型?(篇二:万金油LIME):... 卷积和卷积 :https://blog.csdn.net/Fate_fj...
  • 1,极大只反池化操作需要记录池化的坐标值,根据坐标值进行映射,如图: 2,使用tf.nn.max_pool_with_argmax得到极大值坐标值的 flattened index((b * height + y) * width + x) * channels + c., 使用该值...
  • 卷积: SAME:输入大小不够时会在右边加padding补足。output_shape = ceil(input_shape/ stride_size) VALID:output_shape = ceil((input_shape + kernel_...池化没有参数,除非使用tf.nn.max_pool_with_argmax_...
  • 池化的定义比较简单,最直观的作用便是降维,常见的池化有最大池化、平均池化和随机池化池化层不需要训练参数。 1、 三种池化:最大池化Maxpool、平均池化Average_pool、随机池化randpool 最大池化是对局部的值取...
  • 卷积 若输入含有多个通道,则对于某个卷积核,分别对每个通道求feature map后将对应...在介绍卷积之前,我们需要深入了解一下卷积,一个简单的卷积层运算,卷积参数为i=4,k=3,s=1,p=0i=4,k=3,s=1,p=0i=4,k=3,s=1,p=0
  • 反池化上采样 反池化可以用下图来理解,在池化时需要记录下池化的位置,反池化时把池化的位置直接还原,其他位置填0。 总结: 上面三种方法各有优缺,双线性插值方法实现简单,无需训练;反卷积上采样需要训练,但能...
  • 文章目录卷积的理解池化的理解反卷积的理解反池化的理解 卷积的理解 关于卷积在二维离散图像的可视化理解: 对于卷积过程中各个变量的定义: 输入图像的尺寸为I 图像外围的0填充padding为p 卷积核的尺寸为k 卷积核...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,719
精华内容 4,687
关键字:

反池化