Вот как мои данные:
У меня 500 записей (произвольно разделенных на обучающие, проверочные и тестовые наборы). Каждая запись содержит определенное количество строк, каждая из которых соответствует сегменту ЭЭГ 1 с. Другими словами, длина каждой записи равна длине сигнала ЭЭГ (в с). Каждая строка содержит 22 канала * 22 временных / частотных элемента = 484 элемента + метка выхода (0 или 1).
Итак, я хочу выполнить двоичную классификацию.
Как предлагают многие газеты (см. эту хорошую статью ), для каждой записи я создаю последовательности длиной look_back
, чтобы каждая метка была предсказана с учетом особенностей сегментов "вокруг" ». Вот код:
def create_dataset(feat,targ, look_back=1):
semi_window=math.floor(look_back/2)
dataX, dataY = [], []
for i in range(semi_window,len(targ)-semi_window):
a = feat[i-semi_window:(i+semi_window+1), :]
dataX.append(a)
dataY.append(targ[i])
return np.array(dataX), np.array(dataY)
Эта функция возвращает трехмерный массив размером (samples, look_back=time_steps, features=484)
.
Чтобы справиться с несбалансированными классами, я протестировал как функцию make_imbalance
для отбрасывания экземпляров, чтобы сохранить одинаковое количество экземпляров каждого класса, так и параметр class_weight
, который учитывает дисбаланс в функции потерь.
Итак, я использовал модель LSTM и использовал параметр обратного вызова EarlyStopping, чтобы остановить, как только точность проверки не увеличится на заданный допуск.
Вот моя полная модель:
from sklearn.utils import class_weight
earlystop = EarlyStopping(monitor='val_acc', min_delta=0.001, patience=5, verbose=1, mode='auto')
callbacks_list = [earlystop]
np.random.seed(10)
set_random_seed(30)
rn.seed(50)
# plutôt que faire imbalance qui supprime plic ploc les données, on préfère introduire class_weight et ne pas shuffler les données (ben en fait si..)...
weights = class_weight.compute_class_weight('balanced',np.unique(trainY),trainY)
print (weights)
model = Sequential()
model.add(LSTM(8, input_shape=(look_back, trainX.shape[2]), recurrent_dropout=0.3))
model.add(Dropout(0.3))
model.add(Dense(1, activation='sigmoid'))
print (model.summary())
model.compile(loss='binary_crossentropy', optimizer='adam',metrics=['accuracy'])
model.fit(trainX, trainY, validation_data=(validX, validY), epochs=100, batch_size=32, class_weight=weights, verbose=1 , callbacks=callbacks_list, shuffle=True)
train_score = model.evaluate(trainX, trainY, batch_size=2048)
print(train_score)
trainPredict = model.predict(trainX)
print(confusion_matrix(trainY, trainPredict.round()))
valid_score = model.evaluate(validX, validY, batch_size=2048)
print(valid_score)
validPredict = model.predict(validX)
print(confusion_matrix(validY, validPredict.round()))
test_score = model.evaluate(testX, testY, batch_size=2048)
print(test_score)
testPredict = model.predict(testX)
print(confusion_matrix(testY, testPredict.round()))
и я получаю такие результаты:
Матрица путаницы обучения выдающаяся, но матрицы проверки и проверки плохие ...
Полагаю, это не слишком удобно, так как моя модель очень небольшого размера (один слой, ...). Более того, я думаю, что модель присваивается, потому что ей удается очень хорошо различать данные (огромного) обучающего набора ...
Итак, что не так?
NB. Я говорю, что у меня такая же проблема с классической нейронной сетью с прямой связью Keras
РЕДАКТИРОВАТЬ: Вот что я получаю, когда я строю кривые обучения:
Вы можете видеть, что точность обучения остается действительно высокой, в то время как точность проверки (на самом деле оранжевые кривые должны быть для «проверки») остается очень низкой ...
РЕДАКТИРОВАТЬ: я пытался использовать классификаторы XGBoost и SVM, но мне не удалось получить результаты (все то же поведение)
РЕДАКТИРОВАТЬ: я пытался перетасовать данные и посмотреть. Я получаю очень хорошие результаты, НО это своего рода мираж ... Действительно, у меня есть данные, поступающие из одних и тех же записей (не идентично, но очень близко) в обучающих и проверочных наборах ... вроде обмана. Когда я представляю совершенно новую запись для модели, она падает ... Итак, я еще не нашел решение