我正在尝试使用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))