У меня проблема классификации по нескольким меткам. Моя переменная ответа - 5-мерный вектор. То есть каждое наблюдение / образец имеет вектор ответа, который имеет 5 столбцов. Значением каждого столбца может быть только 0 или 1 (так что это не проблема мультикласса), но один образец может иметь много единиц в своем векторе ответов. Например, это 3 выборки с их переменными ответа
Sample 1: [0, 1, 1, 0, 0]
Sample 2: [1, 0, 0, 0, 0]
Sample 3: [1, 1, 1, 0, 0]
Если вы возьмете каждый отдельный столбец в векторе ответа, число 1 будет ОЧЕНЬ низким по сравнению с числом 0. В большинстве случаев 1 вносят только менее 5%. Таким образом, проблема дисбаланса класса должна быть решена.
У меня есть четырехслойная нейронная сеть в Керасе, построенная следующим образом. Обратите внимание, что x_train, x_test, y_train, y_test
- векторы ввода и вывода / ответа. Таким образом, y_train и y_test являются векторами ответов набора поездов и тестов соответственно.
input = Input(shape=(800,))
input_drop = Dropout(rate=0.25)(input_img)
encoded = Dense(30, activation=None)(input_drop)
batch = BatchNormalization()(encoded)
act = PReLU()(batch)
drop = Dropout(rate, noise_shape=None, seed=None)(act)
encoded = Dense(30, activation=None)(drop)
batch = BatchNormalization()(encoded)
act = PReLU()(batch)
drop = Dropout(rate, noise_shape=None, seed=None)(act)
encoded = Dense(30, activation=None)(drop)
batch = BatchNormalization()(encoded)
act = PReLU()(batch)
drop = Dropout(rate, noise_shape=None, seed=None)(act)
encoded = Dense(30, activation=None)(drop)
batch = BatchNormalization()(encoded)
act = PReLU()(batch)
drop = Dropout(rate, noise_shape=None, seed=None)(act)
cat = concatenate([drop, input_drop])
output = Dense(5, activation='sigmoid', kernel_regularizer=regularizers.l1(0.00001))(cat)
model = Model(input, output)
Adam = optimizers.Adam(lr=0.001)
model.compile(optimizer=Adam, loss='binary_crossentropy', metrics = ['accuracy'])
model.summary()
В sklearn у нас есть class_weights
from sklearn.utils import class_weight
class_weights = class_weight.compute_class_weight('balanced',
np.unique(y_train),
y_train)
, так что я могу использовать эти веса классов, чтобы оштрафовать потерю более-менее наблюдаемые классы при подборе модели:
model.fit(x_train, y_train, epochs=20, batch_size=1024, shuffle=True, validation_data=(x_test, y_test),
class_weight = class_weights)
Однако, class_weights здесь для двоичной классификации, и, следовательно, я не думаю, что это правильный путь. В sklearn есть sample_weights:
from sklearn.utils import class_weight
sample_weights = class_weight.compute_sample_weight('balanced', y_train)
Возвращает sample_weights, который представляет собой вектор с длиной, эквивалентной количеству строк обучающего набора с соответствующими весами. Я не знаю, имеет ли это смысл.
Таким образом, вопрос заключается в том, как решить проблему дисбаланса классов для классификатора с несколькими метками в Keras