卷积神经网络的深度是什么?

34
我正在阅读来自 CS231n Convolutional Neural Networks for Visual Recognition 的卷积神经网络。在卷积神经网络中,神经元按三个维度(heightwidthdepth)排列。我无法想象出卷积神经网络中的depth是什么。
在链接中,他们说CONV层的参数由一组可学习的过滤器组成。每个过滤器在空间上很小(沿宽度和高度),但延伸到输入体的全部深度。
例如,请看这张图片。如果图片太糟糕了,请见谅。crappy picture 我能理解我们从图像中取一个小区域,然后与“过滤器”进行比较的想法。那么过滤器将是一组小图像吗?他们还说:“我们仅将每个神经元连接到输入体积的局部区域。这种连接的空间范围是称为神经元感受野的超参数。”那么感受野是否具有与过滤器相同的维度?在这里深度是多少?使用CNN的深度表示什么意思?
所以,我的问题主要是,如果我拿一个尺寸为[32 * 32 * 3]的图像(假设我有50000个这样的图像,使数据集为[50000 * 32 * 32 * 3]),我应该选择什么作为它的深度,深度意味着什么。过滤器的尺寸是多少?
如果有人能提供一些关于此的直觉链接,那将非常有帮助。
编辑: 在教程的一个部分(现实世界的例子部分),它说:The Krizhevsky et al. architecture that won the ImageNet challenge in 2012 accepted images of size [227x227x3]. On the first Convolutional Layer, it used neurons with receptive field size F=11, stride S=4 and no zero padding P=0. Since (227 - 11)/4 + 1 = 55, and since the Conv layer had a depth of K=96, the Conv layer output volume had size [55x55x96]. 我们可以看到深度是96。那么深度是我随意选择的吗?还是我计算出来的?另外,在上面的例子中(Krizhevsky等人),他们有96个深度。那么它的96个深度是什么意思? 教程还指出:Every filter is small spatially (along width and height), but extends through the full depth of the input volume
这意味着深度会像这样吗?如果是这样,那么我可以假设Depth = Number of Filters吗? enter image description here
8个回答

14

在深度神经网络中,“depth”指的是网络的深度,但在这个上下文中,“depth”用于视觉识别,并且它转换为图像的第三个维度。

在这种情况下,您有一张图像,输入大小为32x32x3,即(宽度,高度,深度)。神经网络应该能够根据这些参数进行学习,因为深度将转化为训练图像的不同通道。

更新:

在CNN的每个层中,它都会学习关于训练图像的规律性。在最初的层中,规律性是曲线和边缘,然后随着您沿着层深入学习更高级别的规律性,例如颜色、形状、对象等。这是基本思想,但存在许多技术细节。在继续之前,请尝试一下:http://www.datarobot.com/blog/a-primer-on-deep-learning/

更新2:

看一下您提供的链接中的第一张图。它说“在这个例子中,红色的输入层保存了图像,因此其宽度和高度将是图像的尺寸,深度将是3(红、绿、蓝通道)。”这意味着ConvNet神经元通过将其神经元排列成三个维度来转换输入图像。

回答您的问题,深度对应于图像的不同颜色通道。

此外,关于过滤器深度。教程中指出:

每个过滤器在空间上很小(沿着宽度和高度),但延伸到输入体的整个深度。

这基本上意味着过滤器是图像的较小部分,它在图像的深度周围移动以学习图像中的规律性。

更新3:

针对这个真实世界的例子,我刚刚浏览了原论文,发现它是这样描述的:第一层卷积层使用96个尺寸为11×11×3的卷积核对224×224×3的输入图像进行过滤,并采用4个像素的步幅。

在教程中,深度被称为通道,但在实际应用中,您可以设计任何您喜欢的维度。毕竟那是您的设计

该教程旨在让您了解ConvNets在理论上是如何工作的,但如果我设计一个ConvNet,没有人能阻止我提出具有不同深度的模型

这有意义吗?


1
你能详细解释一下吗?我正在努力理解基本的概念。 - Shubhashis
抱歉,我仍然无法理解CNN的深度和过滤器会是什么。您提供的链接有点像抽象概念。我想了解技术细节。如果您能访问我提供的链接并查看一下,那将非常有帮助。我是新手,可能会错过一些明显的要点。 - Shubhashis
这就是我的问题所在。由于你所说的“深度对应于图像的不同颜色通道”,但教程页面在某个区域中说得与此不同。在教程的实际示例部分中,它说:“Krizhevsky等人在2012年赢得ImageNet挑战赛的架构接受大小为[227x227x3]的图像。在第一个卷积层中,它使用具有感受野大小F=11、步幅S=4和无零填充P=0的神经元。由于(227-11)/4+1=55,并且由于Conv层的深度为K=96,因此Conv层输出体积的大小为[55x55x96]。”在这里,深度不是3,而是96。 - Shubhashis
我猜这回答了你的问题 :) - Semih Yagcioglu
是的,我想它确实如此 :) - Shubhashis
显示剩余2条评论

