Neural network tf.nn.conv2d在tensorflow中做什么?

Neural network tf.nn.conv2d在tensorflow中做什么?,neural-network,tensorflow,Neural Network,Tensorflow,我在看tensorflow关于tf.nn.conv2d的文档。但我不明白它做了什么,或者它试图实现什么。文件上写着 #1:将过滤器展平为具有形状的二维矩阵 [过滤高度*过滤宽度*输入通道,输出通道] 那又有什么用呢?这是元素乘法还是简单的矩阵乘法?我也无法理解文件中提到的另外两点。我写在下面: #2:从输入张量中提取图像面片,以形成形状的虚拟张量 [批处理、输出高度、输出宽度、过滤器高度*过滤器宽度*输入通道] #3:对于每个面片,右乘滤波器矩阵和图像面片向量 如果有人能给出一个例子,一段代码(

我在看tensorflow关于
tf.nn.conv2d
的文档。但我不明白它做了什么,或者它试图实现什么。文件上写着

#1:将过滤器展平为具有形状的二维矩阵

[过滤高度*过滤宽度*输入通道,输出通道]

那又有什么用呢?这是元素乘法还是简单的矩阵乘法?我也无法理解文件中提到的另外两点。我写在下面:

#2:从输入张量中提取图像面片,以形成形状的虚拟张量

[批处理、输出高度、输出宽度、过滤器高度*过滤器宽度*输入通道]

#3:对于每个面片,右乘滤波器矩阵和图像面片向量

如果有人能给出一个例子,一段代码(非常有用),并解释那里发生了什么,以及为什么操作是这样,那将非常有帮助

我试着编写一小部分代码并打印出操作的形状。不过,我还是不明白

我试过这样的方法:

op=tf.shape(tf.nn.conv2d(tf.random_normal([1,10,10,10]),
tf.随机_正态([2,10,10,10]),
步幅=[1,2,2,1],填充='SAME'))
使用tf.Session()作为sess:
结果=sess.run(op)
打印(结果)
我了解卷积神经网络的一些细节。我研究过它们。但是tensorflow上的实现并不是我所期望的。因此,它提出了一个问题

编辑: 因此,我实现了一个更简单的代码。但我不知道发生了什么。我是说结果是这样的。如果有人能告诉我是什么过程产生了这个输出,那将是非常有帮助的

input=tf.Variable(tf.random_normal([1,2,2,1]))
filter=tf.Variable(tf.random_normal([1,1,1,1]))
op=tf.nn.conv2d(输入、筛选、步幅=[1,1,1,1],padding='SAME')
初始化所有变量()
使用tf.Session()作为sess:
sess.run(初始化)
打印(“输入”)
打印(input.eval())
打印(“过滤器”)
打印(filter.eval())
打印(“结果”)
结果=sess.run(op)
打印(结果)
输出

input
[[[[ 1.60314465]
   [-0.55022103]]

  [[ 0.00595062]
   [-0.69889867]]]]
filter
[[[[-0.59594476]]]]
result
[[[[-0.95538563]
   [ 0.32790133]]

  [[-0.00354624]
   [ 0.41650501]]]]

好的,我认为这是解释这一切的最简单的方法


您的示例是1个图像,大小为2x2,带有1个通道。您有一个大小为1x1的过滤器和一个通道(大小为高度x宽度x通道x过滤器数量)

对于这种简单的情况,得到的2x2,1通道图像(尺寸1x2xx1,图像数量x高度x宽度x通道)是将滤波器值乘以图像的每个像素的结果


现在让我们尝试更多频道:

input=tf.Variable(tf.random_normal([1,3,3,5]))
filter=tf.变量(tf.random_normal([1,1,5,1]))
op=tf.nn.conv2d(输入、筛选、步幅=[1,1,1,1],padding='VALID')
这里3x3图像和1x1滤波器各有5个通道。结果图像将为3x3,带有1个通道(尺寸1x3x1),其中每个像素的值是滤波器通道与输入图像中相应像素的点积

x.x.x
.....
x.x.x
.....
x.x.x

现在使用3x3过滤器

