如何在自定义损失函数中遍历张量?

汤玛士

我正在使用带有tensorflow后端的keras。我的目标是batchsize自定义损失函数中查询当前批次的这是计算定制损失函数的值所必需的,该值取决于特定观测值的索引。鉴于以下最少的可重现示例,我想更清楚地说明这一点。

(顺便说一句:当然,我可以使用为训练过程定义的批处理大小,并在定义自定义损失函数时使用它的值,但是有一些原因导致这种变化可以改变,特别是如果epochsize % batchsize(epochsize modulo batchsize)不等于零,那么最后一个时期的大小是不同的,我没有在stackoverflow中找到合适的方法,尤其是例如自定义损失函数中的Tensor索引Keras中的Tensorflow自定义损失函数-在张量上循环在张量上循环因为显然在构建图时无法推断任何张量的形状(损失函数就是这种情况)-形状推断仅在评估给定数据时才有可能,这仅在给定图时才可能。因此,我需要告诉自定义损失函数对沿特定维度的特定元素执行某些操作,而无需知道维度的长度。

(所有示例都一样)

from keras.models import Sequential
from keras.layers import Dense, Activation

# Generate dummy data
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(2, size=(1000, 1))

model = Sequential()
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dense(1, activation='sigmoid'))

示例1:没有问题的没有特别之处,没有自定义损失

model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])    

# Train the model, iterating on the data in batches of 32 samples
model.fit(data, labels, epochs=10, batch_size=32)

(省略输出,这可以很好地运行)

示例2:没有什么特别的,具有相当简单的自定义损失

def custom_loss(yTrue, yPred):
    loss = np.abs(yTrue-yPred)
    return loss

model.compile(optimizer='rmsprop',
              loss=custom_loss,
              metrics=['accuracy'])

# Train the model, iterating on the data in batches of 32 samples
model.fit(data, labels, epochs=10, batch_size=32)

(省略输出,这可以很好地运行)

示例3:问题

def custom_loss(yTrue, yPred):
    print(yPred) # Output: Tensor("dense_2/Sigmoid:0", shape=(?, 1), dtype=float32)
    n = yPred.shape[0]
    for i in range(n): # TypeError: __index__ returned non-int (type NoneType)
        loss = np.abs(yTrue[i]-yPred[int(i/2)])
    return loss

model.compile(optimizer='rmsprop',
              loss=custom_loss,
              metrics=['accuracy'])

# Train the model, iterating on the data in batches of 32 samples
model.fit(data, labels, epochs=10, batch_size=32)

当然,张量还没有形状信息,只有在训练时才能建立图形时无法推断出该信息。因此for i in range(n)产生一个错误。有什么方法可以执行此操作吗?

输出的回溯: 在此处输入图片说明

-------

顺便说一句,这是我真正的自定义损失函数,如有任何疑问。为了清楚和简单起见,我在上面跳过了它。

def neg_log_likelihood(yTrue,yPred):
    yStatus = yTrue[:,0]
    yTime = yTrue[:,1]    
    n = yTrue.shape[0]    
    for i in range(n):
        s1 = K.greater_equal(yTime, yTime[i])
        s2 = K.exp(yPred[s1])
        s3 = K.sum(s2)
        logsum = K.log(y3)
        loss = K.sum(yStatus[i] * yPred[i] - logsum)
    return loss

这是考克斯比例harzards模型的部分负对数似然可能性的图像。

在此处输入图片说明

这是为了澄清注释中的一个问题,以避免混淆。我认为没有必要详细了解这一问题来回答这个问题。

丹尼尔·莫勒

和往常一样,不要循环。存在严重的性能缺陷和错误。除非完全不可避免,否则仅使用后端函数(通常并非不可避免)


示例3的解决方案:

因此,那里有一件很奇怪的事情……

您是否真的要忽略模型预测的一半?(示例3)

假设这是真的,只需在最后一个维度上复制张量,展平并丢弃一半即可。您将获得所需的确切效果。

def custom_loss(true, pred):
    n = K.shape(pred)[0:1]

    pred = K.concatenate([pred]*2, axis=-1) #duplicate in the last axis
    pred = K.flatten(pred)                  #flatten 
    pred = K.slice(pred,                    #take only half (= n samples)
                   K.constant([0], dtype="int32"), 
                   n) 

    return K.abs(true - pred)

损失函数的解决方案:

如果您按从大到小的顺序对时间进行了排序,则只需累加一个总和即可。

警告:如果每个样本一次,则无法进行迷你批次训练!!!
batch_size = len(labels)

像在循环和一维转换网络中那样,在附加维度上有时间是有意义的(每个样本很多次)。无论如何,考虑到您所表达的示例,它的形状(samples_equal_times,)yTime

def neg_log_likelihood(yTrue,yPred):
    yStatus = yTrue[:,0]
    yTime = yTrue[:,1]    
    n = K.shape(yTrue)[0]    


    #sort the times and everything else from greater to lower:
    #obs, you can have the data sorted already and avoid doing it here for performance

    #important, yTime will be sorted in the last dimension, make sure its (None,) in this case
    # or that it's (None, time_length) in the case of many times per sample
    sortedTime, sortedIndices = tf.math.top_k(yTime, n, True)    
    sortedStatus = K.gather(yStatus, sortedIndices)
    sortedPreds = K.gather(yPred, sortedIndices)

    #do the calculations
    exp = K.exp(sortedPreds)
    sums = K.cumsum(exp)  #this will have the sum for j >= i in the loop
    logsums = K.log(sums)

    return K.sum(sortedStatus * sortedPreds - logsums)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在TensorFlow中的自定义损失函数中标准化张量?

在Keras中的自定义损失函数中重塑张量

如何在keras中测试自定义损失函数?

如何在Tensorflow中编写自定义损失函数?

在自定义损失函数中迭代张量

涉及卷积的张量流中的自定义损失函数

在自定义损失函数中重塑张量

自定义损失函数中的张量索引

张量流中的自定义损失函数

如何在张量流中表达此自定义损失函数?

如何在Keras自定义损失函数中使用张量?

Keras:如何在自定义损失中获得张量尺寸?

您如何在 Keras 中编译自定义损失函数,将预测与来自输入张量的信息连接起来?

如何在简单的数学运算中定义keras自定义损失函数

如何在tf.keras自定义损失函数中触发python函数?

如何在mxnet中使用自定义损失函数?

Keras自定义损失函数打印张量值

自定义损失函数访问张量通道

如何在 keras 中创建自定义损失函数?(自定义加权二元交叉熵)

在Keras中设计自定义损失函数(在Keras中以张量为单位的索引)

如何从Keras中的自定义损失函数获取结果?

pyTorch 中的自定义损失函数如何工作?

如何在自定义Keras / Tensorflow损失函数中对值进行排序?

如何在发生器提供的Keras自定义损失函数中访问样本权重?

如何在 Keras 中实现自定义加权 MSE 损失函数?

如何在Keras中包装自定义TensorFlow损失函数?

如何使用过滤自定义张量流损失函数?

如何使用张量流更正此自定义损失函数?

Keras中的自定义损失函数