Tensorflow-可训练变量不会随时间变化

时间:2019-03-19 13:33:16

标签: python tensorflow

我试图对输入张量应用两种不同的屏蔽方法,一种是半正态分布滤波器,另一种是简单的阶跃函数。

尽管半高斯滤波器工作正常,但是当尝试应用阶跃函数滤波器时,变量(即定义阶跃发生的点)似乎根本没有学习。

这是过滤器代码:

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

从张量板看来,它甚至最后都没有附加到Adam优化器上。enter image description here

并且weight_param_vweight_param持平。

是否可能由于其他操作(例如sequence_mask)使该变量变得不可训练?

1 个答案:

答案 0 :(得分:1)

在这种情况下,问题是tf.sequence_mask是不可微的,即没有分析函数可以告诉您如果对{{1 }}。可能的解决方法是改用某些sigmoidsmoothstep函数。例如,您可以使用logistic functiontf.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渐变。