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
第二种方法可以使 a
和 b
都可训练并通过 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
一旦你有了 w1
和 w2
,你就可以在提到的公式中使用它们来代替 a
和 b
。
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
在call
、b = 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)
我想在层的参数上添加自定义约束。
我编写了一个带有两个可训练参数 a 和 b s.t 的自定义激活层:
activation_fct = a*fct() + b*fct()
。
我需要使参数 (a+b) 的总和等于 1,但我不知道如何编写这样的约束。
你能给我一些建议吗?
提前致谢。
我想到了两种方法。
第一个是锁定其中一个参数,比方说 b
并只使另一个参数(在本例中为 a
)可训练。然后你可以计算 b
如下
b = 1 - a
第二种方法可以使 a
和 b
都可训练并通过 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
一旦你有了 w1
和 w2
,你就可以在提到的公式中使用它们来代替 a
和 b
。
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
在call
、b = 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)