求和技巧的梯度如何在keras中获得最大化位置?

时间:2017-08-22 19:24:58

标签: tensorflow deep-learning keras autoencoder

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?"

1 个答案:

答案 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]