Keras层中参数和的约束
我想在图层的参数上添加自定义约束。 我用两个可训练参数a和b s.t编写了一个自定义激活层:Keras层中参数和的约束,keras,constraints,keras-layer,activation-function,Keras,Constraints,Keras Layer,Activation Function,我想在图层的参数上添加自定义约束。 我用两个可训练参数a和b s.t编写了一个自定义激活层: 激活\u fct=a*fct()+b*fct()。 我需要使参数(a+b)之和等于1,但我不知道如何编写这样的约束。 你能给我一些建议吗 提前谢谢 我想到了两种方法 第一个是锁定其中一个参数,比如说b,并仅使另一个(a在本例中)可训练。然后您可以按如下方式计算b b = 1 - a 第二种方法是使a和b都可培训,并通过softmax功能对其进行转换。Softmax函数将确保其总和始终为1 from s
激活\u 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()
我想到了两种方法 第一个是锁定其中一个参数,比如说
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.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)
然后,在构建权重时,只构建一个约束并使用约束
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
在调用中,b=1-a
:
def call(self, inputs, **kwargs):
#do stuff
....
return (self.a * something) + ((1-self.a)*another_thing)
您也可以尝试@MatusDubrava
softmax
方法,但在这种情况下,您的权重需要具有形状(2,)
,并且没有约束:
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.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)
可以使用单个权重而不是两个,并使用此自定义约束:
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.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)
然后,在构建权重时,只构建一个约束并使用约束
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
在调用中,b=1-a
:
def call(self, inputs, **kwargs):
#do stuff
....
return (self.a * something) + ((1-self.a)*another_thing)
您也可以尝试@MatusDubrava
softmax
方法,但在这种情况下,您的权重需要具有形状(2,)
,并且没有约束:
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.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)
答案很好,但是使用
keras.backend.softmax
,而权重应该是一个带形状的张量(2,)
。然后a=weights[0]
和b=weights[1]
。谢谢Matus Dubrava和Daniel Möller。我决定使用keras.backend.softmax,并按照Daniel所说的更改权重(单张量)。它起作用了!答案很好,但是使用keras.backend.softmax
,而权重应该是一个带形状的张量(2,)
。然后a=weights[0]
和b=weights[1]
。谢谢Matus Dubrava和Daniel Möller。我决定使用keras.backend.softmax,并按照Daniel所说的更改权重(单张量)。它起作用了!