本文介绍了Keras Conv2D自定义内核初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用权重初始化自定义Conv2D内核

I need to initialize custom Conv2D kernels with weights

其中W =要初始化的Conv2D图层的自定义权重

where W = custom weight of Conv2D layer to initialise with

a =随机权重张量为keras.backend.variable(np.random.uniform()),shape =(64,1,10)

a = random weight Tensors as keras.backend.variable(np.random.uniform()), shape=(64, 1, 10)

b =固定基滤波器定义为keras.backend.constant(...),shape =(10,11,11)

b = fixed basis filters defined as keras.backend.constant(...), shape=(10, 11, 11)

我希望我的模型通过仅更改'a'的同时更新'W'值,同时保持'b'不变.

I want my model to update the 'W' values with only changing the 'a's while keeping the 'b's constant.

我将自定义"W"传递为

I pass the custom 'W's as

其中kernel_init_L1返回keras.backend.variable(K.reshape(w_L1, (11, 11, 1, 64)))

Problem:我不确定这是否是正确的方法.是否可以在Keras中指定哪些是trainable,哪些不是.我知道可以将图层设置为trainable = True,但是我不确定权重.

Problem:I am not sure if this is the correct way to do this. Is it possible to specify in Keras which ones are trainable and which are not. I know that layers can be set trainable = True but i am not sure about weights.

我认为实现是不正确的,因为无论有没有自定义初始化,我都可以从模型中获得相似的结果.

I think the implementation is incorrect because I get similar results from my model with or without the custom initializations.

如果有人可以指出我的方法中的任何错误或提供一种验证方法,这将非常有帮助.

It would be immensely helpful if someone can point out any mistakes in my approach or provide a way to verify it.

推荐答案

警告您的形状:如果内核大小为(11,11),并且假设您具有64个输入通道和1个输出通道,则最终内核形状必须为(11,11,64,1).

Warning about your shapes: If your kernel size is (11,11), and assuming you have 64 input channels and 1 output channel, your final kernel shape must be (11,11,64,1).

您可能应该选择a[None,None]b[:,:,:,None,None].

class CustomConv2D(Conv2D):

    def __init__(self, filters, kernel_size, kernelB = None, **kwargs):
        super(CustomConv2D, self).__init__(filters, kernel_size,**kwargs)
        self.kernelB = kernelB

    def build(self, input_shape):


        #use the input_shape to calculate the shapes of A and B
        #if needed, pay attention to the "data_format" used. 

        #this is an actual weight, because it uses `self.add_weight`   
        self.kernelA = self.add_weight(
                  shape=shape_of_kernel_A + (1,1), #or (1,1) + shape_of_A
                  initializer='glorot_uniform', #or select another
                  name='kernelA',
                  regularizer=self.kernel_regularizer,
                  constraint=self.kernel_constraint)


        #this is an ordinary var that will participate in the calculation
            #not a weight, not updated
        if self.kernelB is None:
            self.kernelB = K.constant(....) 
            #use the shape already containing the new axes


        #in the original conv layer, this property would be the actual kernel,
        #now it's just a var that will be used in the original's "call" method 
        self.kernel = K.sum(self.kernelA * self.kernelB, axis=2)  
        #important: the resulting shape should be:
            #(kernelSizeX, kernelSizeY, input_channels, output_channels)   


        #the following are remains of the original code for "build" in Conv2D
        #use_bias is True by default
        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 = InputSpec(ndim=self.rank + 2,
                                axes={channel_axis: input_dim})
        self.built = True


自定义图层的提示

当您从零(源自Layer)创建自定义图层时,应具有以下方法:


Hints for custom layers

When you create a custom layer from zero (derived from Layer), you should have these methods:

  • __init__(self, ... parameters ...)-这是创建者,在您创建图层的新实例时会调用它.在这里,您存储用户作为参数传递的值. (在Conv2D中,初始化将具有过滤器",内核大小"等).
  • build(self, input_shape)-您应该在此处创建权重(所有可学习的变量都在此基于输入形状创建)
  • compute_output_shape(self,input_shape)-在这里,您将根据输入形状返回输出形状
  • call(self,inputs)-在这里执行实际的层计算
  • __init__(self, ... parameters ...) - this is the creator, it's called when you create a new instance of your layer. Here, you store the values the user passed as parameters. (In a Conv2D, the init would have the "filters", "kernel_size", etc.)
  • build(self, input_shape) - this is where you should create the weights (all learnable vars are created here, based on the input shape)
  • compute_output_shape(self,input_shape) - here you return the output shape based on the input shape
  • call(self,inputs) - Here you perform the actual layer calculations

由于我们不是从零开始创建该层,而是从Conv2D派生它,所以一切都准备就绪,我们要做的就是更改"构建方法并替换被认为是Conv2D层内核的东西.

Since we're not creating this layer from zero, but deriving it from Conv2D, everything is ready, all we did was to "change" the build method and replace what would be considered the kernel of the Conv2D layer.

有关自定义图层的更多信息: https://keras.io/layers /writing-your-own-keras-layers/

More on custom layers: https://keras.io/layers/writing-your-own-keras-layers/

用于转换图层的call方法是class _Conv(Layer): 中.

The call method for conv layers is here in class _Conv(Layer):.

这篇关于Keras Conv2D自定义内核初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-12 02:32