Keras Layer 中参数总和的约束

Constraint on the sum of parameters in Keras Layer

我想在层的参数上添加自定义约束。 我编写了一个带有两个可训练参数 a 和 b s.t 的自定义激活层: activation_fct = a*fct() + b*fct()。 我需要使参数 (a+b) 的总和等于 1,但我不知道如何编写这样的约束。 你能给我一些建议吗?

提前致谢。

我想到了两种方法。

第一个是锁定其中一个参数,比方说 b 并只使另一个参数(在本例中为 a)可训练。然后你可以计算 b 如下

b = 1 - a

第二种方法可以使 ab 都可训练并通过 softmax 函数转换它们。 Softmax 函数将确保它们的总和始终为 1。

from scipy.special import softmax

a = 0.12
b = 0.3
w1, w2 = softmax([a, b])

print(f'w1: {w1}, w2: {w2}, w1 + w2: {w1 + w2}')

这将产生

w1: 0.45512110762641994, w2: 0.5448788923735801, w1 + w2: 1.0

一旦你有了 w1w2,你就可以在提到的公式中使用它们来代替 ab

activation_fct = w1 * fct() + w2 * fct()

您可以使用一个权重而不是两个权重,并使用此自定义约束:

import keras.backend as K

class Between_0_1(keras.constraints.Constraint):
    def __call__(self, w):
        return K.clip(w, 0, 1)

然后在构建权重时,只构建一个并使用约束。

def build(self, input_shape):
    self.a = self.add_weight(name='weight_a', 
                                  shape=(1,),
                                  initializer='uniform',
                                  constraint = Between_0_1(), 
                                  trainable=True)

    #if you want to start as 0.5
    K.set_value(self.a, [0.5])

    self.built = True

callb = 1-a中:

def call(self, inputs, **kwargs):
    #do stuff
    ....

    return (self.a * something) +  ((1-self.a)*another_thing)

您也可以尝试@MatusDubrava softmax 方法,但在这种情况下,您的权重需要具有形状 (2,),并且没有约束:

def build(self, input_shape):
    self.w = self.add_weight(name='weights', 
                              shape=(2,),
                              initializer='zeros',
                              trainable=True)
    self.build = True

def call(self, inputs, **kwargs):
    w = K.softmax(self.w)

    #do stuff
    ....

    return (w[0] * something ) + (w[1] * another_thing)