以下是我的数据:

我有500个录音(任意分为训练,验证和测试集) . 每个记录包含一定数量的行,每个行对应于1s的EEG段 . 换句话说,每个记录的长度等于EEG信号的长度(以s为单位) . 每行包含22个通道* 22个时间/频率特征= 484具有输出标签(0或1) .

所以我想进行二进制分类 .

正如许多论文(查看this good paper)所建议的,对于每个记录,我创建长度为 look_back 的序列,以便在考虑到段"around"的特征的情况下预测每个标签 . 这是代码:

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) 的3-D数组 .

为了处理不 balancer 的类,我测试了 make_imbalance 函数以丢弃实例以保持每个类的相同数量的实例以及在损失函数中考虑不 balancer 的 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()))

我得到了这样的结果:

训练混淆矩阵非常出色,但验证和测试矩阵很差......

我想这不是过度拟合,因为我的模型尺寸很小(一层,......) . 此外,我猜这个模型是合适的,因为它设法很好地区分(巨大的)训练集上的数据......

那么,有什么不对?

注意:我的确说我与经典的Keras前馈神经网络有同样的问题

编辑:这是我绘制学习曲线时得到的结果:

您可以看到,训练精度仍然很高,而验证准确性(实际上橙色曲线应该是"validation")仍然很低......

编辑:我试图使用XGBoost和SVM分类器,但我无法获得结果(仍然完全相同的行为)

编辑:我试图改组数据,看看 . 我得到了非常好的结果,但它是一种海市蜃楼...事实上,我在训练和验证集中都有来自相同录音(不完全相同但非常接近)的数据......有点作弊 . 当我向模型呈现一个全新的录音时,它会崩溃......所以,我还没有找到解决方案