keras示例目录包含一个轻量级版本的堆叠什么地方自动编码器(SWWAE),它们在MNIST数据上训练。 (https://github.com/fchollet/keras/blob/master/examples/mnist_swwae.py)
在最初的SWWAE论文中,作者计算了使用软函数的内容和位置。但是,在keras实现中,他们使用技巧来获取这些位置。我想理解这个伎俩。
这是技巧的代码。
def getwhere(x):
''' Calculate the 'where' mask that contains switches indicating which
index contained the max value when MaxPool2D was applied. Using the
gradient of the sum is a nice trick to keep everything high level.'''
y_prepool, y_postpool = x
return K.gradients(K.sum(y_postpool), y_prepool) # How exactly does this line work?
其中y_prepool是MxN矩阵,y_postpool是M / 2 x N / 2矩阵(假设规范池大小为2像素)。
我已经验证了getwhere()的输出是一个钉子矩阵床,其中指甲指示最大位置(如果你愿意的话,当地的argmax)。
有人可以构建一个小例子来演示getwhere如何使用这个" Trick?"
答案 0 :(得分:2)
让我们专注于最简单的例子,而不是真正谈论卷积,比如我们有一个向量
x = [1 4 2]
我们最大化(用一个大窗口),我们得到
mx = 4
从数学上讲,它是:
mx = x[argmax(x)]
现在,"技巧"恢复池化使用的一个热掩码就是
magic = d mx / dx
argmax没有渐变,但是它通过"对应于最大元素位置的向量中元素的渐变,所以:
d mx / dx = [0/dx[1] dx[2]/dx[2] 0/dx[3]] = [0 1 0]
如您所见,非最大元素的所有梯度均为零(由于argmax),以及" 1"出现在最大值,因为dx / x = 1。
现在为"正确" maxpool你有许多汇集区域,连接到许多输入位置,因此采用类似的汇总值之和,将恢复所有索引。
但请注意,如果您的内核严重重叠,这个技巧将无效 - 您最终可能会获得比" 1"更大的值。基本上,如果一个像素被K内核最大化,那么它将具有值K,而不是1,例如:
[1 ,2, 3]
x = [13,3, 1]
[4, 2, 9]
如果我们得到最大池2x2窗口
mx = [13,3]
[13,9]
并且渐变技巧为您提供
[0, 0, 1]
magic = [2, 0, 0]
[0, 0, 1]