Keras 张量有一个额外的维度并导致 net.evaluate() 的错误结果
Posted
技术标签:
【中文标题】Keras 张量有一个额外的维度并导致 net.evaluate() 的错误结果【英文标题】:Keras tensor has an additional dimension and causes wrong results for net.evaluate() 【发布时间】:2019-12-25 00:02:03 【问题描述】:我想使用度量学习自定义损失函数在 Python 和 Keras 中训练神经网络。损失最小化了相似输入的输出距离,并使不同输入之间的距离最大化。考虑类似输入的部分是:
# function to create a pairwise similarity matrix, i.e
# L[i,j] == 1 for similar samples i, j and 0 otherwise
def build_indicator_matrix(y_, thr=0.1):
# y_: contains the labels of the samples,
# samples are similar in case of same label
# prevent checking equality of floats --> check if absolute
# differences are below threshold
lbls_diff = K.expand_dims(y_, axis=0) - K.expand_dims(y_, axis=1)
lbls_thr = K.less(K.abs(lbls_diff), thr)
# cast bool tensor back to float32
L = K.cast(lbls_thr, 'float32')
# POSSIBLE WORKAROUND
#L = K.sum(L, axis=2)
return L
# function to compute the (squared) Euclidean distances between all pairs
# of samples, store in DIST[i,j] the distance between output y_pred[i,:] and y_pred[j,:]
def compute_pairwise_distances(y_pred):
DIFF = K.expand_dims(y_pred, axis=0) - K.expand_dims(y_pred, axis=1)
DIST = K.sum(K.square(DIFF), axis=-1)
return DIST
# function to compute the average distance between all similar samples
def my_loss(y_true, y_pred):
# y_true: contains true labels of the samples
# y_pred: contains network outputs
L = build_indicator_matrix(y_true)
DIST = compute_pairwise_distances(y_pred)
return K.mean(DIST * L, axis=1)
为了训练,我将一个形状为(n,)
的numpy 数组y
作为目标变量传递给my_loss
。但是,我发现(使用 TensorBoard 中的计算图)tensorflow 后端从y
(显示形状? x ?
)创建了一个2D 变量,因此build_indicator_matrix
中的L
不是2 维而是3 维(形状 ? x ? x ?
在 TensorBoard 中)。这会导致net.evaulate()
和net.fit()
计算错误的结果。
为什么 tensorflow 创建 2D 而不是 1D 数组?这对net.evaluate()
和net.fit()
有何影响?
作为快速解决方法,我发现将 build_indicator_matrix()
替换为用于计算 L
的静态 numpy 代码,或者使用 L = K.sum(L, axis=2)
行折叠“假”维度可以解决问题。然而,在后一种情况下,K.eval(build_indicator_matrix(y))
的输出只有(n,)
的形状而不是(n,n)
,所以我不明白为什么这种解决方法仍然会产生正确的结果。为什么 tensorflow 会引入额外的维度?
我的库版本是:
keras:2.2.4 张量流:1.8.0 numpy:1.15.0【问题讨论】:
【参考方案1】:这是因为evaluate
和fit
分批工作。
您在 tensorboard 中看到的第一个维度是批量维度,事先未知,因此表示为 ?
。
使用自定义指标时,请记住您获得的张量(y_true
和 y_pred
)是与批次对应的张量。
有关详细信息,请向我们展示您如何调用这两个函数。
【讨论】:
以上是关于Keras 张量有一个额外的维度并导致 net.evaluate() 的错误结果的主要内容,如果未能解决你的问题,请参考以下文章