减小卷积神经网络中的滤波器大小

Reducing Filter Size in Convolutional Neural Network

我正在阅读 Szegedy 等人的 Inception 论文:https://arxiv.org/abs/1512.00567 我无法理解他们如何通过用 2 层 3x3 过滤器替换单个 5x5 过滤器来减少计算量(第 3.1 节)。

特别是这段话:

If we would naivly slide a network without reusing the computation between neighboring grid tiles, we would increase the computational cost. sliding this network can be represented by two 3x3 convolutional layers which reuses the activations between adjacent tiles.

我不明白我们如何重用这些激活。

所以首先,作者声明:

This way, we end up with a net (9+9) / 25 × reduction of computation, resulting in a relative gain of 28% by this factorization.

他是对的:对于一个 5x5 过滤器,您必须使用 25 (5*5) 个单独的权重。对于两个 3x3 过滤器,您必须使用 9 + 9 (3*3 + 3*3) 个单独的权重。 所以使用两个 3x3 过滤器需要更少的参数。但是,你是对的,这并不意味着它需要更少的计算:乍一看,使用两个 3x3 过滤器需要更多的操作。

让我们比较给定 n*n 输入的两个选项的操作量。演练:

  1. 计算给定输入 ((n - filtersize + 1)^2) 上 5x5 滤波器的输出维度,及其相应的操作
  2. 计算第一个3x3滤波器的输出维度(同上公式),及其对应的操作
  3. 计算第二个3x3过滤器的输出维度,及其对应的操作

让我们从 5x5 输入开始:

1. (5 - 5 + 1)^2 = 1x1. So 1*1*25 operations = 25 operations
2. (5 - 3 + 1)^2 = 3x3. So 3*3*9  operations = 81 operations
3. (3 - 3 + 1)^2 = 1x1. So 1*1*9  operations = 9  operations
So 25 vs 90 operations. Using a single 5x5 filter is best for a 5x5 input.

接下来,6x6 输入:

1. (6 - 5 + 1)^2 = 2x2. So 2*2*25 operations = 100 operations
2. (6 - 3 + 1)^2 = 4x4. So 4*4*9  operations = 144 operations
3. (4 - 3 + 1)^2 = 2x2. So 2*2*9  operations = 36  operations
So 100 vs 180 operations. Using a single 5x5 filter is best for a 6x6 input.

让我们跳到前面,8x8 输入:

1. (8 - 5 + 1)^2 = 4x4. So 4*4*25 operations = 400 operations
2. (8 - 3 + 1)^2 = 6x6. So 6*6*9  operations = 324 operations
3. (4 - 3 + 1)^2 = 4x4. So 4*4*9  operations = 144 operations
So 400 vs 468 operations. Using a single 5x5 filter is best for a 8x8 input.

注意到这个模式了吗?给定输入大小 n*n5x5 过滤器的操作具有以下公式:

(n - 4)*(n - 4) * 25

对于 3x3 过滤器:

(n - 2)*(n - 2) * 9 + (n - 4) * (n - 4) * 9

所以让我们绘制这些:

它们好像有交集!正如您可能从上图中读到的那样,从 n=10 及以后的两个 3x3 过滤器的操作次数似乎更少!

结论:看来在n=10之后使用两个3x3滤镜是有效的。此外,无论 n,与单个 5x5 滤波器相比,两个 3x3 滤波器需要调整的参数更少。


尽管这篇文章有点奇怪,但出于某种原因,它让人感觉像是在一个 5x5 过滤器上使用两个 3x3 过滤器 'obvious':

This setup clearly reduces the parameter count by sharing the weights between adjacent tiles.

it seems natural to exploit translation invariance again and replace the fully connected component by a two layer convolutional architecture

If we would naivly slide

我也一直在处理这种困惑,似乎每次我都需要重新审视 Inception 论文。

比较的正确设置是考虑形状为 5x5 的玩具示例输入图像。要使用 5x5 卷积生成 5x5 输出图像,您需要在顶部、底部和侧面用 2 个额外填充像素填充原始图像,然后继续进行通常的 5x5 卷积。卷积滤波器有25个权重参数,输出的每个像素需要输入的25项的加权和。

现在,我们将执行两个阶段,而不是 5x5 过滤器。首先,我们将沿顶部、底部和侧面用 1 个额外像素填充原始图像,以使其在每个点都符合标准的 3x3 卷积。

这会产生一个中间图像,由于填充,形状与输入相同,但每个像素都是 3x3 卷积的结果(因此每个像素都控制着 9 个项目的加权和)。

现在我们将对最后阶段的 3x3 卷积再次重复此操作,从第一个 3x3 卷积的中间图像开始。同样,我们在顶部、底部和侧面填充 1 个像素,输出的每一项都是通过输入的 9 项的加权和来实现的。

您在问题中提供的图表演示了这如何允许聚合 5x5 卷积的相同跨度空间信息,但只是通过两个 3x3 卷积的一组不同的两个加权和来计算。要清楚,计算是不一样的,因为系数的两个 9-d 滤波器不必学习与系数的 25-d 滤波器相同。它们可能是不同的权重,但它们可以按顺序跨越与 5x5 卷积相同的原始图像距离。

最后,我们可以看到,在 5x5 的情况下,每个输出单元需要 25 次乘加运算。顺序 3x3 情况下最终输出的每个单元需要先进行 9 次乘加以生成第一个 3x3 卷积的单元,然后再进行 9 次乘加以生成最终输出的单元。

关于"activation sharing"的具体注释是指你只计算一次中间3x3卷积的值。您为每个单元花费 9 次操作,但一旦创建它们,您只需再花费 9 次操作即可到达最终输出单元。您无需为最终输出的每个单元一遍又一遍地重复创建第一个 3x3 卷积。

这就是为什么不将其算作每个输出单元需要 81 次操作的原因。当您碰到 final 3x3 卷积输出的下一个 (i, j) 位置时,您正在重新使用 intermediate[=47= 的一堆像素] 3x3 卷积,所以你每次只需要多做 9 次操作就可以得到最终输出。

5x5 输入的 5x5 填充卷积的操作数为 25 * 25。

第一个 3x3 填充卷积的操作数是 25 * 9,从那里你 添加 另一个填充 3x3 卷积的成本,所以整体变成 25 * 9 + 25 * 9 = 25 * 18.

这就是他们如何得出 (25 * 25) / (25 * 18) = 25/18 的比率。

碰巧,这也是参数总数的相同减少。

我认为关键是原始图表(来自论文和您的问题)做得非常糟糕,表明您将首先支付标准的 3x3 卷积成本来创建整个像素的中间集原始 5x5 输入,包括填充。 然后你会运行中间结果的第二个 3x3 卷积(这就是他们重新使用激活的意思)。

图片让它看起来像单独的,对于每个最终输出像素,您将围绕整个 3x3 中间层的所有正确位置滑动原始 3x3 卷积,每次计算 9-ops 加权和(81 ops整体),然后 计算最终的 9-ops 加权和以获得输出的单个像素。然后返回到原来的位置,将卷积层颠簸 1 个点,然后重复。但这是不正确的,不会 "re-use" 中间卷积层,而是会为最终输出层的每个单元单独重新计算它。

但总的来说,我同意这是非常重要且难以思考的。这篇论文实际上掩盖了它,并假设很多上下文已经在 reader.

的脑海中