gpt4 book ai didi

deep-learning - 我可以在 keras 层之间共享权重但其他参数不同吗?

转载 作者:行者123 更新时间:2023-12-04 00:49:25 25 4
gpt4 key购买 nike

在 keras 中,是否可以在两层之间共享权重,但其他参数不同?考虑以下(诚然有点做作)示例:

conv1 = Conv2D(64, 3, input_shape=input_shape, padding='same')
conv2 = Conv2D(64, 3, input_shape=input_shape, padding='valid')

请注意,除了 padding 之外,层是相同的。 .我可以让 keras 对两者使用相同的权重吗? (即也相应地训练网络?)

我看过 keras 文档和 section on shared layers似乎暗示只有当层完全相同时共享才有效。

最佳答案

据我所知,这无法通过 Keras 使用的常见“API 级别”来完成。
但是,如果您深入挖掘,有一些(丑陋的)方法可以共享权重。

首先,Conv2D的权重图层是在 build() 内创建的函数,通过调用 add_weight() :

    self.kernel = self.add_weight(shape=kernel_shape,
initializer=self.kernel_initializer,
name='kernel',
regularizer=self.kernel_regularizer,
constraint=self.kernel_constraint)

对于您提供的用法(即默认 trainable/ constraint/ regularizer/ initializer ), add_weight()除了将权重变量附加到 _trainable_weights 之外,没有什么特别的。 :

    weight = K.variable(initializer(shape), dtype=dtype, name=name)
...
self._trainable_weights.append(weight)

最后,由于 build()仅在内部调用 __call__()如果层尚未构建,层之间的共享权重可以通过以下方式创建:
  • 调用 conv1.build()初始化 conv1.kernelconv1.bias共享变量。
  • 调用 conv2.build()初始化图层。
  • 替换 conv2.kernelconv2.bias来自 conv1.kernelconv1.bias .
  • 删除 conv2.kernelconv2.bias来自 conv2._trainable_weights .
  • 追加 conv1.kernelconv1.biasconv2._trainable_weights .
  • 完成模型定义。这里conv2.__call__()将被调用;然而,由于 conv2已经构建,权重不会被重新初始化。

  • 以下代码片段可能会有所帮助:

    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 shared
    input_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 fitting
    left = 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]

    这种 hacky 权重共享的一个缺点是,在模型保存/加载后,权重不会保持共享。这不会影响预测,但如果您想加载训练好的模型以进行进一步微调,则可能会出现问题。

    关于deep-learning - 我可以在 keras 层之间共享权重但其他参数不同吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45245396/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com