我应该使用什么激活函数来强制执行类似舍入的行为



我需要一个激活函数来舍入张量。

函数round((的导数(梯度(为0(或tensorflow中的None(,这使得它不能用作激活函数。

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

我知道公式:tanh○sigmoid被用来强制{-1,0,1}个数字只在模型中流动,那么是否有一些函数的组合可以模拟舍入行为?

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

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中注册您自己的梯度(例如,请参阅这个问题(。然而,我对实现这一部分并不熟悉,因为我不经常使用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)

也许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

最新更新