张量流梯度-获取所有nan值

时间:2019-01-24 12:04:02

标签: python python-3.x tensorflow deep-learning gradient

我将python 3与anaconda结合使用,将tensorflow 1.12与热切的eval结合使用。

我正在使用它为暹罗网络创建三重态损失函数,并且需要计算不同数据样本之间的距离。

我创建了一个函数以创建距离计算,但是无论我做什么,当我尝试计算相对于网络输出的坡度时,它总是给我所有的nan坡度。

这是代码:

def matrix_row_wise_norm(matrix):
    import tensorflow as tf
    tensor = tf.expand_dims(matrix, -1)

    tensor = tf.transpose(tensor, [0, 2, 1]) - tf.transpose(tensor, [2, 0, 1])
    norm = tf.norm(tensor, axis=2)
    return norm

在损失函数中,我正在使用

def loss(y_true, p_pred):
    with tf.GradientTape() as t:
    t.watch(y_pred)
        distance_matrix = matrix_row_wise_norm(y_pred)
        grad = t.gradient(distance_matrix, y_pred)

毕业是所有nan。 我检查了y_pred是由合法值构成的,并且确实如此。 我尝试针对自己创建一个y_pred * 2的渐变,并获得了合法的渐变值。

我在这里想念什么?距离矩阵的创建中的索引是否有问题?


编辑:

y_predloss的dtype均为tf.float32

编辑:在tf中找到一个open bug report-这可能是问题吗?


编辑:

当我将范数轴更改为0或1时,我得到的是合法值,而nan却一无所有。我在axis=2中使用norm的操作是矩阵中行对之间的成对距离,我怀疑这可能与行与自身之间的0距离有关,因此我用min裁剪了值值1e-7,没有任何运气。

谢谢

1 个答案:

答案 0 :(得分:0)

似乎tf.norm遭受数值不稳定,如here

所述

他们还建议使用l2范数,该范数更数字稳定,因此我尝试了该方法,由于0梯度,还获得了nan值。因此,我将它们与梯度修剪一起使用,到目前为止,损失函数正在起作用并且设法收敛。

def last_attempt(y_true,y_pred):     将tensorflow作为tf导入     将numpy导入为np

loss = tf.zeros(1)

for i in range(y_pred.shape[0]):
    dist = tf.gather(y_pred, [i], axis=0)
    y = y_true.numpy().squeeze()
    norm = tf.map_fn(tf.nn.l2_loss, dist-y_pred)

    d = norm.numpy()
    d[np.where(y != y[i])] = 0.0
    max_pos = tf.gather(norm, np.argmax(d))

    d = norm.numpy()
    d[np.where(y == y[i])] = np.inf
    min_neg = tf.gather(norm, np.argmin(d))

    loss += tf.clip_by_value(max_pos - min_neg + tf.constant(1, dtype=tf.float32),
                             1e-8, 1e1)

return loss

有很多空间可以优化该功能,这里是我其他SO question的参考-对此进行了研究。

谢谢