Я пытаюсь решить проблему двоичной классификации с помощью Keras, используя метод ImageDataGenerator.flow_from_directory
для создания пакетов. Однако мои классы очень несбалансированы, например, в 8 или 9 раз больше в одном классе, чем в другом, что приводит к тому, что модель застревает, предсказывая один и тот же выходной класс для каждого примера. Есть ли способ установить flow_from_directory
либо для избыточной выборки из моего маленького класса, либо для недостаточной выборки из моего большого класса в каждую эпоху? На данный момент я только что создал несколько копий каждого изображения в своем меньшем классе, но мне хотелось бы иметь немного больше гибкости.
keras flow_from_directory изменяет или занижает выборку класса
Ответы:
В текущей версии Keras невозможно сбалансировать набор данных, используя только встроенные методы Keras. flow_from_directory
просто создает список всех файлов и их классов, перетасовывает его (при необходимости), а затем перебирает его.
Но можно было сделать и другой трюк - написать свой генератор, который делал бы балансировку внутри python
:
def balanced_flow_from_directory(flow_from_directory, options):
for x, y in flow_from_directory:
yield custom_balance(x, y, options)
Здесь custom_balance
должна быть функция, которая с учетом пакета (x, y)
балансирует его и возвращает сбалансированный пакет (x', y')
. Для большинства приложений размер пакета не обязательно должен быть одинаковым, но есть некоторые странные варианты использования (например, stateful RNN) - где размеры пакетов должны иметь фиксированный размер).
Одна вещь, которую вы можете сделать, это установить параметр class_weight
при вызове model.fit()
или model.fit_generator()
.
Также случается, что вы можете легко вычислить свои class_weights, используя библиотеки sklearn
и numpy
следующим образом:
from sklearn.utils import class_weight
import numpy as np
class_weights = class_weight.compute_class_weight(
'balanced',
np.unique(train_generator.classes),
train_generator.classes)
После этого все становится так же просто, как установить параметр class_weights
равным class_weight
:
model.fit_generator(..., class_weight=class_weights)
np.unique(train_generator.classes)
вернет классы в правильном порядке? 18.09.2018 Вы также можете рассчитать количество файлов в каждом классе и нормализовать class_weights.
files_per_class = []
for folder in os.listdir(input_foldr):
if not os.path.isfile(folder):
files_per_class.append(len(os.listdir(input_foldr + '/' + folder)))
total_files = sum(files_per_class)
class_weights = {}
for i in xrange(len(files_per_class)):
class_weights[i] = 1 - (float(files_per_class[i]) / total_files)
print (class_weights)
...
...
...
model.fit_generator(... ,class_weight=class_weights)