keras支持class_weights
功能,允许为不同的类提供不同的权重 - 例如,当样本数量不平衡时
我想做类似的事情,但要根据每批次中的类不平衡使用动态权重。
这可能吗?
答案 0 :(得分:4)
选项1:
为纪元和批次制作手动循环,使用方法train_on_batch
,该方法也接受class_weight
:
for epoch in range(epochs):
for batchX,batchY in batches: #adapt this loop to your way of creating/getting batches
weights = calculateOrGetTheWeights(batch)
model.train_on_batch(batchX,batchY,...,class_weight=weights)
选项2:
创建自定义损失。可能更棘手,取决于数据格式,类的数量,损失函数的类型等。
假设2D数据(样本,类)和多类问题:
import keras.backend as K
def customLoss(yTrue,yPred):
classes = K.argmax(yTrue)
classCount = K.sum(yTrue,axis=0)
loss = K.some_loss_function(yTrue,yPred)
return loss / K.gather(classCount, classes)
假设使用1D或2D数据的二进制分类(仅1类):
import keras.backend as K
def binaryCustomLoss(yTrue,yPred):
positives = yTrue
negatives = 1 - yTrue
positiveRatio = K.mean(positives)
negativeRatio = 1 - positiveRatio #or K.mean(negatives)
weights = (positives / positiveRatio) + (negatives / negativeRatio)
#you may need K.squeeze(weights) here
return weights * K.some_loss_function(yTrue,yPred)
警告:如果任何类计数为零,则两个损失函数都将返回Nan(或无穷大)。
答案 1 :(得分:3)
一种选择是使用样本权重
,而不是使用class_weight
如果您希望样本权重动态,则需要使用fit_generator
代替fit
,这样您就可以在运行时更改权重
所以在伪代码中:
def gen(x, y):
while True:
for x_batch, y_batch in make_batches(x, y):
weights = make_weights(y_batch)
yield x_batch, y_batch, weights
model.fit_generator(gen(x_train, y_train))
在此代码中,make_weights
应返回与y_batch
长度相同的数组。每个元素都是要应用于相应样本的权重
如果您不确定class_weight
的行为和样本权重是否相同,notice keras如何标准化类权重。
因此,类权重实际上最终转化为样本权重:)