我正在使用带有tensorflow后端的keras . 我的目标是在 custom loss 函数中查询当前批次的 batchsize . 这需要计算自定义损失函数的值,这取决于特定观察的索引 . 鉴于下面的可重复性最低的例子,我想更清楚 .

(顺便说一下:当然我可以使用为训练过程定义的批量大小并在定义自定义损失函数时插入它的值,但是有一些原因可以改变,特别是如果 epochsize % batchsize (epochsize modulo batchsize)不等于零,那么最后一批epoch有不同的大小 . 我没有在stackoverflow中找到合适的方法,特别是例如Tensor indexing in custom loss functionTensorflow custom loss function in Keras - loop over tensorLooping over a tensor因为很明显在构建图形时无法推断出任何张量的形状 . 损失函数 - 只有在给定数据的情况下才能进行形状推断,这只能在给定图形的情况下实现 . 因此,我需要告诉自定义损失函数在不知道尺寸长度的情况下对特定元素执行某些操作 .

(在所有示例中都是相同的)

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) 会出错 . 有没有办法执行此操作?

The traceback of the output:
enter image description here

-------

BTW这是我的真正的自定义损失功能,如果有任何问题 . 为了清晰和简单,我在上面跳过了它 .

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

image loss function: partial negative log-likelihood of the cox proportional harzards model . 这是为了澄清评论中的一个问题,以避免混淆 . 我不认为有必要详细了解这个问题来回答这个问题 .