对tf.nn.conv2d方法的理解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wgj99991111/article/details/83447915

理解这个方法之前,先要理解卷积的概念。
卷积,通俗的讲就是加权叠加,就相当于把输入信号的各个时间点的单位响应 加权叠加,就直接得到了输出信号。
在数字图像处理中,卷积的物理含义是:把一个点的像素值用它周围的点的像素值的加权平均代替。通常应用于图像滤波。
注意:这里要强调的是卷积运算时,输入与卷积核之间的运算过程不是矩阵运算,而仅仅是对应位置相乘,然后把所有的值相加,得到中心点的值。
如下图所示:
在这里插入图片描述
这篇文章对卷积的过程讲解比较详细:
https://blog.csdn.net/chaipp0607/article/details/72236892?locationNum=9&fps=1

  • 方法定义

    tf.nn.conv2d (input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)

  • 参数:

  1. input:输入的要做卷积的图片,要求为一个张量。
    shape即形态为: [ batch, in_height, in_weight, in_channel ],
    batch:图片的数量,(为-1表示任意数量)
    in_height :图片高度,
    in_weight :图片宽度,
    in_channel 为图片的通道数,灰度图该值为1,彩色图为3。(也可以用其它值,但是具体含义不是很理解)
  2. filter: 卷积核,也就是卷积函数,要求也是一个张量。
    shape为 [ filter_height, filter_weight, in_channel, out_channels ]
    filter_height 为卷积核高度;
    filter_weight 为卷积核宽度
    in_channel 是图像通道数 ,和 input 的 in_channel 要保持一致,
    out_channel 是卷积核数量。
    out_channel表示有多少个卷积核,in_channel则表示一个卷积核中包含了几个卷积矩阵,in_channel的数值与输入数据的通道数保持一致,因为计算的过程中,一个矩阵对应输入的每个通道中的矩阵进行卷积运算。通常情况下,原始输入的图像都可以区分为RGB三个通道,所以,第一层卷积的in_channel一般为3,当然如果是灰度图就是1了。 而out_channel就表示卷积核的数量,多少个卷积核就要重复多少次上面的运算,运算后得到与卷积核数量相等的输出矩阵。
    下面这篇文章对这些内容讲解的比较详细,不要头大,可以仔细看看哦。
    https://blog.csdn.net/qq_30979017/article/details/79506593?utm_source=blogxgwz1
  3. strides: 卷积时在图像每一维的步长,这是一个一维的向量,
    [ 1, strides, strides, 1],第一位和最后一位固定必须是1
  4. padding: string类型,值为“SAME” 和 “VALID”,表示的是卷积的形式,是否考虑边界。"SAME"是考虑边界,不足的时候用0去填充周围,"VALID"则不考虑
  5. use_cudnn_on_gpu: bool类型,是否使用cudnn加速,默认为true
# case
# 输入是1张 3*3 大小的图片,图像通道数是1,卷积核是 2*2 大小,数量是1 
# 步长是[1,1,1,1]最后得到一个 3*3 的feature map 
# 1张图最后输出就是一个 shape为[1,3,3,1] 的张量
 input = tf.Variable(tf.random_normal([1,3,3,1])) 
 filter = tf.Variable(tf.random_normal([2,2,1,1])) 
 op2 = tf.nn.conv2d(input, filter, strides=[1,1,1,1], padding='SAME') 

副注:看到一个对卷积很形象的解释,抄录如下:
比如说你的老板命令你干活,你却到楼下打台球去了,后来被老板发现,他非常气愤,扇了你一巴掌(注意,这就是输入信号,脉冲),于是你的脸上会渐渐地(贱贱地)鼓起来一个包,你的脸就是一个系统,而鼓起来的包就是你的脸对巴掌的响应,好,这样就和信号系统建立起来意义对应的联系。

下面还需要一些假设来保证论证的严谨:假定你的脸是线性时不变系统,也就是说,无论什么时候老板打你一巴掌,打在你脸的同一位置(这似乎要求你的脸足够光滑,如果你说你长了很多青春痘,甚至整个脸皮处处连续处处不可导,那难度太大了,我就无话可说了哈哈),你的脸上总是会在相同的时间间隔内鼓起来一个相同高度的包来,并且假定以鼓起来的包的大小作为系统输出。好了,那么,下面可以进入核心内容——卷积了!

如果你每天都到地下去打台球,那么老板每天都要扇你一巴掌,不过当老板打你一巴掌后,你5分钟就消肿了,所以时间长了,你甚至就适应这种生活了……如果有一天,老板忍无可忍,以0.5秒的间隔开始不间断的扇你的过程,这样问题就来了,第一次扇你鼓起来的包还没消肿,第二个巴掌就来了,你脸上的包就可能鼓起来两倍高,老板不断扇你,脉冲不断作用在你脸上,效果不断叠加了,这样这些效果就可以求和了,结果就是你脸上的包的高度随时间变化的一个函数了(注意理解);

如果老板再狠一点,频率越来越高,以至于你都辨别不清时间间隔了,那么,求和就变成积分了。可以这样理解,在这个过程中的某一固定的时刻,你的脸上的包的鼓起程度和什么有关呢?和之前每次打你都有关!但是各次的贡献是不一样的,越早打的巴掌,贡献越小,所以这就是说,某一时刻的输出是之前很多次输入乘以各自的衰减系数之后的叠加而形成某一点的输出,然后再把不同时刻的输出点放在一起,形成一个函数,这就是卷积,卷积之后的函数就是你脸上的包的大小随时间变化的函数。

本来你的包几分钟就可以消肿,可是如果连续打,几个小时也消不了肿了,这难道不是一种平滑过程么?反映到剑桥大学的公式上,f(a)就是第a个巴掌,g(x-a)就是第a个巴掌在x时刻的作用程度,乘起来再叠加就ok了

猜你喜欢

转载自blog.csdn.net/wgj99991111/article/details/83447915