我正在尝试使用Keras功能API实现所谓的symmetrical layer,我在此paper中找到了该API。这个想法是转置卷积运算符K,所以我必须转置Conv2D
层的内核并将其重用于另一个Conv2D
层。因此,我需要编写自己的Keras层。到目前为止,我得到了:
class TiedConv2D(layers.Conv2D):
def __init__(self, filters, kernel_size, padding, tied_to=None, **kwargs):
super(TiedConv2D, self).__init__(filters, kernel_size,**kwargs)
self.tied_to = tied_to
def build(self, input_shape):
#the following remains of the original code for Conv2D
if self.data_format == 'channels_first':
channel_axis = 1
else:
channel_axis = -1
if input_shape[channel_axis] is None:
raise ValueError('The channel dimension of the inputs '
'should be defined. Found `None`.')
input_dim = input_shape[channel_axis]
# own code
k1 = self.tied_to.kernel
self.kernel = K.transpose(k1)
#the following remains of the original code for Conv2D
if self.use_bias:
self.bias = self.add_weight(shape=(self.filters,),
initializer=self.bias_initializer,
name='bias',
regularizer=self.bias_regularizer,
constraint=self.bias_constraint)
else:
self.bias = None
# Set input spec.
self.input_spec = keras.engine.base_layer.InputSpec(ndim=self.rank + 2, axes={channel_axis: input_dim})
self.built = True
如果我仅传递前一层的内核而不对其进行任何处理,则该代码有效。内核定义为3x3形状,因此对其进行转置应能很好地工作。但是问题在于内核是具有3x3x1x1形状的张量的形式,并且
K.transpose
转置了整个张量。如何只转置内核本身,以便再次获得3x3x1x1形式的内核? 最佳答案
您要使用K.permute_dimensions
。
我不确定您要转置的内容,但我看到两种可能性。
转置空间尺寸(内核将与原始内核标识的事物相同,但方向不同):K.permute_dimensions(k1, (1,0,2,3))
转置输入和输出通道(也许是在某种反向层中使用内核-不知道这是否存在,但是....):K.permute_dimensions(k1, (0,1,3,2))
关于python - Keras:转置Conv2D层的内核以在另一个Conv2D层中重用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59590693/