我在进行EEG数据(时间序列)的分类工作时,使用Keras的evaluate函数和从Keras迭代历史中获取的准确率不同。我想知道哪个更准确。以下是我的Keras模型
model=Sequential()model.add(Conv1D(filters=60,kernel_size=5,strides=1,padding='same',input_shape=X_train.shape[1::]))model.add(Activation('relu'))model.add(Dropout(0.5))model.add(Conv1D(filters=40,kernel_size=5,strides=1,padding='same'))model.add(Activation('relu'))model.add(Dropout(0.5))model.add(Conv1D(filters=20,kernel_size=3,strides=1,padding='same'))model.add(Activation('relu'))model.add(Dropout(0.5))model.add(Flatten())model.add(Dense(50,activation='tanh'))model.add(Dense(20,activation='tanh'))model.add(Dense(2,activation='sigmoid'))optimizer=optimizers.Adam(lr=0.0001)model.compile(optimizer=optimizer,loss='binary_crossentropy',metrics=['accuracy'])history=model.fit(X_train,y_train,batch_size=20,epochs=100, verbose=2,validation_split=0.3)print('accuracy',np.average(np.array(history.history['val_acc'])))model.evaluate(X_test,y_test)
使用evaluate函数得到的准确率是0.448。通过平均验证准确率从历史记录中得到的准确率是0.709。
以下是最后20个epoch的准确率日志
Epoch 81/100 - 2s - loss: 0.3923 - acc: 0.8217 - val_loss: 0.5482 - val_acc: 0.7327Epoch 82/100 - 2s - loss: 0.3843 - acc: 0.8227 - val_loss: 0.5522 - val_acc: 0.7305Epoch 83/100 - 2s - loss: 0.3885 - acc: 0.8235 - val_loss: 0.5589 - val_acc: 0.7268Epoch 84/100 - 2s - loss: 0.4001 - acc: 0.8142 - val_loss: 0.5781 - val_acc: 0.7177Epoch 85/100 - 2s - loss: 0.3938 - acc: 0.8165 - val_loss: 0.5474 - val_acc: 0.7396Epoch 86/100 - 2s - loss: 0.3965 - acc: 0.8187 - val_loss: 0.5587 - val_acc: 0.7230Epoch 87/100 - 2s - loss: 0.3768 - acc: 0.8279 - val_loss: 0.5947 - val_acc: 0.7107Epoch 88/100 - 2s - loss: 0.3789 - acc: 0.8288 - val_loss: 0.5583 - val_acc: 0.7334Epoch 89/100 - 2s - loss: 0.3805 - acc: 0.8262 - val_loss: 0.5690 - val_acc: 0.7227Epoch 90/100 - 2s - loss: 0.3712 - acc: 0.8302 - val_loss: 0.5661 - val_acc: 0.7271Epoch 91/100 - 2s - loss: 0.3678 - acc: 0.8361 - val_loss: 0.5798 - val_acc: 0.7180Epoch 92/100 - 2s - loss: 0.3727 - acc: 0.8352 - val_loss: 0.5927 - val_acc: 0.7085Epoch 93/100 - 2s - loss: 0.3720 - acc: 0.8271 - val_loss: 0.5622 - val_acc: 0.7321Epoch 94/100 - 2s - loss: 0.3829 - acc: 0.8200 - val_loss: 0.5799 - val_acc: 0.7155Epoch 95/100 - 2s - loss: 0.3630 - acc: 0.8384 - val_loss: 0.5623 - val_acc: 0.7337Epoch 96/100 - 2s - loss: 0.3655 - acc: 0.8330 - val_loss: 0.5817 - val_acc: 0.7164Epoch 97/100 - 2s - loss: 0.3722 - acc: 0.8314 - val_loss: 0.5892 - val_acc: 0.7164Epoch 98/100 - 2s - loss: 0.3591 - acc: 0.8373 - val_loss: 0.5750 - val_acc: 0.7155Epoch 99/100 - 2s - loss: 0.3710 - acc: 0.8327 - val_loss: 0.5674 - val_acc: 0.7258Epoch 100/100 - 2s - loss: 0.3669 - acc: 0.8319 - val_loss: 0.5900 - val_acc: 0.7104
回答:
两者都是正确的 – 你只是每次使用了不同的数据集。
你指定了
model.fit(X_train,y_train,batch_size=20,epochs=100, verbose=2,validation_split=0.3)
这意味着30%的训练数据集未用于训练,而是留作验证(validation_split=0.3
)。这就是你在历史记录中看到的验证损失。
然而,在测试时,你这样做:
model.evaluate(X_test,y_test)
这使用了一个全新的数据集X_test
。由于你在该数据集上的准确率显著降低,这个数据集在某些方面一定与你的训练集根本不同,你的模型未能捕捉到这种变化性。
现在,哪个准确率反映了“真实”性能?都不是。两者都是。这取决于X_test
包含什么,它与X_train
的不同之处,以及你希望模型擅长什么。但通常,你会在新的和未见过的数据上报告模型性能,即X_test
。