我应该使用什么激活函数来强制四舍五入行为

时间:2018-08-07 18:31:34

标签: python tensorflow neural-network derivative activation-function

我需要一个能使张量取整的激活函数。

函数round()的导数(梯度)为0(或在Tensorflow中为None),这使其无法用作激活函数。

我正在寻找一种强制执行类似舍入行为的函数,以使我的模型结果不只是近似于一个数字。 (因为我的标签是整数)

我知道公式tanh○sigmoid仅用于强制{-1,0,1}数字流经模型,因此是否存在可推导的模拟舍入行为的函数组合?

2 个答案:

答案 0 :(得分:0)

也许您正在寻找带有softmax函数tf.nn.softmax_cross_entropy_with_logits_v2的交叉熵损失,请参见

https://www.tensorflow.org/api_docs/python/tf/nn/softmax_cross_entropy_with_logits_v2

也看看

https://deepnotes.io/softmax-crossentropy

答案 1 :(得分:0)

如果您想在实线上近似取整,可以执行以下操作:

def approx_round(x, steepness=1):
    floor_part = tf.floor(x)
    remainder = tf.mod(x, 1)
    return floor_part + tf.sigmoid(steepness*(remainder - 0.5))

事实上,有多种方法可以在Tensorflow中注册自己的渐变(例如,参见this question)。但是,我对实现这一部分并不熟悉,因为我不经常使用Keras / TensorFlow。

关于函数,它会为您提供近似值的梯度,如下所示:

def approx_round_grad(x, steepness=1):
    remainder = tf.mod(x, 1)
    sig = tf.sigmoid(steepness*(remainder - 0.5))
    return sig*(1 - sig)

为清楚起见,此近似值假设您使用的是“足够陡峭”的steepness参数,因为sigmoid函数除大参数的限制外不会精确地变为0或1。 >

要执行类似半罪恶近似的操作,可以使用以下代码:

def approx_round_sin(x, width=0.1):
    if width > 1 or width <= 0:
        raise ValueError('Width must be between zero (exclusive) and one (inclusive)')
    floor_part = tf.floor(x)
    remainder = tf.mod(x, 1)
    return (floor_part + clipped_sin(remainder, width))

def clipped_sin(x, width):
    half_width = width/2
    sin_part = (1 + tf.sin(np.pi*((x-0.5)/width)))/2
    whole = sin_part*tf.cast(tf.abs(x - 0.5) < half_width, tf.float32)
    whole += tf.cast(x > 0.5 + half_width, tf.float32)
    return whole

def approx_round_grad_sin(x, width=0.1):
    if width > 1 or width <= 0:
        raise ValueError('Width must be between zero (exclusive) and one (inclusive)')
    remainder = tf.mod(x, 1)
    return clipped_cos(remainder, width)

def clipped_cos(x, width):
    half_width = width/2
    cos_part = np.pi*tf.cos(np.pi*((x-0.5)/width))/(2*width)
    return cos_part*tf.cast(tf.abs(x - 0.5) < half_width, dtype=tf.float32)