回答问题

在带有kernel_size=3的默认Conv2D层中,其中一个过滤器的切片的权重可以这样命名:

A B C
D E F
G H I

像这样使用kernel_size=5:

A B C D E
F G H I J
K L M N O
P Q R S T
U V W X Y

现在我想构建(和训练/测试)一个基于卷积层的模型,其内核如下:

A A B C C
A A B C C
D D E F F
G G H I I
G G H I I

这样一个自定义层的实现会是什么样子?

Answers

也许像这样?

class CustomConv2D(Layer):
    def __init__(self, filters, **kwargs):
        self.filters = filters
        self.kernel_size = (3, 3)
        super(CustomConv2D, self).__init__(**kwargs)

    def build(self, input_shape):
        # only have a 3x3 kernel
        shape = self.kernel_size + (input_shape[-1], self.filters)
        self.kernel = self.add_weight(name='kernel', shape=shape,
                                      initializer='glorot_uniform')
        super(CustomConv2D, self).build(input_shape)

    def call(self, x):
        # duplicate rows 0 and 2
        dup_rows = K.stack([self.kernel[0]]*2 + [self.kernel[1]] + [self.kernel[2]]*2, axis=0)
        # duplicate cols 0 and 2
        dup_cols = K.stack([dup_rows[:,0]]*2 + [dup_rows[:,1]] + [dup_rows[:,2]]*2, axis=1)
        # having a 5x5 kernel now
        return K.conv2d(x, dup_cols)

    def compute_output_shape(self, input_shape):
        return input_shape[:-1] + (self.filters,)

诀窍是在 3x3 内核中仅存储每个过滤器的 9 个权重(硬编码,您可能希望对其进行概括)并复制第一行和最后一行和列以使其成为您想要的 5x5 内核。然后这个内核被传递给K.conv2d(),就像在原始 Conv2d 实现中一样。

我测试了它,它似乎正在工作。您可能想要添加其他参数,如填充、偏差等。

Logo

Python社区为您提供最前沿的新闻资讯和知识内容

更多推荐