Я думаю, что это базовая версия того, что вы намереваетесь:
from keras import backend as K
class Conv2DTiledKernel(Layer):
def __init__(self, filters, kernel_size, multiplies, **kwargs):
self.filters = filters
self.kernel_size = kernel_size
self.multiplies = multiplies
super(Conv2DTiledKernel, self).__init__(**kwargs)
def build(self, input_shape):
shape = list(self.kernel_size) + [input_shape[-1], self.filters]
self.kernel = self.add_weight(name='kernel', shape=shape,
initializer='glorot_uniform')
super(Conv2DTiledKernel, self).build(input_shape)
def call(self, x):
mult = list(self.multiplies) + [1, 1]
kernel_tiled = K.tile(self.kernel, mult)
return K.conv2d(x, kernel_tiled)
def compute_output_shape(self, input_shape):
return input_shape[:-1] + (self.filters,)
fitlers
- это число выходных каналов, kernel_size
размер каждого канала ядра и multiplies
коэффициенты листов. Вы бы использовали что-то вроде этого:
from keras.models import Model
from keras.layers import Input, Layer
img = Input(shape=(64, 64, 3))
output = Conv2DTiledKernel(10, [1, 5], [5, 1])(img)
model = Model(inputs=img, outputs=output)
Это довольно простая версия. Позже вы можете добавить опции для смещения, регуляризатора, инициализации, заполнения, шагов, расширения и т. Д. Вы можете посмотреть исходный код , чтобы увидеть, как сверточные слои реализованы в Keras. Было бы идеально, если бы вы могли просто создать подкласс одного из классов, чтобы вы получили все дополнительные опции бесплатно, но я не уверен, что это можно сделать практичным способом, поскольку код в настоящее время стоит.