我试图对输入张量应用两种不同的屏蔽方法,一种是半正态分布滤波器,另一种是简单的阶跃函数。
尽管半高斯滤波器工作正常,但是当尝试应用阶跃函数滤波器时,变量(即定义阶跃发生的点)似乎根本没有学习。
这是过滤器代码:
def per_kernel_step_filter(input,weight_param=20,trainable=True):
input_shape = input.get_shape().as_list()
weight_param_v = tf.Variable(np.full((input_shape[-1]),weight_param), dtype=tf.float32, trainable=trainable)
weight_param_v_c = tf.clip_by_value(weight_param_v, 0, input_shape[-2])
kernel_filter = tf.transpose(tf.sequence_mask(weight_param_v_c, input_shape[-2], dtype=tf.float32))
kernel_filter = tf.reshape(kernel_filter,tf.concat([(1,1),kernel_filter.get_shape()],0))
output = input * kernel_filter
tf.summary.histogram("weight_param histogram", weight_param_v)
return output
并且weight_param_v
与weight_param
持平。
是否可能由于其他操作(例如sequence_mask
)使该变量变得不可训练?
答案 0 :(得分:1)
在这种情况下,问题是tf.sequence_mask
是不可微的,即没有分析函数可以告诉您如果对{{1 }}。可能的解决方法是改用某些sigmoid或smoothstep函数。例如,您可以使用logistic function(tf.math.sigmoid
)进行偏移,使其以步点为中心,并且您可以操纵要评估的点以控制其“陡峭度”(注意这会影响梯度,进而影响变量的学习能力。
通常,您可以使用tf.gradients
来检查是否有区别。例如,如果您有一个函数weight_param_v
,则可以输入my_function
并定义x
,然后检查y = my_function(x)
的输出;如果它是tf.gradients(y, x)
,则该函数是不可微的。
[None]
我认为在这种情况下发生的一件棘手的事情是,即使存在一些import tensorflow as tf
x = tf.placeholder(tf.float32, [None])
# Squaring is differentiable
print(tf.gradients(tf.square(x), x))
# [<tf.Tensor 'gradients/Square_grad/Mul_1:0' shape=(?,) dtype=float32>]
# Flooring is not differentiable
print(tf.gradients(tf.floor(x), x))
# [None]
# Sequence mask is not differentiable
print(tf.gradients(tf.sequence_mask(x, dtype=tf.float32), x))
# [None]
# Gather is differentiable for the parameters but not for the indices
x2 = tf.placeholder(tf.int32, [None])
print(tf.gradients(tf.gather(x, x2), [x, x2]))
# [<tensorflow.python.framework.ops.IndexedSlices object at 0x000001F6EDD09160>, None]
渐变,训练也可能会起作用。只要存在一些有效的梯度,TensorFlow(或更具体地说,tf.train.Optimizer
及其子类)就假定None
梯度是不相关的。您可以做的一项可能的检查是,而不是直接调用minimize
,而是调用compute_gradients
并在调用apply_gradients
之前检查是否没有None
渐变。