Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Keras Conv2D自定义内核初始化_Python_Keras_Conv Neural Network - Fatal编程技术网

Python Keras Conv2D自定义内核初始化

Python Keras Conv2D自定义内核初始化,python,keras,conv-neural-network,Python,Keras,Conv Neural Network,我需要使用权重初始化自定义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[:,:,:,无,无]*b[无,无,无,:,:,:],轴=2)#形状=(64,1,11,11) 我希望我

我需要使用权重初始化自定义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[:,:,:,无,无]*b[无,无,无,:,:,:],轴=2)#形状=(64,1,11,11)

我希望我的模型更新“W”值,只更改“a”,同时保持“b”不变

我通过海关的“W”为

Conv2D(64,kernel\u size=(11,11),activation='relu',kernel\u初始值设定项=kernel\u init\u L1)(img)

其中
kernel\u init\u L1
返回
keras.backend.variable(K.reformate(w\u L1,(11,11,1,64))

问题:
我不确定这样做是否正确。是否可以在KERA中指定哪些是可培训的,哪些不是。我知道可以设置层
trainable=True
,但我不确定权重

我认为实现是不正确的,因为无论是否使用自定义初始化,我的模型都会得到类似的结果


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

关于形状的警告:如果内核大小为
(11,11)
,并且假设有64个输入通道和1个输出通道,那么最终的内核形状必须是
(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

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

  • \uuuuu init\uuuuuu(self,…parameters…)
    -这是创建者,在创建层的新实例时调用它。在这里,存储用户作为参数传递的值。(在Conv2D中,init将具有“过滤器”、“内核大小”等)
  • build(self,input\u shape)
    -这是您应该创建权重的地方(所有可学习的变量都在这里创建,基于输入形状)
  • compute\u output\u shape(self,input\u shape)
    -在这里,您根据输入形状返回输出形状
  • 调用(self,inputs)
    -在这里您可以执行实际的图层计算
因为我们不是从零开始创建这个层,而是从
Conv2D
派生出来的,所以一切都准备好了,我们所做的只是“更改”构建方法并替换Conv2D层的内核

有关自定义图层的详细信息:


conv层的
调用方法是。

关于形状的警告:如果内核大小是
(11,11)
,并且假设您有64个输入通道和1个输出通道,那么最终的内核形状必须是
(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

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

  • \uuuuu init\uuuuuu(self,…parameters…)
    -这是创建者,在创建层的新实例时调用它。在这里,存储用户作为参数传递的值。(在Conv2D中,init将具有“过滤器”、“内核大小”等)
  • build(self,input\u shape)
    -这是您应该创建权重的地方(所有可学习的变量都在这里创建,基于输入形状)
  • compute\u output\u shape(self,input\u shape)
    -在这里,您根据输入形状返回输出形状
  • 调用(self,inputs)
    -在这里您可以执行实际的图层计算
因为我们不是从零开始创建这个层,而是从
Conv2D
派生出来的,所以一切都准备好了,我们所做的只是“更改”构建方法并替换Conv2D层的内核

有关自定义图层的详细信息:


conv层的调用方法是。

但是,我的方法是否意味着只更新“a”值?我如何验证这一点?那么我如何控制在Keras中更新哪些参数?我怎样才能阻止“b”值的变化,从而使“W”中的变化只是由于“a”中的变化。据我所知,只能设置层
trainable=False
我再次考虑了这一点,并删除了以前的注释。你说得对,只有“层”可以训练/不训练。要控制权重,必须创建自定义层并实现自定义“构建”方法。但是,我的方法是否意味着只更新“a”值?我如何验证这一点?那么我如何控制在Keras中更新哪些参数?我怎样才能阻止“b”值的变化,从而使“W”中的变化只是由于“a”中的变化。据我所知,只能设置层
trainable=False
我再次考虑了这一点,并删除了以前的注释。你说得对,只有“层”可以训练/不训练。要控制权重,必须创建自定义层并实现自定义“构建”方法。非常感谢。我会试试这个。:)您还可以给我一些关于
call()
函数的建议吗?这是我第一次实现自定义Keras层。我需要实现Conv2D功能还是调用Conv2D层功能?不,您只需要这些。查看答案中的更新。感谢更新;真的帮了大忙。还有两个问题:1。我使用层作为
l1=CustConv2D(filters=64,kernel\u size=(11,11),kernelA=None,kernelB=basic\u l1,activation='relu')(img)
\img\u shape=(28,28,1),但我得到的输出是
(None,28,28,1)
,而不是
(None,18,18,1)
2。我得到
ValueError:一个操作有