input=tf.Variable(tf.random_normal([1,3,3,5]))
filter=tf.变量(tf.random_normal([3,3,5,1]))
op=tf.nn.conv2d(输入、筛选、步幅=[1,1,1,1],padding='VALID')
这里我们得到一个1x1图像,带有一个通道(大小为1x1x1)。该值是9,5元素点积的总和。但你可以称之为45元素点积


现在有一个更大的形象

input=tf.Variable(tf.random_normal([1,5,5,5]))
filter=tf.变量(tf.random_normal([3,3,5,1]))
op=tf.nn.conv2d(输入、筛选、步幅=[1,1,1,1],padding='VALID')
输出为3x3单通道图像(尺寸1x3x1)。 每个值都是9,5元素点积的总和

每个输出都是通过将滤波器置于输入图像的9个中心像素之一的中心来实现的,这样滤波器就不会突出。下面的
x
s代表每个输出像素的过滤器中心

.....
.xxx.
.xxx.
.xxx.
.....

现在使用“相同”填充:

input=tf.Variable(tf.random_normal([1,5,5,5]))
filter=tf.变量(tf.random_normal([3,3,5,1]))
op=tf.nn.conv2d(输入、筛选、步幅=[1,1,1,1],padding='SAME')
这将提供5x5输出图像(尺寸为1x5x1)。这是通过将过滤器置于图像上每个位置的中心来实现的

滤光片伸出图像边缘的任何5元素点积的值都为零

所以角点只是4,5元素点积的和


现在使用多个过滤器

input=tf.Variable(tf.random_normal([1,5,5,5]))
filter=tf.变量(tf.random_normal([3,3,5,7]))
op=tf.nn.conv2d(输入、筛选、步幅=[1,1,1,1],padding='SAME')
这仍然提供5x5输出图像,但有7个通道(尺寸为1x5x7)。其中每个通道由集合中的一个滤波器产生


现在大踏步2,2:

input=tf.Variable(tf.random_normal([1,5,5,5]))
filter=tf.变量(tf.random_normal([3,3,5,7]))
op=tf.nn.conv2d(输入,过滤,步幅=[1,2,2,1],填充='SAME')
现在,结果仍然有7个通道,但只有3x3(大小为1x3x7)

这是因为过滤器不是在图像上的每个点居中,而是在图像上的每个其他点居中,采取宽度为2的步长(步幅)。下面的
x
代表输入图像上每个输出像素的过滤中心

x.x.x
.....
x.x.x
.....
x.x.x

当然,输入的第一个维度是图像的数量,因此您可以将其应用于一批10个图像,例如:

input=tf.Variable(tf.random_normal([10,5,5,5]))
filter=tf.变量(tf.random_normal([3,3,5,7]))
op=tf.nn.conv2d(输入,过滤,步幅=[1,2,2,1],填充='SAME')
这将对每个图像分别执行相同的操作,给出一个s
res = tf.squeeze(tf.nn.conv2d(image, kernel, [1, 1, 1, 1], "VALID"))
# VALID means no padding
with tf.Session() as sess:
   print sess.run(res)
filter = tf.Variable(tf.random_normal([3,3,5,7]))
filter = tf.Variable(tf.random_normal([100,100,3,7]))
def conv(ix, w):
   # filter shape: [filter_height, filter_width, in_channels, out_channels]
   # flatten filters
   filter_height = int(w.shape[0])
   filter_width = int(w.shape[1])
   in_channels = int(w.shape[2])
   out_channels = int(w.shape[3])
   ix_height = int(ix.shape[1])
   ix_width = int(ix.shape[2])
   ix_channels = int(ix.shape[3])
   filter_shape = [filter_height, filter_width, in_channels, out_channels]
   flat_w = tf.reshape(w, [filter_height * filter_width * in_channels, out_channels])
   patches = tf.extract_image_patches(
       ix,
       ksizes=[1, filter_height, filter_width, 1],
       strides=[1, 1, 1, 1],
       rates=[1, 1, 1, 1],
       padding='SAME'
   )
   patches_reshaped = tf.reshape(patches, [-1, ix_height, ix_width, filter_height * filter_width * ix_channels])
   feature_maps = []
   for i in range(out_channels):
       feature_map = tf.reduce_sum(tf.multiply(flat_w[:, i], patches_reshaped), axis=3, keep_dims=True)
       feature_maps.append(feature_map)
   features = tf.concat(feature_maps, axis=3)
   return features