是否可以在张量流神经网络输出节点之间实施数学约束?

Is it possible to enforce mathematical constraints between tensorflow neural network output nodes?

基本上是这样的:

是否可以在最后一层的 tensorflow 神经网络输出节点之间实施数学约束?

例如,节点之间的单调性,例如输出节点1大于节点2,而节点2又大于节点3,等等。

有很多方法,一种是神经元学习,第二种是数学 Fn,或者两者都通过分数权重或奖励或从其他神经元学习。

This is one way I teach the networks to lean, you may study from the online sample.

X = tf.compat.v1.placeholder(tf.float32, shape=( (10, 88, 80, 4)))
y = tf.compat.v1.placeholder(tf.float32, shape=(1, 1))
X_action = tf.compat.v1.get_variable('X_action', dtype = tf.float32, initializer = tf.random.normal((1, 1))) # X_var
in_training_mode = tf.compat.v1.get_variable('in_training_mode', dtype = tf.float32, initializer = tf.random.normal((1, 1))) # X_var

loss = tf.reduce_mean(input_tensor=tf.square((X * y) - (X * X_action))) *
optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate)
training_op = optimizer.minimize(loss)

This is another way me for the similar tasks with simple configuration just select the correct optimizer and loss Fn that performs faster learning, the previous sample is just Error roots mean sequare.

optimizer = tf.keras.optimizers.Nadam(
    learning_rate=0.00001, beta_1=0.9, beta_2=0.999, epsilon=1e-07,
    name='Nadam'
)
lossfn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
model.compile(optimizer=optimizer, loss=lossfn, metrics=['accuracy'])current version.

总的来说——不是真的,至少不是直接的。 Keras 层支持 weights 上的约束参数,您可以将所需的输出约束转换为权重约束——但否则,您将需要考虑如何设置建立你的网络结构,使约束得到满足。

这是单调约束如何可能的草图。实际上将其包含在模型中可能需要创建自定义 Layer 子类或者可能使用功能 API.

首先,让我们创建一些虚拟数据。这可能是标准 Dense 层的输出(4 是批量大小,5 是输出数量)。

raw_outputs = tf.random.normal([4, 5])
>>> <tf.Tensor: shape=(4, 5), dtype=float32, numpy=
array([[ 0.3989258 , -1.7693167 ,  0.13419539,  1.1059834 ,  0.3271042 ],
       [ 0.6493515 , -1.4397207 ,  0.05153034, -0.2730962 , -1.1569825 ],
       [-1.3043666 ,  0.20206456, -0.3841469 ,  1.8338723 ,  1.2728293 ],
       [-0.3725195 ,  1.1708363 , -0.01634515, -0.01382025,  1.2707714 ]],
      dtype=float32)>

接下来,使用 softplus 使所有输出为正。将其视为输出激活函数。 returns values >= 0 的任何函数都可以。例如,您可以使用 tf.exp,但指数增长可能会导致数值问题。我不推荐 relu,因为硬 0 会阻止梯度流动——这在输出层通常是个坏主意。

positive_outputs = tf.nn.softplus(raw_outputs)
>>> <tf.Tensor: shape=(4, 5), dtype=float32, numpy=
array([[0.9123723 , 0.15738781, 0.7624942 , 1.3918277 , 0.8700147 ],
       [1.0696293 , 0.21268418, 0.71924424, 0.56589293, 0.2734058 ],
       [0.24007489, 0.7992745 , 0.5194075 , 1.9821143 , 1.5197192 ],
       [0.5241344 , 1.4409455 , 0.685008  , 0.68626094, 1.5181118 ]],
      dtype=float32)>

最后,使用cumsum将数值相加:

constrained = tf.cumsum(positive_outputs, reverse=True, axis=-1)

>>> <tf.Tensor: shape=(4, 5), dtype=float32, numpy=
array([[4.0940967, 3.1817245, 3.0243368, 2.2618425, 0.8700147],
       [2.8408566, 1.7712271, 1.558543 , 0.8392987, 0.2734058],
       [5.0605907, 4.8205156, 4.021241 , 3.5018334, 1.5197192],
       [4.8544607, 4.3303266, 2.889381 , 2.204373 , 1.5181118]],
      dtype=float32)>

正如我们所见,每个批次元素的输出单调递减!这是因为我们的每个原始输出 (positive_outputs) 基本上只是编码每个单元 added 的数量,并且因为我们强制它们为正数,所以数字只能得到更大(或在这种情况下更小,因为 cumsum 中的 reverse=True)。