Keras使用面膜冻结特定重量

时间:2019-07-05 17:24:39

标签: keras convolution masking

我是Keras的新手。我想实现一个并非所有权重都会更新的图层。例如,在下面的代码中,我希望dilation层将以某些中心权重永远不会更新的方式进行更新。可以说,dilation层中每个特征矩阵(1024个中的一个)的形状为448, 448,并且所有特征矩阵中心的8x8块将永远不会更新,即8x8块是特征矩阵的(不可训练的)掩码。

input_layer=Input(shape=(896,896,3))
new_layer = Conv2D(32, kernel_size=(3,3), padding="same", activation='relu', kernel_initializer='he_normal')(input_layer)
new_layer = MaxPooling2D(pool_size=(2, 2), strides=(2,2), padding='same', data_format=None)(new_layer)
new_layer = Conv2D(64, kernel_size=(3,3), padding='same', activation='relu', kernel_initializer='he_normal')(new_layer)
new_layer = Conv2D(1024, kernel_size=(7,7), dilation_rate=8, padding="same", activation='relu', kernel_initializer='he_normal', name='dialation')(new_layer)
new_layer = Conv2D(32, kernel_size=(1,1), padding="same", activation='relu', kernel_initializer='he_normal')(new_layer)
new_layer = Conv2D(32, kernel_size=(1,1), padding="same", activation='relu', kernel_initializer='he_normal')(new_layer)

model = Model(input_layer, new_layer)

我尝试使用Keras的custom layer [link],但是我很难理解。任何人都请帮忙。

更新: 我添加了下图以更好地理解。膨胀层包含1024个要素。我希望每个功能的中间区域都是不可训练的(静态)。

image of dilation layer

1 个答案:

答案 0 :(得分:0)

在两种情况下都使用此掩码:

mask = np.zeros((1,448,448,1))
mask[:,220:228,220:228] = 1

替换部分功能

如果您用恒定值替换部分特征,则表示该特征将是静态的,但仍将参与反向传播(因为权重仍将乘以该部分图像并相加,并且存在连接)

constant = 0 (will annulate kernel, but not bias) 

def replace(x):
    return x*(1-mask) + constant*mask

#before the dilation layer
new_layer=Lambda(replace)(new_layer) 

保留特征值,但停止向后传播

此处,扩张层的权重以及进一步的权重将正常更新,但是扩张层之前的权重将不会受到中心区域的影响。

def stopBackprop(x):
    stopped=K.stop_gradients(x)
    return x*(1-mask) + stopped*mask

#before the dilation layer
new_layer=Lambda(stopBackprop)(new_layer)