问题描述
我需要使用权重初始化自定义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 shapecall(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自定义内核初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!