当训练具有较高的准确性但model.evaluate()的准确性较低时,如何改善模型?

时间:2020-08-16 18:20:40

标签: python tensorflow machine-learning keras deep-learning

我正在从事一个处理传感器数据的项目。我从3个地方收集了传感器数据,并将数据存储为csv文件。大约有4000个样本。数据具有X,Y,Z,它们用作特征和作为目标变量的类。目标是在数据集上建立分类模型。目标变量/标签为[1,2,3]。由于它是时间序列数据,因此我选择使用双向LSTM。

数据分发:

enter image description here

model = keras.Sequential()
model.add(
    keras.layers.Bidirectional(
    keras.layers.LSTM(
    units = 128,
    input_shape = [X_train.shape[1], X_train.shape[2]]
    )
)
)
model.add(keras.layers.Dropout(rate = 0.2))
model.add(keras.layers.Dense(units = 128, activation = 'relu'))
model.add(keras.layers.Dense(y_train.shape[1], activation = 'softmax'))
model.compile(
loss = 'categorical_crossentropy',
optimizer = 'adam',
metrics = ['acc']
)

训练完模型后

history3 = model.fit(
    X_train, y_train,
    epochs=35,
    batch_size=100,
    validation_split = 0.1,
    shuffle=False
)

这是我上一个纪元给出的准确性和验证准确性:

Epoch 35/35
4002/4002 [==============================] - 3s 858us/step - loss: 0.0216 - acc: 0.9948 - val_loss: 0.3026 - val_acc: 0.9056

当我使用model.evaluate(X_test, y_test)时,它将返回两个值的列表:[5.144028138408701, 0.43551796674728394]

所以问题是这两个值是什么? 我的猜测是,第一个值为MSE,第二个为准确性。如果我是对的,那么为什么在使用.evaluate时精度却这么低?我应该怎么做才能改善模型?

P.S。 更多信息

print(X_train.shape, y_train.shape, X_test.shape, y_test.shape)

(4447, 24, 3) (4447, 3) (473, 24, 3) (473, 3)

数据是有序数据,因此我在拆分期间使用shuffle = True

df_train, df_test = train_test_split(df, test_size = 0.1, shuffle = True)

2 个答案:

答案 0 :(得分:0)

您对哪种model.evaluate回报的猜测是正确的,第一个是损失,第二个是准确性。即使val_accuracy正在显示其他内容,您的模型似乎还是过拟合。 我建议您检查数据集中有两个类别的标签。我的意思是,也许您一门课有90%,而另一门课只有10%。 如果是这样的话,您可以使用sklearn做一件简单的事情(我猜您使用了sklearn.model_selection中的train_test_split),也就是说,您应该将参数stratify = y添加到train_test_split函数中。这可以帮助解决数据集不平衡的问题。 另外,您是否尝试过使用其他优化算法?您降低了学习率吗?

答案 1 :(得分:0)

我怀疑您的数据集高度不平衡。例如,如果您有一个数据集,该数据集包含类别0的10,000个样本和类别1的1000个样本。假设您将其分为训练集和验证集。两组都将仍然具有这种不平衡。现在,如果您训练网络,将倾向于选择0类,并且验证数据结果将看起来不错。如果网络始终预测为0级,则其精度为90%。现在,如果您有一个平衡的测试集,则说0类的500个样本和1类的500个样本 在测试集上运行模型评估时,您的错误率会很高。 我没有用过它,但是我知道model.fit有一个叫做class_weight的参数。这是一个字典,允许您根据类调整对损失函数的影响。在上面的示例中,您希望1类样本的权重是0类样本的10倍。然后,您将class_weight字典创建为

class_weight={0:.55, 1:5.5}

然后在model.fit中使用它。您可以做的其他事情是使用可调的学习率,并以最小的验证损失保存模型并将其用于评估。使用Keras回调很容易做到。可以设置回调ModelCheckpoint来监视验证损失并以最低的损失保存模型。文档为here.,可以设置ReduceLROnPlateau回调以监视验证损失,如果在连续N个时期后损失没有减少,则可以将学习减少一个因子。文档为here.