Ana*_*kin 0 python conv-neural-network keras
我需要用权重初始化自定义 Conv2D 内核
W = a1b1 + a2b2 + ... + anbn
其中 W = 要初始化的 Conv2D 层的自定义权重
a = 随机权重张量 as keras.backend.variable(np.random.uniform()), shape=(64, 1, 10)
b = 固定基础滤波器定义为keras.backend.constant(...), shape=(10, 11, 11)
W = K.sum(a[:, :, :, None, None] * b[None, None, :, :, :], axis=2) #shape=(64, 1, 11, 11)
我希望我的模型更新“W”值,只更改“a”,同时保持“b”不变。
我通过自定义 'W' 作为
Conv2D(64, kernel_size=(11, 11), activation='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但我不确定权重。
我认为实现是不正确的,因为无论有没有自定义初始化,我的模型都会得到类似的结果。
如果有人能指出我方法中的任何错误或提供一种验证方法,那将非常有帮助。
关于形状的警告:如果您的内核大小为(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
Run Code Online (Sandbox Code Playgroud)
当您从零(派生自Layer)创建自定义图层时,您应该拥有以下方法:
__init__(self, ... parameters ...)- 这是创建者,当您创建图层的新实例时会调用它。在这里,您存储用户作为参数传递的值。(在 Conv2D 中,init 将具有“过滤器”、“kernel_size”等)build(self, input_shape) - 这是你应该创建权重的地方(所有可学习的变量都在这里创建,基于输入形状)compute_output_shape(self,input_shape) - 在这里您根据输入形状返回输出形状call(self,inputs) - 在这里您执行实际的层计算由于我们不是从零创建这个层,而是从 派生它Conv2D,一切都准备好了,我们所做的就是“改变”构建方法并替换被认为是 Conv2D 层的内核。
更多关于自定义层:https : //keras.io/layers/writing-your-own-keras-layers/
callconv层的方法在这里class _Conv(Layer):。
| 归档时间: |
|
| 查看次数: |
5397 次 |
| 最近记录: |