ConvNet中的col2im实施

时间:2018-08-06 08:21:53

标签: python neural-network deep-learning conv-neural-network convolution

我正在尝试仅使用numpy实施 CNN

在进行反向传播时,我发现必须使用 col2im 来重塑 dx ,因此我从https://github.com/huyouare/CS231n/blob/master/assignment2/cs231n/im2col.py中检查了实现。 / p>

class UserMailer < ApplicationMailer
  def account_activation(user, activation_token)
    @user = user
    @activation_token = activation_token
    mail to: user.email, subject: "user activation"
  end
end

UserMailer.account_activation(user, user.activation_token).deliver_later

<p><%= link_to "active link", edit_account_activation_url(@activation_token, email: @user.email) %></p>

我希望将 X 放入 im2col_indices ,并将该输出放回 col2im_indices ,将返回相同的 X ,但是没有。

我不明白col2im的实际作用。

2 个答案:

答案 0 :(得分:2)

如果我是对的,则输出不是相同的X,因为X的每个单元格都转换为多个col,并且在im2col_indices期间被相乘。

假设您有一个像这样的简单图片X

 1 2 3
 4 5 6
 7 8 9

,然后将其转换为内核大小3,步幅为1,并使用same填充,结果将为

0 0 0 0 1 2 0 4 5
0 0 0 1 2 3 4 5 6
0 0 0 2 3 0 5 6 0
0 1 2 0 4 5 0 7 8
1 2 3 4 5 6 7 8 9
2 3 0 5 6 0 8 9 0
0 4 5 0 7 8 0 0 0
4 5 6 7 8 9 0 0 0
5 6 0 8 9 0 0 0 0
* *   * *

如您所见,第一个值为1的单元格出现在四个col中:0、1、3、4。

im2col_indices首先用0初始化具有填充大小的图像,然后将每个col添加到其中。专注于第一个单元格,过程应该像

1.zero初始化图片

0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

2.add col 0

0 0 0 0 0     0 0 0 - -     0 0 0 0 0
0 0 0 0 0     0 1 2 - -     0 1 2 0 0
0 0 0 0 0  +  0 4 5 - -  =  0 4 5 0 0
0 0 0 0 0     - - - - -     0 0 0 0 0
0 0 0 0 0     - - - - -     0 0 0 0 0

3.add col 1

0 0 0 0 0     - 0 0 0 -     0  0  0  0  0
0 1 2 0 0     - 1 2 3 -     0  2  4  3  0
0 4 5 0 0  +  - 4 5 6 -  =  0  8 10  6  0
0 0 0 0 0     - - - - -     0  0  0  0  0
0 0 0 0 0     - - - - -     0  0  0  0  0

4.add col 3

0  0  0  0  0     - - - - -     0  0  0  0  0
0  2  4  3  0     0 1 2 - -     0  3  6  3  0
0  8 10  6  0  +  0 4 5 - -  =  0 12 15  6  0
0  0  0  0  0     0 7 8 - -     0  7  8  0  0 
0  0  0  0  0     - - - - -     0  0  0  0  0

5.add col 4

0  0  0  0  0     - - - - -     0  0  0  0  0
0  3  6  3  0     - 1 2 3 -     0  4  8  6  0
0 12 15  6  0  +  - 4 5 6 -  =  0 16 20 12  0
0  7  8  0  0     - 7 8 9 -     0 14 16  9  0
0  0  0  0  0     - - - - -     0  0  0  0  0 

转换回时,第一个单元格乘以4。对于这张简单的图片,col2im_indices(im2col_indices(X))应该给您

 4  12  12
24  45  36
28  48  36

与原始图像相比,四个角单元1 3 7 9被乘以4,四个边缘单元2 4 6 8被乘以6,而中心单元5被乘以9。

对于大图像,大多数单元将被9乘以,我认为这大致意味着您的学习率实际上比您想象的大9倍。

答案 1 :(得分:0)

回复这个已有2年历史的主题,将来可能会对某人有所帮助。

这是我的理解。在CNN反向传播上下文中,col2im矩阵是滤波器与反向传播误差(dout)的乘积。必须注意的是,矩阵已经是两个矩阵的乘积,这与前向传递中的im2col用例不同,前向传递中我们只是将输入扩展到im2col矩阵中,准备进行乘法(卷积)。由于im2col和col2im之间存在这种差异,因此在col2im中,我们需要向所有贡献的输入索引中添加回传的误差。

让我们考虑一个1x5x5输入,单个1x3x3过滤器,0填充,跨度为1的示例。输入的索引如下所示:

[0,0] [0,1] [0,2] [0,3] [0,4]
[1,0] [1,1] [1,2] [1,3] [1,4]
[2,0] [2,1] [2,2] [2,3] [2,4]
[3,0] [3,1] [3,2] [3,3] [3,4]
[4,0] [4,1] [4,2] [4,3] [4,4]

为正向传播计算的结果9x9 im2col索引 矩阵乘法看起来像:

im2col索引

<-----------------------  9 ----------------------------->
[ 0] [0,0] [0,1] [0,2] [1,0] [1,1] [1,2] [2,0] [2,1] [2,2] 
[ 1] [0,1] [0,2] [0,3] [1,1] [1,2] [1,3] [2,1] [2,2] [2,3] 
[ 2] [0,2] [0,3] [0,4] [1,2] [1,3] [1,4] [2,2] [2,3] [2,4] 
[ 3] [1,0] [1,1] [1,2] [2,0] [2,1] [2,2] [3,0] [3,1] [3,2] 
[ 4] [1,1] [1,2] [1,3] [2,1] [2,2] [2,3] [3,1] [3,2] [3,3] 
[ 5] [1,2] [1,3] [1,4] [2,2] [2,3] [2,4] [3,2] [3,3] [3,4] 
[ 6] [2,0] [2,1] [2,2] [3,0] [3,1] [3,2] [4,0] [4,1] [4,2] 
[ 7] [2,1] [2,2] [2,3] [3,1] [3,2] [3,3] [4,1] [4,2] [4,3] 
[ 8] [2,2] [2,3] [2,4] [3,2] [3,3] [3,4] [4,2] [4,3] [4,4] 

在反向传递中,当我们通过将反向传播的误差点与滤波器相乘生成col2im矩阵时,如上所示的结果索引已经是相乘的结果。当我们将其转换回输入错误时,我们需要在输入错误数组的给定位置添加相应的索引。

例如:

input_error[0,0] = im2col_error[0,0]
input_error[0,1] = im2col_error[0,1] + im2col_error[1,0]
input_error[0,2] = im2col_error[0,2] + im2col_error[1,1] + im2col_error[2,0]
....
....

从上面的索引矩阵可以明显看出这一点。