Python 在Keras中使用自定义步骤激活功能会导致;一个操作的梯度为“无”;错误。如何解决这个问题?

Python 在Keras中使用自定义步骤激活功能会导致;一个操作的梯度为“无”;错误。如何解决这个问题?,python,tensorflow,keras,gradient,activation-function,Python,Tensorflow,Keras,Gradient,Activation Function,我正在构建自动编码器,我想把我的值编码成一个逻辑矩阵。但是,当我在一个中间层(所有其他层都使用“relu”)中使用自定义步骤激活功能时,keras会引发以下错误: An operation has `None` for gradient. 我尝试过使用函数,但它不适合我的问题,因为它仍然生成中间值,而我只需要二进制。我知道,在大多数情况下,我的函数没有梯度,但是否可以使用其他函数进行梯度计算,并且仍然使用阶跃函数进行精度和损耗计算 我的激活功能: def binary_activation(x

我正在构建自动编码器,我想把我的值编码成一个逻辑矩阵。但是,当我在一个中间层(所有其他层都使用“relu”)中使用自定义步骤激活功能时,keras会引发以下错误:

An operation has `None` for gradient.
我尝试过使用函数,但它不适合我的问题,因为它仍然生成中间值,而我只需要二进制。我知道,在大多数情况下,我的函数没有梯度,但是否可以使用其他函数进行梯度计算,并且仍然使用阶跃函数进行精度和损耗计算

我的激活功能:

def binary_activation(x):
    ones = tf.ones(tf.shape(x), dtype=x.dtype.base_dtype)
    zeros = tf.zeros(tf.shape(x), dtype=x.dtype.base_dtype)
    return keras.backend.switch(x > 0.5, ones, zeros)
我希望能够使用二进制步骤激活功能来训练网络,然后将其用作典型的自动编码器。类似于中使用的二进制特征映射的东西。

如前所述,您可以使用它为激活函数定义“可反向传播”的梯度

也许是这样的:

@tf.custom_gradient
def binary_activation(x):

    ones = tf.ones(tf.shape(x), dtype=x.dtype.base_dtype)
    zeros = tf.zeros(tf.shape(x), dtype=x.dtype.base_dtype)

    def grad(dy):
        return ...  # TODO define gradient
  return keras.backend.switch(x > 0.5, ones, zeros), grad

其中,
grad
可以简单地返回
dy
,作为线性函数。根据特殊情况,这可能会使某些权重矩阵无限增加/减少,最终达到机器极限。在这些情况下,也许一个“正常”形状的梯度(类似于“S形”的梯度)是一个选项。这个定义正好给出了我想要的。然而,我得到了一个错误:AttributeError:“tuple”对象没有属性“\u keras\u shape”,我使用的是@DanielMöller建议的grad。