我正在尝试仅使用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的实际作用。
答案 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]
....
....
从上面的索引矩阵可以明显看出这一点。