python - 训练和验证时准确率高,使用相同数据集进行预测时准确率低
问题描述
所以我正在尝试训练 Keras 模型。训练和验证时准确度很高(我使用的是 f1score,但准确度也很高)。但是当我试图预测一些数据集时,我的准确性会降低。即使我预测训练集。所以我想这不是过度拟合的问题。那么问题是什么?
import matplotlib.pyplot as plt
skf = StratifiedKFold(n_splits=5)
for train_index, test_index in skf.split(X, y):
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
X_train,x_val,y_train,y_val = train_test_split(X_train, y_train, test_size=0.5,stratify = y_train)
y_train = encode(y_train)
y_val = encode(y_val)
model = Sequential()
model.add(Dense(50,input_dim=X_train.shape[1],activation='tanh'))
model.add(Dropout(0.5))
model.add(Dense(25,activation='tanh'))
model.add(Dropout(0.5))
model.add(Dense(10,activation='tanh'))
model.add(Dropout(0.5))
model.add(Dense(2, activation='softmax'))
opt = Adam(learning_rate=0.001)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['acc', ta.utils.metrics.f1score])
history = model.fit(X_train, y_train,
validation_data=(x_val, y_val),
epochs=5000,
verbose=0)
plt.plot(history.history['f1score'])
plt.plot(history.history['val_f1score'])
plt.title('model accuracy')
plt.ylabel('f1score')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
break
结果就在这里。如您所见,训练和验证集的结果很高。
和预测代码:
from sklearn.metrics import f1_score
y_pred = model.predict(x_train)
y_pred = decode(y_pred)
y_train_t = decode(y_train)
print(f1_score(y_train_t, y_pred))
结果为 0.64,低于预期的 0.9。
我的解码和编码:
def encode(y):
Y=np.zeros((y.shape[0],2))
for i in range(len(y)):
if y[i]==1:
Y[i][1]=1
else :
Y[i][0]=1
return Y
def decode(y):
Y=np.zeros((y.shape[0]))
for i in range(len(y)):
if np.argmax(y[i])==1:
Y[i]=1
else :
Y[i]=0
return Y
解决方案
由于您使用了最后一层
model.add(Dense(2, activation='softmax')
你不应该使用in loss='binary_crossentropy'
,model.compile()
而是使用loss='categorical_crossentropy'
。
由于这个错误,模型拟合期间显示的结果可能是错误的——sklearn 返回的结果f1_score
是真实的。
与您的问题无关(因为我猜后续问题将是如何改进它?),我们实际上从不使用activation='tanh'
隐藏层(relu
改为尝试)。此外,默认情况下不应使用dropout(尤其是在 0.5 如此高的值下);注释掉所有 dropout 层,只有在模型过拟合时才将它们添加回来(已知在不需要时使用 dropout 会损害性能)。
推荐阅读
- react-native - 我想在反应原生的选择器中显示 json 数据。我正在使用基于功能的组件而不是基于类。有什么解决办法吗?
- python - 为什么 Beautiful Soup 将“<”视为无效字符?
- ios - Objective C - 使用自己的样式从 HTML 文本更改属性字符串的字体
- javascript - 如何从 typescript/javascript 中的对象数组中提取具有值的特定键?
- junit - @DataJpaTest 期间自动装配的 ObjectMapper 为空
- android - 如何使用工具栏而不是操作栏将旧的导航抽屉片段代码升级为代码?
- reactjs - 分阶段实施 React,怎么可能?
- go - 谷歌表格数据到 json
- node.js - 如何在我的数据库中填充多个路径?
- sql - 使用 case 语句创建函数以封装行级安全性