【问题标题】:Keras' convolution layer on images coming from circular/cyclic domain [closed]Keras 在来自循环/循环域的图像上的卷积层 [关闭]
【发布时间】:2019-07-21 12:03:04
【问题描述】:

需要

您好,我正在尝试在来自圆柱域的图像上使用 CNN,因此我有兴趣以循环(或循环)方式应用卷积层。 我的意思是一个卷积层而不是用零填充图像只会环绕图像(或图像周围的内核)。

想法、搜索和想法

来自信号处理背景,我预计它已经被涵盖:实际上,当在频域中执行计算时(即通过 DFT),这种循环来自免费的,而不是额外的努力(称为“零填充” ) 是必需的以避免循环模棱两可。

好吧,好吧:我了解到,由于内核大小通常很小,因此可以在基域中更方便地进行计算。我无法弄清楚这不可行的任何充分理由,所以我希望存在一些直接的方法来进行循环卷积。

但我在 Keras 和 TensorFlow 文档中都没有找到该函数的覆盖范围。此外,我发现很少或根本没有真正相关的讨论:Torch7 discussion

所以我有以下选择:

  • 通过继承 Keras 的layer.Layer 类来实现我自己的CyclicConv2D 层,如here 所述
  • 按照here 的描述,提交我自己的实验性新功能拉取请求。很快,我会考虑为“padding=”参数添加一些“wrap”值,或者添加一个新的“wrap=”参数。它应该指定图像应该沿着哪些轴环绕。事实上,这可能只需要沿一个维度,即圆形维度,而不是两个维度。

问题

我应该首先解决任何更直接的选择或信息来源吗?

否则,我在哪里可以找到如何实施前者的建议?

对于后者,我必须承认我描述它更多是为了激发一些集体思考应该如何从用户的角度实现它,但我真的不觉得能够贡献一个好的拉取请求(即包括好的代码) .无论如何,我将不胜感激任何建议从哪里开始。

【问题讨论】:

  • 嗨@lurix66 你找到解决方案了吗?我认为创建自己的图层的问题在于找到一种有效的方法。最简单有效的实现是从域的另一侧(光晕或幽灵单元)镜像实际数据像素,直至内核大小。然后,当您使用valid 填充时,它将返回一个具有填充前原始大小的图像。
  • 没有@Ed,谢谢,还没有。我正在考虑用从另一端复制的列(行)显式地预先填充左侧(顶部)的输入张量,然后调用通常的valid 卷积。我意识到这也应该在池化层上实现,并且让它在多维卷积和池化的一般情况下工作是合理的。
  • 我终于成功了,我想发表我自己对这个问题的回答,但是这个问题已经因为太宽泛而被关闭了,我无法做到它。我能做什么?
  • 提出一个新问题。一个更有针对性的新问题。或者回答这个问题 (stackoverflow.com/questions/49189496/…)
  • @Elias Hasle,我投票决定重新开放

标签: python keras conv-neural-network keras-layer


【解决方案1】:

我正在实现类似的东西,所以虽然我会添加代码。我认为实际实现包装填充的最简单方法是将Numpy pad function 与“wrap”选项一起使用。例如用

input = np.array([[1,2,3],[4,5,6],[7,8,9]])
kernel = [1,1]
#We want symmetrical padding (same top and bottom)
# and np.pad format ((before_1, after_1), … (before_N, after_N))
pad = [[i,i] for i in kernel]
padded_input = np.pad(input, pad, "wrap")

给出,

array([[9, 7, 8, 9, 7],
       [3, 1, 2, 3, 1],
       [6, 4, 5, 6, 4],
       [9, 7, 8, 9, 7],
       [3, 1, 2, 3, 1]])

看起来像创建一个类似于ZeroPadding2D 的自定义层,称为CyclicPadding2D,然后可能是尽量减少对 Keras 代码的更改的最佳主意,就像这样,

kernel = [7,7]
model = Sequential()
model.add(CyclicPadding2D(kernel, input_shape=(224, 224, 3)))
model.add(Conv2D(32, kernel=kernel, padding="valid"))
model.build()

您也可以在池化层和转换层之间使用它。 CyclicPadding2D 中的代码可能需要考虑输入格式(通道、批处理等),例如,

if self.data_format is "channels_last":
    #(batch, depth, rows, cols, channels)
    pad = [[0,0]] + [[i,i] for i in self.kernel] + [[0,0]]
elif self.data_format is "channels_first":
    #(batch, channels, depth, rows, cols)
    pad = [[0, 0], [0, 0]] + [[i,i] for i in self.kernel]
inputs = np.pad(inputs,  pad, "wrap")

这类似于 Keras Numpy backend 使用硬连线选项“constant”所做的事情,而 tensorflow 后端没有提供任何选项,因此默认为常量(尽管有趣的是 tf.pad 提供了反射 option)。

查看 Keras 源代码,当填充选项类似于“周期性”时,只需将上面的代码放在 _conv 的 call function 中,也许可以添加类似这样的功能。也就是说,简单地添加一个新的填充层可能是最灵活的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-02
    • 2021-02-12
    • 2020-03-27
    相关资源
    最近更新 更多