我试图对卷积层施加一些约束,但似乎不起作用。
import tensorflow as tf
import numpy as np
c2 = tf.keras.layers.Conv2D(filters=1, kernel_size=3, strides=(1, 1),
kernel_initializer=tf.keras.initializers.constant(-20.),
kernel_constraint=tf.keras.constraints.non_neg(), padding='valid')
x = np.reshape([1. for i in range(9)], (1, 3, 3, 1))
y = c2(x)
print(y)
我希望答案为0,但它却给了我
tf.Tensor([[[[-180.]]]], shape=(1, 1, 1, 1), dtype=float32)
忽略kernel_constraint函数。
我想念东西还是虫子?顺便说一句,我使用Windows作为平台
归结为首次构建Layer对象时,初始化程序还是约束优先。在这种情况下,似乎初始化器具有优先权。考虑到Keras约束文档中所说的内容,这是有道理的:
“约束模块的功能允许设置约束(例如非负性)优化过程中的网络参数。“
(参考:https://keras.io/constraints/)。
关键词是“优化中”。就您的代码示例而言,不涉及优化(即,无需培训或fit()
)调用。您的代码可以稍作修改,以显示约束实际上是有效的:
import tensorflow as tf
import numpy as np
c2 = tf.keras.layers.Conv2D(filters=1, kernel_size=3, strides=(1, 1),
kernel_initializer=tf.keras.initializers.constant(-20.),
kernel_constraint=tf.keras.constraints.non_neg(), padding='valid')
x = tf.constant(np.reshape([1. for i in range(9)], (1, 3, 3, 1)))
optimizer = tf.optimizers.SGD(0.01)
with tf.GradientTape() as tape:
y = c2(x)
print(y)
gradients = tape.gradient(y, c2.variables)
optimizer.apply_gradients(zip(gradients, c2.variables))
print(c2.get_weights()) # <-- See that the weights are all 0s now.