Как добавить веса классов для классификатора с несколькими метками в Keras? - PullRequest
0 голосов
/ 17 марта 2020

У меня проблема классификации по нескольким меткам. Моя переменная ответа - 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...