10

CONV层的深度是指其使用的过滤器数目。 过滤器的深度等于其所使用的输入图像的深度。

例如:假设您使用的是一张227*227*3的图像。 现在假设您使用的是一个11*11(空间大小)大小的过滤器。 这个11*11的方块将沿着整个图像滑动,以产生一个二维数组作为响应。但为了这样做,它必须覆盖11*11区域内的每个方面。因此,过滤器的深度将是图像的深度=3。 现在假设我们有96个这样的过滤器,每个过滤器都会产生不同的响应。这将是卷积层的深度。它只是使用的过滤器数量。


7

我不确定为什么这一部分被轻描淡写地忽略了。一开始我也有困难理解它,很少有人像Andrej Karpathy(感谢d00d)那样解释它。尽管在他的写作中(http://cs231n.github.io/convolutional-networks/),他使用了一个与动画不同的例子来计算输出体的深度。

首先阅读标题为“Numpy examples”的部分

在这里,我们进行迭代。

在这种情况下,我们有一个11x11x4。(为什么我们从4开始有点奇怪,因为深度为3更容易理解)

真正注意这一行:

位置(x,y)处的深度列(或纤维)将是激活X [x,y,:]。

深度切片,或者等效地说,深度d处的激活图将是激活X [:,:,d]。

V [0,0,0] = np.sum(X [:5,:5,:] * W0)+ b0

V是您的输出体积。零索引v [0]是您的列 - 在这种情况下,V [0] = 0 这是输出体积中的第一列。 V [1] = 0 这是输出体积中的第一行。V [3] = 0 是深度。这是第一个输出层。

现在,这就是人们感到困惑的地方(至少我是)。输入深度与输出深度绝对没有任何关系。输入深度只控制过滤器深度。W在Andrej的例子中。

附:很多人想知道为什么3是标准输入深度。对于普通图像,彩色输入图像始终为3。

np.sum(X [:5,:5,:] * W0)+ b0 (卷积1)

在这里,我们在一个权重向量W0和一个5x5x4之间计算逐元素乘积。 5x5是任意选择。 4是深度,因为我们需要匹配输入深度。 权重向量是您的过滤器,内核,接受域或其他人们决定在未来称其为的名称。

如果你没有Python背景,那可能是因为数组切片符号不直观导致更加困惑。计算是图像的第一个卷积大小(5x5x4)与权重向量的点积。输出是一个单一标量值,它采取了第一个滤波器输出矩阵的位置。想象一个4 x 4矩阵,表示每个卷积操作在整个输入上的乘积总和。现在为每个过滤器堆叠它们。这将给你你的输出体积。在Andrej的写作中,他开始沿着x轴移动。y轴保持不变。
以下是关于卷积方面的例子:V[:,:,0]。请记住,在这里我们索引的第三个值是你的输出层的深度 [卷积1的结果,卷积2的结果,..., ...] [..., ..., ..., ..., ...] [..., ..., ..., ..., ...] [..., ..., ..., 卷积n的结果] 动画最适合理解这个,但是Andrej决定用一个与上述计算不匹配的例子来交换它。
这花了我一段时间。部分原因是因为numpy没有按照Andrej在他的例子中所做的方式进行索引,至少我没有玩过。此外,有一些假设是清晰的总和乘积操作。这是理解如何创建输出层的关键,每个值代表什么以及深度是什么。
希望这有所帮助!

5
由于我们在进行图像分类问题时的输入体积为 N x N x 3,因此最初很容易想象深度是什么意思 - 只是通道数 - 红、绿、蓝。好的,第一层的含义就清楚了。但是下一层呢?以下是我尝试形象化这个概念的方法。
  1. 在每一层上,我们应用一组滤波器来卷积输入。假设我们当前在第一层,并且我们在大小为N x N x 3的体积V周围卷积。正如@Semih Yagcioglu在一开始提到的那样,我们正在寻找一些粗略的特征:曲线、边缘等等...假设我们应用了N个相同大小(3x3)并带有步长1的过滤器。然后,这些过滤器中的每一个都在卷积V周围寻找不同的曲线或边缘。当然,过滤器具有相同的深度,我们希望提供整个信息而不仅仅是灰度表示。
  2. 现在,如果有M个过滤器寻找M个不同的曲线或边缘。每个过滤器将产生一个特征图,由标量组成(标量的含义是过滤器说:在这里拥有这条曲线的概率为X%)。当我们在体积周围使用相同的过滤器进行卷积时,我们获得了这个标量地图,告诉我们我们在哪里看到了这条曲线。
  3. 接下来是特征映射堆叠。将堆叠想象为以下内容。我们知道每个过滤器检测到某个曲线的位置信息。好的,那么当我们将它们堆叠在一起时,我们就可以获得关于输入体积的每个小部分可用的曲线/边缘的信息。这就是我们第一个卷积层的输出。
  4. 考虑到3,理解非线性思想很容易。当我们在某个特征映射上应用ReLU函数时,我们说:删除此位置的所有曲线或边缘的负概率。这当然是有道理的。
  5. 接下来,下一层的输入将是一个体积$V_1$,携带着不同空间位置的不同曲线和边缘的信息(记住:每个层都携带有关1个曲线或边缘的信息)。
  6. 这意味着下一层将能够通过组合这些曲线和边缘来提取有关更复杂形状的信息。为了将它们组合起来,过滤器应具有与输入体积相同的深度。
  7. 有时我们会应用池化。其含义正是缩小体积。由于当我们使用步长=1时,通常会对同一特征进行多次像素(神经元)查看。
希望这有意义。请查看著名的CS231课程提供的惊人图表,以了解如何计算某个位置上每个特征的概率。

所以,如果我理解有误,请纠正我。如果我理解正确的话,每层过滤器的数量是任意确定的。应用的过滤器越多,该层的自由度就越大,因此其识别复杂形状的能力也会提高。当然,更多并不总是更好,因为人们应该注意网络的过拟合问题。 - CatOsMandros

2
你需要注意的第一件事是:
receptive field of a neuron is 3D 

如果接受域为5x5,神经元将连接到5x5x(输入深度)个点。因此,无论输入深度如何,一层神经元仅会生成1层输出。

Each neuron is connected to whole depth in receptive field

现在,需要注意的下一件事是:
depth of output layer = depth of conv. layer

ie 输出音量与输入音量无关,仅取决于滤波器数量(深度)。这从前面的观点应该很明显。

请注意,滤波器的数量(cnn层的深度)是超参数。您可以根据自己的需要进行选择,而与图像的深度无关。每个滤波器都有自己的一组权重,使其能够在由滤波器覆盖的同一局部区域上学习不同的特征。


2
简单来说,可以解释如下,
假设您有10个过滤器,其中每个过滤器的大小为5x5x3。这是什么意思?这一层的深度10,等于过滤器的数量。每个过滤器的大小可以按照我们想要的方式定义,例如,在本例中为5x5x3,其中3是上一层的深度。确切地说,下一层中每个过滤器的深度应为10(nxnx10),其中n可以定义为您想要的值,例如5或其他值。希望这样能让一切变得清晰明了。

1
网络的深度是指网络中的层数。在Krizhevsky的论文中,深度为9层(除了如何计算层数的栅杆问题?)。Krizhevsky等人CNN的架构

0

如果您指的是滤波器深度(我搜索这个问题就找到了这个),那么LeNet的这个图示说明了:

LeNet-5 来源 http://yann.lecun.com/exdb/publis/pdf/lecun-01a.pdf

如何创建这样的滤波器;在Python中,可以使用类似于https://github.com/alexcpn/cnn_in_python/blob/main/main.py#L19-L27的代码:

这将给您一个numpy数组列表,列表的长度即为深度。

在上面的代码示例中,但添加颜色(RGB)深度为3时,以下是网络结构。第一卷积层是形状为(5,5,3)和深度6的滤波器。

Input (R,G,B)= [32.32.3] *(5.5.3)*6  == [28.28.6] * (5.5.6)*1 = [24.24.1] *  (5.5.1)*16 = [20.20.16] *
FC layer 1 (20, 120, 16) * FC layer 2 (120, 1) * FC layer 3 (20, 10) * Softmax  (10,) =(10,1) = Output

在Pytorch中
np.set_printoptions(formatter={'float': lambda x: "{0:0.2f}".format(x)})
# Generate a random image
image_size = 32 
image_depth = 3
image = np.random.rand(image_size, image_size)
# to mimic RGB channel
image = np.stack([image,image,image], axis=image_depth-1) # 0 to 2
image = np.moveaxis(image, [2, 0], [0, 2])
print("Image Shape=",image.shape)
input_tensor = torch.from_numpy(image)
m = nn.Conv2d(in_channels=3,out_channels=6,kernel_size=5,stride=1)
output = m(input_tensor.float())
print("Output Shape=",output.shape)

Image Shape= (3, 32, 32)
Output Shape= torch.Size([6, 28, 28])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接