У вас должны быть весовые коэффициенты, основанные на всех ваших данных (если размер вашей партии не достаточно велик, поэтому у вас есть стабильные весовые коэффициенты).
Если какой-либо класс недостаточно представлен, с небольшим размером пакета, он будет иметь весы бесконечности.
Если целевыми данными являются numpy массив:
shp = y_train.shape
totalPixels = shp[0] * shp[1] * shp[2]
weights = np.sum(y_train, axis=(0, 1, 2)) #final shape (4,)
weights = totalPixels/weights
Если ваши данные находятся в генераторе Sequence
:
totalPixels = 0
counts = np.zeros((4,))
for i in range(len(generator)):
x, y = generator[i]
shp = y.shape
totalPixels += shp[0] * shp[1] * shp[2]
counts = counts + np.sum(y, axis=(0,1,2))
weights = totalPixels / counts
Если ваши данные находятся в генератор yield
(вы должны знать, сколько у вас пакетов за эпоху):
for i in range(batches_per_epoch):
x, y = next(generator)
#the rest is equal to the Sequence example above
Попытка 1
Я не знаю, являются ли более новые версии Keras в состоянии справиться с этим, но сначала вы можете попробовать самый простой подход: просто позвоните fit
или fit_generator
с аргументом class_weight
:
model.fit(...., class_weight = {0: weights[0], 1: weights[1], 2: weights[2], 3: weights[3]})
Попытка 2
Сделайте здоровее функция потерь:
weights = weights.reshape((1,1,1,4))
kWeights = K.constant(weights)
def weighted_cce(y_true, y_pred):
yWeights = kWeights * y_pred #shape (batch, 128, 128, 4)
yWeights = K.sum(yWeights, axis=-1) #shape (batch, 128, 128)
loss = K.categorical_crossentropy(y_true, y_pred) #shape (batch, 128, 128)
wLoss = yWeights * loss
return K.sum(wLoss, axis=(1,2))