我需要一个能使张量取整的激活函数。
函数round()的导数(梯度)为0(或在Tensorflow中为None),这使其无法用作激活函数。
我正在寻找一种强制执行类似舍入行为的函数,以使我的模型结果不只是近似于一个数字。 (因为我的标签是整数)
我知道公式tanh○sigmoid仅用于强制{-1,0,1}数字流经模型,因此是否存在可推导的模拟舍入行为的函数组合?
答案 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
也看看
答案 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)