我需要用权重初始化自定义的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,但我不确定权重。
我认为这个实现是不正确的,因为我从我的模型中得到了类似的结果,不管有没有自定义初始化。
如果有人能指出我的方法中的任何错误,或者提供一种方法来验证它,那将是非常有帮助的。
发布于 2018-07-10 13:33:08
关于您的形状的警告:如果您的内核大小为(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自定义层的提示
当您从零(从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):。
https://stackoverflow.com/questions/51265578
复制相似问题