【问题标题】:Define loss function in keras using itertools使用 itertools 在 keras 中定义损失函数
【发布时间】:2019-01-19 09:26:47
【问题描述】:

我想定义一个损失函数,它表示隐藏层输出点之间的距离。首先,我在没有 keras 的情况下写了这个

import numpy as np
import itertools
pts = np.array([
    [10,10,10],
    [10,11,20],
    [20,11,30],
    [20,10,10],
    [10,10,20],
    ])
diff = list(itertools.combinations(pts, 2))

ptdiff = lambda (p1,p2): (np.sqrt(np.sum((p1 - p2) ** 2)))
diffs = map(ptdiff, diff)
np.mean(diffs)

我得到了结果。我在keras中尝试了这个损失函数,z是隐藏层的输出,是一个矩阵

定义损失函数

def vae_loss(z):
    z_diff = list(itertools.combinations(z,2))
    ptdiff = lambda (p1,p2): (np.sqrt(np.sum((p1 - p2) ** 2)))
    z_diffs = map(ptdiff, z_diff)
    loss = K.mean(z_diffs)
    return loss

但它显示TypeError: 'Tensor' object is not iterable.,我只是想知道我该如何解决这个问题。

【问题讨论】:

  • 出于好奇:为什么要使用这个损失函数?您是否考虑过使用熵作为矩阵行之间差异的度量?缩放对您的应用程序重要吗?
  • 感谢您的帮助。我想使用这个损失函数来使特征空间中的数据点尽可能接近。我想测量矩阵的每两行之间的差异?

标签: python tensorflow keras itertools loss-function


【解决方案1】:

基于this 非常有用的问题,您可以利用 Keras 的广播属性。我假设您在 TensorFlow 后端运行 Keras。来自TFdocs直播:

出现了一种特殊情况,也支持这种情况,其中每个输入 数组在不同的索引处具有退化维度。在这种情况下, 结果是“外部操作”。

您的 numpy 代码的可重现示例如下:

import numpy as np
import itertools

# Generate 100 random points in a 5-D space
n_dim = 5
matrix = np.random.rand(1000, 5)

# List all possible combinations
combinations = list(itertools.combinations(matrix.tolist(), 2))

def mse(tup):
    """MSE between first and second element of a tuple of lists"""
    return np.mean((np.array(tup[0]) - np.array(tup[1]))**2)

avg_mse = np.mean([mse(c) for c in combinations])
print('Average mse: {:.3f}'.format(avg_mse))

在我的情况下,这将返回 Average mse: 0.162

根据上面提到的问题,您可以按如下方式构建您的损失函数:

import keras.backend as K

# Wrap our random matrix into a tensor
tensor = K.constant(value=matrix)

def loss_function(x):
    x_ = K.expand_dims(tensor, axis=0)
    x__ = K.expand_dims(tensor, axis=1)

    # Compute mse for all combinations, making use of broadcasting
    z = K.mean(K.square(x_ - x__), axis=-1)

    # Return average mse
    return(K.mean(z))

with K.get_session() as sess:
    print('Average mse: {:.3f}'.format(loss_function(tensor).eval()))

返回给我Average mse: 0.162

请注意,此实现不会完全复制您的 numpy 示例中的行为。不同之处在于,还考虑了行与自身的所有组合(itertools.combinations 不是这种情况)并且组合被考虑两次:mse((row1, row2))mse((row2, row1)) 都将被计算,而你的 @987654330 又不是这种情况@ 代码。正如我的示例所示,对于具有大量行的矩阵,这不应该有太大的区别。

【讨论】:

    猜你喜欢
    • 2018-07-22
    • 2016-12-07
    • 1970-01-01
    • 2020-12-19
    • 2017-12-18
    • 2020-03-27
    • 1970-01-01
    • 2018-10-28
    • 2017-12-29
    相关资源
    最近更新 更多