首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Keras Conv2D自定义内核初始化

Keras Conv2D自定义内核初始化
EN

Stack Overflow用户
提问于 2018-07-10 12:44:20
回答 1查看 6.9K关注 0票数 1

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

W= a1b1 + a2b2 +.+ anbn

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

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

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

W= K.sum(a:、None、None * bNone、None、:、:、axis=2) #shape=(64、1、11、11)

我希望我的模型更新'W‘值,只改变’a‘’,同时保持‘b’的不变。

我把这个习惯说成

Conv2D(64,kernel_size=(11,11),激活=‘relu’,kernel_initializer=kernel_init_L1)(img)

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

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

我认为这个实现是不正确的,因为我从我的模型中得到了类似的结果,不管有没有自定义初始化。

如果有人能指出我的方法中的任何错误,或者提供一种方法来验证它,那将是非常有帮助的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-10 13:33:08

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

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

代码语言:javascript
复制
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派生)创建自定义层时,您应该拥有以下方法:

  • __init__(self, ... parameters ...) --这是创建者,当您创建一个新的层实例时调用它。在这里,您可以存储用户作为参数传递的值。(在Conv2D中,init有“过滤器”、"kernel_size“等)
  • build(self, input_shape) -这是您应该创建权重的地方(所有可学习的vars都是在这里创建的,基于输入的形状)
  • compute_output_shape(self,input_shape) -在这里,您根据输入形状返回输出形状
  • call(self,inputs) -在这里执行实际的层计算

由于我们不是从零创建这个层,而是从Conv2D派生它,所以一切都准备好了,我们所做的就是“更改”构建方法,并替换将被认为是Conv2D层内核的内容。

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

conv层的call方法是class _Conv(Layer):

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51265578

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档