精华内容
下载资源
问答
  • 卷积操作

    2018-08-03 16:02:07
    卷积操作详解(填充、步长、高维卷积、卷积公式)  
    展开全文
  • 今天小编就为大家分享一篇pytorch 自定义卷积核进行卷积操作方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 最近在看全连接网络的一些代码,里面的反卷积操作还是有点意思的,写个博客记录一下自己的心得,以便后续自己的查看 1.卷积操作 在TensorFlow中,由tf.nn.conv2d()函数来实现卷积操作,举个例子 y4 = tf.nn.conv...

    最近在看全连接网络的一些代码,里面的反卷积操作还是有点意思的,写个博客记录一下自己的心得,以便后续自己的查看
    1.卷积操作
    在TensorFlow中,由tf.nn.conv2d()函数来实现卷积操作,举个例子
    y4 = tf.nn.conv2d(x2, kernel, strides=[1,2,2,1], padding=“SAME”)具体讲一下函数的参数含义

    第一个参数:是一个四维的张量输入,具有[batch_size,height,width,channel]这样的shape,切记这个是一个四维的tensor,数据类型一般为float32或者是float64.四个参数的具体含义是训练一个batch里面的图片数量,图片的高宽和通道数,或者说是图像的特征层的数量。

    第二个参数:filter的表示,同样也是一个四维的tensor,具有[filter_height,filter_width,in_channel,out_channel]的shape,一般来说卷积核的高宽都是一样的,第三个参数表示输入图像的channel,这个数值和被卷积对象的channel是一致的,即与四维张量输入的channel是相等的,第四个参数表示输出的channel,表示经过卷积核卷积操作后的图像的通道数。

    第三个参数:表示卷积核在卷积操作过程中每一维中的移动步长,是一个一维的向量,如上述的例子所述,第一个和第四个参数一般都为1,因为在batch_size和channel中的步长都默认为1,第二个和第三个参数表示卷积核在图像中水平和垂直方向的滑动步长,视情况而变。

    第四个参数:卷积的操作形式,只能是SAME和VALID两者二选一,表示不同的卷积形式

    SAME和VALID的区别
    卷积方式: SAME(卷积后的特征图大小跟卷积核大小无关,只跟卷积所用的步长有关,当卷积步长是1时,卷积前后特征图大小保持不变)
    输入特征图大小:W×W
    卷积核大小: k×k
    卷积步长: s×s
    输出特征图大小: W1×W1

    W1 = math.ceil(W / s) 表示向上取整函数
    卷积方式是SAME时,会根据卷积核大小,按需在图像上扩充padding,即在宽度或高度方向上补充若干个0,保证图像上的当前点处于卷积中心。
    如果补充的padding个数为偶数会在两侧补充相同个数个0,如果padding为奇数2n+1,会在左侧补n个0,右侧补n+1个0。
    总结:其实我们没必要看SAME方式是如何padding补零的,既然是写了SAME方式,经过卷积核的输出大小只和步长stride有关,直接除步长向上取整就能得到输出图像的大小。

    卷积方式: VALID(根据图片实际大小执行卷积,不对图像边界填充,一般卷积后特征图变小)
    输入特征图大小:W×W
    卷积核大小: k×k
    卷积步长: s×s
    输出特征图大小: W1×W1

    W1 = math.ceil((W-k+1)) / s 表示向上取整函数
    VALID方式和上述的SAME就不大一样了,VALID对图像是没有补零操作的,所以经过卷积后图像的尺寸会变小,而且根据上述的公式卷积后的大小和卷积核尺寸步长都有关系。
    到这里卷积操作就基本上讲的差不多了,上个卷积的图
    卷积示意图图片描述
    2.反卷积操作
    反卷积操作就是个骚操作了,也是写这篇博客的主要目的,也不知道我的理解是不是对的,如有错误,请指正。
    原理上来讲,反卷积操作就是卷积的转置操作,卷积的反向操作,在TensorFlow中,通过tf.nn.conv2d_transpose()函数来实现,还是先讲一下函数的参数含义

    conv2d_transpose(
        value,
        filter,
        output_shape,
        strides,
        padding='SAME',
        data_format='NHWC',
        name=None
    )
    

    第一个参数:和前面讲的正向卷积是一样的,四维的一个输入张量[N,H,W,C],没啥区别。
    第二个参数:卷积核的大小,这里要注意一下,和前面的有点不同[filter_size,filter_size,out_channel,in_channel],可以看出输入和输出的channel和正向卷积刚好相反,因为毕竟是反向卷积吗,所以反过来也好理解QAQ。这个算是一个不同点了
    第三个参数:输出shape,这是反卷积的一个骚操作,为什么要指定输出的输出大小呢?后面会仔细讲。
    第四个参数:步长,和前面的正向卷积差不多吧
    第五个参数:padding模式,也是SAME和VALID这两种

    反卷积的实现过程
    主要是包括两个过程:
    #Step 1 扩充:
    将 inputs 进行填充扩大,扩大的倍数与strides有关(strides倍)。扩大的方式是在元素之间插[ strides - 1 ]个 0。padding="VALID"时,在插完值后继续在周围填充的宽度为[ kenel_size - 1 ],填充值为0;padding = "SAME"时,在插完值后根据output尺寸进行填充,填充值为0。
    #Step 2 卷积:
    对扩充变大的矩阵,用大小为kernel_size卷积核做卷积操作,并且这里的卷积步长一定为1(与参数strides无关,一定是1)
    反卷积操作示意图
    其实我们也能看出反卷积其实就是先把原始的输入进行一系列的插值进行扩大然后在进行正常的卷积操作,其实也是个paper tiger,还有一个问题为什么要指定输出的outshape?因为好像根据卷积核大小、步长、输入能推导出最后的输出结果,最重要的一点是因为一个输入的反卷积结果可能会有好几个,我们需要通过指定输出的大小来确定到底是哪个结果
    那我们应该如何计算最后输出的大小呢?其实这有要关注反卷积的逆向操作卷积了,我们可以通过正向的卷积来判断是否输出的shape合理。
    屁话少说,代码详解,更有利于理解

    import tensorflow as tf
    
    x1 = tf.constant(1.0, shape=[1, 3, 3, 1])
    x2 = tf.constant(1.0, shape=[1, 6, 6, 3])
    x3 = tf.constant(1.0, shape=[1, 5, 5, 3])
    kernel = tf.constant(1.0, shape=[3, 3, 3, 1])
    y1 = tf.nn.conv2d_transpose(x1, kernel, output_shape=[1, 6, 6, 3],
                                strides=[1, 2, 2, 1], padding="SAME")
    y2 = tf.nn.conv2d_transpose(x1, kernel, output_shape=[1, 5, 5, 3],
                                strides=[1, 2, 2, 1], padding="SAME") # 同样输入具有两个不同的输出
    """
    上述的两个反卷积操作是SAME模式,我不管它是怎么padding0的,根据正向卷积的操作,
    输出的大小是W/S向上取整,和卷积核大小无关,5/2和6/2向上取整都为3,所以可以有两个输出
    """
    y3 = tf.nn.conv2d(x3, kernel, strides=[1, 2, 2, 1], padding="SAME")
    y4 = tf.nn.conv2d_transpose(y3, kernel, output_shape=[1, 7, 7, 3],
                                strides=[1, 2, 2, 1], padding="VALID")
    y5 = tf.nn.conv2d_transpose(y3, kernel, output_shape=[1, 8, 8, 3],
                                strides=[1, 2, 2, 1], padding="VALID") # 同样输入具有两个不同的输出
    """
    上述的两个反卷积操作是VALID模式,我不管它是怎么padding0的,根据正向卷积的操作,
    输出的大小(W-k+1))/s是向上取整,(7-3+1)/2和(8-3+1)/2向上取整都为3,所以可以有两个输出
    """
    
    y6 = tf.nn.conv2d_transpose(x1,kernel,output_shape=[1,9,9,3],strides=[1,3,3,1],padding="SAME")
    """
    上述代码可以直接使用stride的倍数来进行扩张输出的倍数,输出=输入×stride
    """
    
    sess= tf.Session()
    tf.global_variables_initializer().run(session=sess)
    x1_decov, x1_decov2, x3_cov, y3_decov, y3_decov2,x1_decov3 = sess.run([y1, y2, y3, y4, y5,y6])
    print(x1_decov.shape)
    print(x1_decov2.shape)
    print(x3_cov.shape)
    print(y3_decov.shape)
    print(y3_decov2.shape)
    print(x1_decov3.shape)
    

    讲的差不多了,总的来说反卷积就是卷积的逆向操作,好好理解卷积的操作能够很好的反向推导反卷积。

    展开全文
  • 卷积神经网络——卷积操作 在上一篇《卷积神经网络简介》里我们介绍了卷积神经网络包含四个主要的操作,其中最重要的就是本文要讲述的“卷积”操作。 对于CNN,卷积操作的主要目的是从输入图像中提取特征。卷积...

    卷积神经网络——卷积操作

    在上一篇《卷积神经网络简介》里我们介绍了卷积神经网络包含四个主要的操作,其中最重要的就是本文要讲述的“卷积”操作。

    对于CNN,卷积操作的主要目的是从输入图像中提取特征。卷积通过使用输入数据的小方块学习图像特征来保留像素之间的空间关系。

    图 1

     卷积操作就是卷积核(过滤器 / Filter)在原始图片中进行滑动得到特征图(Feature Map)的过程。假设我们现在有一个单通道的原始图片和一个卷积核,卷积的过程如图2所示:

    图 2

     卷积得到的特征图的每一个像素值,是由对应位置的卷积核所覆盖的原始图像的对应像素值相乘,然后再相加获得的。卷积核每滑动一次,就进行一次卷积运算,直至得到最后的特征图。

    大家可以观察出,原始图片一定的情况下,得到的特征图和卷积核的矩阵的像素值有很大的关系,卷积核矩阵的不同值将为同一输入图像生成不同的特征图。例如,考虑面3这张输入图像:

    图 3

     我们可以通过在卷积运算之前更改卷积核矩阵的数值来执行诸如边缘检测,锐化和模糊之类的操作——这意味着不同的卷积核可以从图像中检测不同的特征,例如边缘, 曲线等。

    图 4

    图5展示的是不同的卷积核(红色小框和绿色小框),在同一张灰度图上进行卷积操作后得到的了不同的特征图。

    图 5

    实际上,CNN在训练过程中会自行学习这些过滤器的值。 我们拥有的过滤器数量越多,提取的图像特征就越多,并且我们的网络在识别看不见的图像中的图案方面会变得越好。但是在训练过程之前,我们仍然需要指定一些超参数,例如卷积核的数量,卷积核大小,网络的体系结构等。特征图的大小和三个参数有关系:

    • 深度:特征图的深度等于卷积核的个数。
    • 步长:步长是将卷积核滑过输入矩阵的像素数。 当步长为1时,我们将卷积核一次移动一个像素。步长较大将产生较小的特征图。
    • 零填充:用于控制特征图的大小;有利于卷积核学习到输入图像周边的信息。

    前方高能!!

    前面我们都是针对单通道的灰度图进行卷积操作,过程并不复杂。下面我们来看看卷积核在三通道的彩色图像上是如何进行卷积操作的,并逐一详细介绍上面说到的三个参数(深度,步长和零填充)。

    1、深度

    图 6

     首先,一个卷积核的通道数是和被卷积的图像的通道数一致,例如,对于三通道的图像,那么一个卷积核也是由三个通道组成(三个叠加而成的二维矩阵)。而每个通道的大小是可以自定义的超参数,图6一个卷积核的大小为(3,3,3),前两个3分别表示长宽,最后一个3表示通道数。

    其次,卷积核的个数可以是多个,每一个卷积核得到特征图的“一层”,N个卷积核得到的特征图就有N层,即特征图的深度为N。图6所示,一共有4个卷积核,那么最终得到的特征图的深度就为4。

    最后,提问:如果现在针对上图的特征图进行卷积操作,那么每一个卷积核的通道数是多少呢?(思考一下,答案放文章末尾)

    2、步长

    步长就是卷积核在滑动过程中间隔的“格子”数,例如,图1的步长设置为1,因为卷积核每次滑动1格。

    3、零填充

    图 7

    零填充就是在原始图像的周围添加0像素,如图7所示,原始图像大小为32x32,零填充后,图像大小变为36x36。零填充的作用有:1、控制卷积后的特征图的大小。2、加强了对图像周边像素信息的利用。

     

    答案:4。因为卷积核的通道数要与被卷积的图像的通道数相同。此时特征图的通道数为4,所以卷积核的通道数也是4。

     

    展开全文
  • c++图像卷积操作

    2018-11-15 12:14:53
    c++实现图像卷积操作,参数为(输入图像,输出图像),卷积核内部自己更改
  • pytorch 自定义卷积核进行卷积操作

    万次阅读 多人点赞 2018-11-16 02:43:36
    卷积操作:在pytorch搭建起网络时,大家通常都使用已有的框架进行训练,在网络中使用最多就是卷积操作,最熟悉不过的就是 torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, ...

    一 卷积操作:在pytorch搭建起网络时,大家通常都使用已有的框架进行训练,在网络中使用最多就是卷积操作,最熟悉不过的就是

    torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)

    通过上面的输入发现想自定义自己的卷积核,比如高斯核,发现是行不通的,因为上面的参数里面只有卷积核尺寸,而权值weight是通过梯度一直更新的,是不确定的。

    二  需要自己定义卷积核的目的:目前是需要通过一个VGG网络提取特征特后需要对其进行高斯卷积,卷积后再继续输入到网络中训练。

    三 解决方案。使用

    torch.nn.functional.conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1)

     

    这里注意下weight的参数。与nn.Conv2d的参数不一样

    可以发现F.conv2d可以直接输入卷积的权值weight,也就是卷积核。那么接下来就要首先生成一个高斯权重了。这里不直接一步步写了,直接输入就行。

    kernel = [[0.03797616, 0.044863533, 0.03797616],
             [0.044863533, 0.053, 0.044863533],
             [0.03797616, 0.044863533, 0.03797616]]

    四 完整代码

    class GaussianBlur(nn.Module):
        def __init__(self):
            super(GaussianBlur, self).__init__()
            kernel = [[0.03797616, 0.044863533, 0.03797616],
                      [0.044863533, 0.053, 0.044863533],
                      [0.03797616, 0.044863533, 0.03797616]]
            kernel = torch.FloatTensor(kernel).unsqueeze(0).unsqueeze(0)
            self.weight = nn.Parameter(data=kernel, requires_grad=False)
    
        def forward(self, x):
            x1 = x[:, 0]
            x2 = x[:, 1]
            x3 = x[:, 2]
            x1 = F.conv2d(x1.unsqueeze(1), self.weight, padding=2)
            x2 = F.conv2d(x2.unsqueeze(1), self.weight, padding=2)
            x3 = F.conv2d(x3.unsqueeze(1), self.weight, padding=2)
            x = torch.cat([x1, x2, x3], dim=1)
            return x
    

     这里为了网络模型需要写成了一个类,这里假设输入的x也就是经过网络提取后的三通道特征图(当然不一定是三通道可以是任意通道)

    如果是任意通道的话,使用torch.expand()向输入的维度前面进行扩充。如下:

        def blur(self, tensor_image):
            kernel = [[0.03797616, 0.044863533, 0.03797616],
                   [0.044863533, 0.053, 0.044863533],
                   [0.03797616, 0.044863533, 0.03797616]]
           
            min_batch=tensor_image.size()[0]
            channels=tensor_image.size()[1]
            out_channel=channels
            kernel = torch.FloatTensor(kernel).expand(out_channel,channels,3,3)
            self.weight = nn.Parameter(data=kernel, requires_grad=False)
    
            return F.conv2d(tensor_image,self.weight,1,1)

     

    展开全文
  • 理解卷积操作

    2020-12-08 16:55:46
    为啥卷积操作好使?因为它在大致的位置进行粗略的比对。 举个例子,为了识别一张图片是x还是o,通过卷积操作,可以使计算机在图片大致的位置进行粗略的比对,这样的话,即使图片中的x旋转、拉伸、位移,也能很好的...
  • 理解图像卷积操作的意义

    万次阅读 多人点赞 2017-05-16 22:40:04
    数字信号处理中卷积 卷积一词最开始出现在信号与线性系统中,信号与线性系统中讨论的就是信号经过一个线性系统以后发生的变化。由于现实情况中常常是一个信号前一时刻的输出影响着这一时刻的输出,所在一般利用系统...
  • 卷积及理解图像卷积操作的意义

    万次阅读 多人点赞 2018-03-20 16:56:17
    转载:http://blog.csdn.net/chaipp0607/article/details/72236892 https://www.zhihu.com/question/22298352 在图像处理领域,我们经常能听到滤波,卷积之类的词,其实他们都可以看做一种图像的卷积操作,相对应...
  • 膨胀卷积操作

    2019-11-09 11:57:44
    膨胀卷积操作是指将卷积核扩张到指定尺寸,并将原卷积核中没有占用的区域用零填充(如下图所示)。 膨胀卷积计算公式: 膨胀的卷积核尺寸 = 膨胀系数*(原始卷积核尺寸-1)+1 代码实现: import tensorflow ...
  • 图像卷积操作

    2018-09-03 10:08:50
    理解图像卷积操作的意义
  • python实现卷积操作

    千次阅读 2018-12-27 15:03:09
    我们知道,tensorflow里面自带卷积函数,tf.nn.conv2d()就可以实现相关功能,本文主要是自己实现卷积操作,然后和tf.nn.conv2d()函数的结果对比,验证正确性。 调用tf.nn.conv2d()实现卷积 首先是调用卷积函数实现...
  • 与图像上的卷积操作不同,图像上的卷积操作实际上是图像的感受野与卷积核进行加权和,终其原因是因为,数学上的卷积操作与图像上的卷积操作不同。 一、数学中的卷积 数学中的卷积操作分为两种,一种是连续函数进行...
  • 卷积操作的基础知识

    万次阅读 多人点赞 2019-03-05 17:48:34
    在Tensorflow中该API的功能是进行的是卷积操作,那是如何运行的呢? 卷积操作的目的 卷积操作的目的是提取图像的特征。都提取什么特种呢?根据不同的卷积核、不同的计算方式,会得到不同的特征提取图。 图(1) ...
  • Tensorflow2.0 卷积操作

    2020-11-27 11:30:30
    卷积操作 """ keras.Conv2D 卷积操作与 tf.nn.Conv2D 卷积操作 """ import tensorflow as tf from tensorflow.keras import layers # 获取物理GPU的个数 gpus = tf.config.experimental.list_physical_devices(...
  • 卷积神经网络中的卷积操作主要是由:卷积核大小(kearl_size),步长(stride),填充(padding)等决定,根据输入的特征图的in_channel的个数,尺寸以及卷积核大小,步长与填充的关系可以计算出卷积后输出的特征图的out...
  • 基本为上采样后进行卷积操作,下图为upPooling后使用尺寸不变的卷积操作(通过padding实现尺寸不变)。 有人说也叫转置卷积,因为如下原因: 先说说卷积: 以矩阵相乘的形式完成卷积,????????????????????????...
  • 首先说明一下,深度学习中常见的卷积操作和数学意义上的卷积求和是有略略区别的。深度学习中的卷积和就是对应点数相乘再相加即可,而数学中的卷积和要先进性变换再进行对应相乘相加。 数学意义卷积求和 ...
  • 在介绍卷积神经网络CNN的时候,大部分教材在介绍“卷积操作”的时候都与下面这张图类似的说明 这点让人很困惑,因为在数学上,卷积运算是这么定义的 (f∗g)(t)=∫0tf(τ)g(t−τ) dτ(f * g )(t) = \int_{0}^{t} f...
  • 不同类型的卷积操作

    2019-12-19 11:29:38
    原始版本卷积操作 这种卷积操作叫SAME Padding,卷积操作后原图与特征图大小相同。每次移动一个格子 这种卷积操作叫VALUE Padding,卷积操作后原图比特征图要大,每次移动的步长为2 代表模型: ...
  • 代码实现卷积操作

    2020-09-03 18:08:51
    代码实现卷积操作 转载:https://blog.csdn.net/qq_41398808/article/details/97925070
  • 卷积操作的HLS优化初步操作

    千次阅读 2018-08-09 14:29:45
    背景:卷积操作运用到了三个for循环,非常耗时耗力,HLS综合之后需要耗费很多时钟周期,我们需要对卷积操作进行相应的优化,从而减少卷积运行的时间。 目的:优化卷积操作。 目录 0.原始未优化情况 0.1 test...
  • 卷积操作的参数量和FLOPs

    万次阅读 2020-03-03 17:45:31
    卷积操作的参数量和FLOPs   这里首先需要辨析一个概念就是FLOPs和FLOPS可以看到简写的差别仅仅是一个字母大小写的区别。   FLOPS(floating-point operations per second),这个缩写长这个样子确实也很奇怪,大致...
  • 深度学习卷积操作总结1. 1*1卷积2. 深度可分离卷积3. 残差网络Residual Net 1. 1*1卷积 ① 特征维度匹配:通常在进行大量卷积操作后,利用1*1卷积块的前后尺度一致性,进行特征通道对齐,保证尺度不变而通道个数符合...
  • 卷积操作及其变体

    2019-02-17 16:10:11
    卷积神经网络中十大拍案叫绝的操作文章的启发,我们从卷积操作本身进一步进行理解。下图方便直观理解标准的卷积过程。 图片来自这里 卷积核的维度由四个参数决定:输入特征图的通道数、滤波器的高度、滤波器的...
  • 它也可以通过卷积操作来实现,只是需要将卷积核旋转180度。它主要应用在图像分割和超分辨率等任务中。笔记主要包括转置卷积操作和Pytorch转置卷积层。本笔记的知识框架主要来源于深度之眼,并依此作了内容的丰富拓展...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,189
精华内容 2,875
关键字:

卷积操作