【问题标题】:Constraint on the sum of parameters in Keras Layer对 Keras 层中参数总和的约束
【发布时间】:2020-05-21 04:20:11
【问题描述】:

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

提前致谢。

【问题讨论】:

    标签: keras constraints keras-layer activation-function


    【解决方案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()
    

    【讨论】:

    • 很好的答案,但使用keras.backend.softmax,而权重应该是形状为(2,) 的单个张量。然后a=weights[0]b=weights[1]
    • 感谢 Matus Dubrava 和 Daniel Möller。我决定使用 keras.backend.softmax,并按照 Daniel 所说的那样更改权重(单张量)。它有效!
    【解决方案2】:

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

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

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

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-11
      • 1970-01-01
      • 2020-06-02
      • 1970-01-01
      • 1970-01-01
      • 2018-08-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多