永兴的tensorflow笔记-13 卷积操作

在这里插入图片描述

一、什么是卷积?(Convolutional)

  • 卷积是一种有效提取图片特征的方法。一般用一个正方形卷积核,遍历图片 上的每一个像素点。图片与卷积核重合区域内相对应的每一个像素值乘卷积核 内相对应点的权重,然后求和,再加上偏置后(可不加),最后得到输出图片中的一个像素值。
  • 在原始的输入上进行特征的提取。特征提取简言之就是,在原始输入上一个小区域一个小区域进行特征的提取。
    在这里插入图片描述

二、卷积的作用:

  • 图像卷积操作的目的是提取图像的特征。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 特征是不断进行提取和压缩的,最终能得到比较高层次特征,简言之就是对原式特征一步又一步的浓缩,最终得到的特征更可靠。利用最后一层特征可以做各种任务:比如分类、回归等。
  • 如下图:
    • 第一次卷积可以提取出低层次的特征。
    • 第二次卷积可以提取出中层次的特征。
    • 第三次卷积可以提取出高层次的特征。

在这里插入图片描述

三、卷积的实际运用:

  • 普通的卷积:
    在这里插入图片描述
    例:上面是 5x5x1 的灰度图片,1 表示单通道,5x5 表示分辨率,共有 5 行 5 列个灰度值。若用一个 3x3x1 的卷积核对此 5x5x1 的灰度图片进行卷积,偏置项 b=1,则求卷积的计算是:(-1)x1+0x0+1x2+(-1)x5+0x4+1x2+(-1)x3+0x4+1x5+1=1(注意不要忘记加偏置 1)。
    输出图片边长=(输入图片边长–卷积核长+1)/步长,此图为:(5 – 3 + 1)/ 1 = 3,输出图片是 3x3 的分辨率,用了 1 个卷积核,输出深度是 1,最后输出的是 3x3x1 的图片。
    在这里插入图片描述
  • 全零填充 Padding:
    有时会在输入图片周围进行全零填充,这样可以保证输出图片的尺寸和输入 图片一致。
    在这里插入图片描述
    例:在前面 5x5x1 的图片周围进行全零填充,可使输出图片仍保持 5x5x1 的 维度。这个全零填充的过程叫做 padding。
    输出数据体的尺寸=(W−F+2P)/S+1
    W:输入数据体尺寸,F:卷积层中神经元感知域,S:步长,P:零填充的数量。
    例:输入是 7×7,滤波器是 3×3,步长为 1,填充为 0,那么就能得到一个 5×5 的输出。如果步长为 2,输出就是 3×3。
    如果输入量是 32x32x3,核是 5x5x3,不用全零填充,输出是(32-5+1)/1=28, 如果要让输出量保持在 32x32x3,可以对该层加一个大小为 2 的零填充。可以根据需求计算出需要填充几层零。32=(32-5+2P)/1 +1,计算出 P=2,即需填充 2 层零。
    在这里插入图片描述
    在这里插入图片描述
  • 使用 padding 和不使用 padding 的输出维度:
    在这里插入图片描述
    上一行公式是使用 padding 的输出图片边长,下一行公式是不使用 padding 的输出图片边长。公式如果不能整除,需要向上取整数。如果用全零填充,也就 是 padding=SAME。如果不用全零填充,也就是 padding=VALID。

四、TensorFlow下的函数。

tf.nn.conv2d

conv2d(  
    input,
    filter=None,
    strides=None,
    padding=None,
    use_cudnn_on_gpu=True,
    data_format="NHWC",
    dilations=[1, 1, 1, 1],
    name=None,
    filters=None)

