Модель LSTM дает хорошую тренировку, но неудовлетворительные результаты испытаний, но не видит переоснащения - PullRequest
0 голосов
/ 08 сентября 2018

Вот как мои данные:

У меня 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()))

и я получаю такие результаты:

enter image description here

Матрица путаницы обучения выдающаяся, но матрицы проверки и проверки плохие ...

Полагаю, это не слишком удобно, так как моя модель очень небольшого размера (один слой, ...). Более того, я думаю, что модель присваивается, потому что ей удается очень хорошо различать данные (огромного) обучающего набора ...

Итак, что не так?

NB. Я говорю, что у меня такая же проблема с классической нейронной сетью с прямой связью Keras

РЕДАКТИРОВАТЬ: Вот что я получаю, когда я строю кривые обучения:

enter image description here Вы можете видеть, что точность обучения остается действительно высокой, в то время как точность проверки (на самом деле оранжевые кривые должны быть для «проверки») остается очень низкой ...

РЕДАКТИРОВАТЬ: я пытался использовать классификаторы XGBoost и SVM, но мне не удалось получить результаты (все то же поведение)

РЕДАКТИРОВАТЬ: я пытался перетасовать данные и посмотреть. Я получаю очень хорошие результаты, НО это своего рода мираж ... Действительно, у меня есть данные, поступающие из одних и тех же записей (не идентично, но очень близко) в обучающих и проверочных наборах ... вроде обмана. Когда я представляю совершенно новую запись для модели, она падает ... Итак, я еще не нашел решение

...