我正在使用带有anaconda的Python 3和eager eval的tensorflow 1.12。
我使用它来为连体网络创建三元组损失函数,并需要计算不同数据样本之间的距离。
我创建了一个函数来计算距离,但无论我做什么,当我尝试计算相对于网络输出的梯度时,它都会给出所有nan梯度。
以下是代码:
我使用的是损失函数。
我使用它来为连体网络创建三元组损失函数,并需要计算不同数据样本之间的距离。
我创建了一个函数来计算距离,但无论我做什么,当我尝试计算相对于网络输出的梯度时,它都会给出所有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_pred
和loss
的数据类型均为tf.float32
编辑:在tf中发现了一个已公开的错误报告,这可能是问题所在吗?
编辑:
当我将norm轴更改为0或1时,我得到了合法的值,并且没有出现nan。使用axis=2
进行norm操作时,我得到的是矩阵中行对之间的成对距离,我怀疑这可能与一行到自身的距离为0有关,因此我将值裁剪为最小值为1e-7,但没有成功。
谢谢
y_pred
和loss
的dtype
。 - Ankish Bansalnorm(tensor, axis=2)
或者它上面的转置和减法操作没有梯度。我之前在自定义损失函数时遇到过这个问题,好像与重塑有关?非可导操作似乎会影响梯度计算。 - Engineero