参数:

  • input:A Tensor。必须是下列类型之一: half,bfloat16,float32,float64。一个4-D张量。尺寸顺序根据的值进行解释data_format,有关详细信息,请参见下文。
  • filters:A Tensor。必须具有与相同的类型input。形状的4D张量 [filter_height, filter_width, in_channels, out_channels]
  • strides:一个的int或列表ints具有长度1,2或4。每个尺寸的滑动窗的步幅input。如果给出单个值,则将其复制到H和W维度中。默认情况下,N和C尺寸设置为1。尺寸顺序由的值确定data_format,有关详细信息,请参见下文。
  • padding:string “SAME"或"VALID"指示要使用的填充算法的类型,或者是一个列表,指示在每个维度的开始和结束处的显式填充。如果使用显式填充,并且使用data_format “NHWC”,则应采用形式[[0, 0], [pad_top, pad_bottom], [pad_left, pad_right], [0, 0]]。如果使用显式填充,并且data_format是"NCHW”,则应采用形式[[0, 0], [0, 0], [pad_top, pad_bottom], [pad_left, pad_right]]。
  • data_format:string来自的可选"NHWC", “NCHW”。默认为"NHWC"。指定输入和输出数据的数据格式。使用默认格式“ NHWC”时,数据按以下顺序存储:[批,高度,宽度,通道]。或者,格式可以是“ NCHW”,数据存储顺序为:[批,通道,高度,宽度]。
  • dilations:An的int或列表ints具有长度1,2或者4,默认为1对的各维的扩张因子input。如果给出单个值,则将其复制到H和W维度中。默认情况下,N和C维度设置为1。如果设置为k> 1,则该维度上每个过滤器元素之间将跳过k-1个单元格。尺寸顺序由的值确定data_format,有关详细信息,请参见上文。如果4-d张量必须为1.则批量和深度尺寸的膨胀。
  • name:操作的名称(可选)。

返回值:

  • 一Tensor。与类型相同input。
一般情况:
  • 函数中要给出四个信息:对输入图片的描述、对卷积核的描述、对卷积核 滑动步长的描述以及是否使用 padding。

    • 1)对输入图片的描述:用 batch 给出一次喂入多少张图片,每张图片的分 辨率大小,比如 5 行 5 列,以及这些图片包含几个通道的信息,如果是灰度图 则为单通道,参数写 1,如果是彩色图则为红绿蓝三通道,参数写 3。

    • 2)对卷积核的描述:要给出卷积核的行分辨率和列分辨率、通道数以及用 了几个卷积核。比如上图描述,表示卷积核行列分辨率分别为 3 行和 3 列,且是 1 通道的,一共有 16 个这样的卷积核,卷积核的通道数是由输入图片的通道数 决定的,卷积核的通道数等于输入图片的通道数,所以卷积核的通道数也是 1。 一共有 16 个这样的卷积核,说明卷积操作后输出图片的深度是 16,也就是输出 为 16 通道。

    • 3)对卷积核滑动步长的描述:上图第二个参数表示横向滑动步长,第三个 参数表示纵向滑动步长。第一个 1 和最后一个 1 这里固定的。这句表示横向纵向 都以 1 为步长。

    • 4)是否使用 padding:用的是 VALID。注意这里是以字符串的形式给出 VALID。

  • 对多通道的图片求卷积
    多数情况下,输入的图片是 RGB 三个颜色组成的彩色图,输入的图片包含了 红、绿、蓝三层数据,卷积核的深度应该等于输入图片的通道数,所以使用 3x3x3 的卷积核,最后一个 3 表示匹配输入图像的 3 个通道,这样这个卷积核有三层, 每层会随机生成 9 个待优化的参数,一共有 27 个待优化参数 w 和一个偏置 b。
    在这里插入图片描述
    对于彩色图,按层分解开,可以直观表示为上面这张图,三个颜色分量:红 色分量、绿色分量和蓝色分量。
    卷积计算方法和单层卷积核相似,卷积核为了匹配红绿蓝三个颜色,把三层 的卷积核套在三层的彩色图片上,重合的 27 个像素进行对应点的乘加运算,最 后的结果再加上偏置项 b,求得输出图片中的一个值。
    这个 5x5x3 的输入图片加了全零填充,使用 3x3x3 的卷积核,所有 27 个点与 对应的待优化参数相乘,乘积求和再加上偏置 b 得到输出图片中的一个值 6。

在这里插入图片描述
针对上面这幅彩色图片,用 conv2d 函数实现可以表示为:
一次输入 batch 张图片,输入图片的分辨率是 5x5,是 3 通道的,卷积核是 3x3x3,一共有 16 个卷积核,这样输出的深度就是 16,核滑动横向步长是 1,纵 向步长也是 1,padding 选择 same,保证输出是 5x5 分辨率。由于一共用了 16 个卷积核,所以输出图片是 5x5x16。

使用演示:
import tensorflow as tf
input = tf.Variable(tf.constant(1.0, shape=[1, 5, 5, 1]))
filter = tf.Variable(tf.constant([-1.0, 0, 0, -1], shape=[2, 2, 1, 1]))
op = tf.nn.conv2d(input, filter, strides=[1, 2, 2, 1], padding='SAME')

init = tf.global_variables_initializer()
with tf.Session() as sess:
  sess.run(init)
  print("op:\n",sess.run(op))
发布了45 篇原创文章 · 获赞 28 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/m0_43505377/article/details/104068129
今日推荐