Finally, since build() is only called inside __call__() if the layer hasn't been built, shared weights between layers can be created by:调用 conv1.build() 来初始化要共享的 conv1.kernel 和 conv1.bias 变量.调用 conv2.build() 来初始化层.将 conv2.kernel 和 conv2.bias 替换为 conv1.kernel 和 conv1.bias.从 conv2._trainable_weights 中删除 conv2.kernel 和 conv2.bias.将 conv1.kernel 和 conv1.bias 附加到 conv2._trainable_weights.完成模型定义.这里 conv2.__call__() 将被调用;但是,由于 conv2 已经构建,因此不会重新初始化权重.Call conv1.build() to initialize the conv1.kernel and conv1.bias variables to be shared.Call conv2.build() to initialize the layer.Replace conv2.kernel and conv2.bias by conv1.kernel and conv1.bias.Remove conv2.kernel and conv2.bias from conv2._trainable_weights.Append conv1.kernel and conv1.bias to conv2._trainable_weights.Finish model definition. Here conv2.__call__() will be called; however, since conv2 has already been built, the weights are not going to be re-initialized.以下代码片段可能会有所帮助:The following code snippet may be helpful:def create_shared_weights(conv1, conv2, input_shape): with K.name_scope(conv1.name): conv1.build(input_shape) with K.name_scope(conv2.name): conv2.build(input_shape) conv2.kernel = conv1.kernel conv2.bias = conv1.bias conv2._trainable_weights = [] conv2._trainable_weights.append(conv2.kernel) conv2._trainable_weights.append(conv2.bias)# check if weights are successfully sharedinput_img = Input(shape=(299, 299, 3))conv1 = Conv2D(64, 3, padding='same')conv2 = Conv2D(64, 3, padding='valid')create_shared_weights(conv1, conv2, input_img._keras_shape)print(conv2.weights == conv1.weights) # True# check if weights are equal after model fittingleft = conv1(input_img)right = conv2(input_img)left = GlobalAveragePooling2D()(left)right = GlobalAveragePooling2D()(right)merged = concatenate([left, right])output = Dense(1)(merged)model = Model(input_img, output)model.compile(loss='binary_crossentropy', optimizer='adam')X = np.random.rand(5, 299, 299, 3)Y = np.random.randint(2, size=5)model.fit(X, Y)print([np.all(w1 == w2) for w1, w2 in zip(conv1.get_weights(), conv2.get_weights())]) # [True, True]这种笨拙的权重共享的一个缺点是,在模型保存/加载后,权重不会保持共享.这不会影响预测,但如果你想加载训练好的模型进行进一步的微调,可能会出现问题.One drawback of this hacky weight-sharing is that the weights will not remain shared after model saving/loading. This will not affect prediction, but it may be problematic if you want to load the trained model for further fine-tuning. 这篇关于我可以在 keras 层之间共享权重但其他参数不同吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
07-13 09:59