对于CNN,我需要使用此损失函数,list_distance和list_residual是隐藏层的输出张量,这对于计算损失非常重要,但是当我执行代码时,它会给我返回此错误
TypeError:仅在启用急切执行后,张量对象才可迭代。要遍历此张量,请使用tf.map_fn。
还有另一种方法可以在不使用构造函数的情况下遍历张量 在X中使用x还是将其转换为numpy数组或使用keras的后端函数?
def DBL(y_true, y_pred, list_distances, list_residual, l=0.65):
prob_dist = []
Li = []
# mean of the images power spectrum
S = np.sum([np.power(np.abs(fp.fft2(residual)), 2)
for residual in list_residual], axis=0) / K.shape(list_residual)[0]
# log-ratio between the geometric and arithmetic of S
R = np.log10((scistats.gmean(S) / np.mean(S)))
for c_i, dis_i in enumerate(list_distances):
prob_dist.append([
np.exp(-dis_i) / sum([np.exp(-dis_j) if c_j != c_i else 0 for c_j, dis_j in enumerate(list_distances)])
])
for count, _ in enumerate(prob_dist):
Li.append(
-1 * np.log10(sum([p_j for c_j, p_j in enumerate(prob_dist[count])
if y_pred[count] == 1 and count != c_j])))
L0 = np.sum(Li)
return L0 - l * R
答案 0 :(得分:1)
您需要定义一个自定义函数以填充到tf.map_fn()
-Tensorflow dox
映射器函数使用您定义的函数将(有趣的)现有对象(张量)映射为一个新对象。
它们将自定义函数应用于对象中的每个元素,而不会引起for
循环的麻烦。
例如(未经测试的代码,可能无法在我的手机atm上运行):
def custom(a):
b = a + 1
return b
original = np.array([2,2,2])
mapped = tf.map_fn(custom, original)
# mapped == [3, 3, 3] ... hopefully
Tensorflow示例全部使用lambda
函数,因此如果上述方法不起作用,则可能需要像这样定义函数。 Tensorflow示例:
elems = np.array([1, 2, 3, 4, 5, 6])
squares = map_fn(lambda x: x * x, elems)
# squares == [1, 4, 9, 16, 25, 36]
编辑:
顺便说一句,map函数比for循环更容易并行化-假定对象的每个元素都是唯一处理的-因此您可以通过使用它们来提高性能。
编辑2:
对于“减少总和,但不在此索引上”部分,我强烈建议您开始回顾矩阵运算...如上所述,map
函数以元素为单位工作-他们不知道其他元素。 reduce
函数是您想要的,但是当您尝试执行“ not this index”求和时,即使它们很狡猾... tensorflow还是围绕矩阵操作构建的...不是MapReduce范式。
遵循这些思路可能会有所帮助:
sess = tf.Session()
var = np.ones([3, 3, 3]) * 5
zero_identity = tf.linalg.set_diag(
var, tf.zeros(var.shape[0:-1], dtype=tf.float64)
)
exp_one = tf.exp(var)
exp_two = tf.exp(zero_identity)
summed = tf.reduce_sum(exp_two, axis = [0,1])
final = exp_one / summed
print("input matrix: \n", var, "\n")
print("Identities of the matrix to Zero: \n", zero_identity.eval(session=sess), "\n")
print("Exponential Values numerator: \n", exp_one.eval(session=sess), "\n")
print("Exponential Values to Sum: \n", exp_two.eval(session=sess), "\n")
print("Summed values for zero identity matrix\n ... along axis [0,1]: \n", summed.eval(session=sess), "\n")
print("Output:\n", final.eval(session=sess), "\n")