我有一个关于tf.keras.constraints方法的问题。
(1)
class WeightsSumOne(tf.keras.constraints.Constraint):
def __call__(self, w):
return tf.nn.softmax(w, axis=0)
output = layers.Dense(1, use_bias=False,
kernel_constraint = WeightsSumOne())(input)
(2)
intermediate = layers.Dense(1, use_bias = False)
intermediate.set_weights(tf.nn.softmax(intermediate.get_weights(), axis=0))
(1(和(2(是否执行相同的过程?
我问这个问题的原因是Keras Documentation说
它们是应用于目标的每变量投影函数每次梯度更新后的变量(使用fit((时(。(https://keras.io/api/layers/constraints/)
与(1(不同,我认为在(2(的情况下,在每次梯度更新之前都会应用约束。
在我看来,(1(和(2(的权重的梯度是不同的,因为在第二种情况下在梯度计算之前应用softmax,但在第一种情况下是在梯度计算之后应用softmax。
如果我错了,如果你指出错误的部分,我将不胜感激。
它们不一样。
在第一种情况下,约束被应用于weights
,但在第二种情况下它在dense
层的输出上(在与输入相乘之后(。
在第一种情况下构建模型:
inp = keras.Input(shape=(3,5))
out = keras.layers.Dense(1, use_bias=False, kernel_initializer=tf.ones_initializer(),
kernel_constraint= WeightsSumOne())(inp)
model = keras.Model(inp, out)
model.compile('adam', 'mse')
模拟运行,
inputs = tf.random.normal(shape=(1,3,5))
outputs = tf.random.normal(shape=(1,3,1))
model.fit(inputs,outputs, epochs=1)
检查model
的层权重
print(model.layers[1].get_weights()[0])
#outputs
array([[0.2],
[0.2],
[0.2],
[0.2],
[0.2]]
在第二种情况中构建模型
inp = keras.Input(shape=(3,5))
out = keras.layers.Dense(1, activation='softmax', use_bias=False,
kernel_initializer=tf.ones_initializer())(inp)
model1 = keras.Model(inp, out)
model1.compile('adam', 'mse')
#dummy run
model1.fit(inputs,outputs, epochs=1)
检查模型1、的层权重
print(model1.layers[1].get_weights()[0])
#outputs
array([[1.],
[1.],
[1.],
[1.],
[1.]],
我们可以看到layer weight of model
是layer weight of model1
的softmax