Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 训练模型后和加载模型后的精度差异很大_Python_Machine Learning_Keras - Fatal编程技术网

Python 训练模型后和加载模型后的精度差异很大

Python 训练模型后和加载模型后的精度差异很大,python,machine-learning,keras,Python,Machine Learning,Keras,我制作了Keras NN模型用于假新闻检测。我的特征是单词的平均长度、句子的平均长度、标点符号的数量、大写字母的数量、问题的数量等。我有34个特征。我有一个输出,0和1(0表示假新闻,1表示真新闻)。 我使用了50000个样本进行培训,10000个用于测试,2000个用于验证。我的数据的值是从-1到10,所以值之间没有太大的差异。我使用的标准定标器如下所示: x_train, x_test, y_train, y_test = train_test_split(features, results

我制作了Keras NN模型用于假新闻检测。我的特征是单词的平均长度、句子的平均长度、标点符号的数量、大写字母的数量、问题的数量等。我有34个特征。我有一个输出,0和1(0表示假新闻,1表示真新闻)。 我使用了50000个样本进行培训,10000个用于测试,2000个用于验证。我的数据的值是从-1到10,所以值之间没有太大的差异。我使用的标准定标器如下所示:

x_train, x_test, y_train, y_test = train_test_split(features, results, test_size=0.20, random_state=0)

scaler = StandardScaler()
x_train = scaler.fit_transform(x_train)
x_test = scaler.transform(x_test)

validation_features = scaler.transform(validation_features)
我的NN:

model = Sequential()
model.add(Dense(34, input_dim = x_train.shape[1], activation = 'relu')) # input layer requires input_dim param
model.add(Dense(150, activation = 'relu'))
model.add(Dense(150, activation = 'relu'))
model.add(Dense(150, activation = 'relu'))
model.add(Dense(150, activation = 'relu'))
model.add(Dense(150, activation = 'relu'))
model.add(Dense(1, activation='sigmoid')) # sigmoid instead of relu for final probability between 0 and 1

model.compile(loss="binary_crossentropy", optimizer= "adam", metrics=['accuracy'])

es = EarlyStopping(monitor='val_loss', min_delta=0.0, patience=0, verbose=0, mode='auto')
model.fit(x_train, y_train, epochs = 15, shuffle = True, batch_size=64, validation_data=(validation_features, validation_results), verbose=2, callbacks=[es])

scores = model.evaluate(x_test, y_test)
print(model.metrics_names[0], round(scores[0]*100,2), model.metrics_names[1], round(scores[1]*100,2))
结果:

Train on 50407 samples, validate on 2000 samples
Epoch 1/15
 - 3s - loss: 0.3293 - acc: 0.8587 - val_loss: 0.2826 - val_acc: 0.8725
Epoch 2/15
 - 1s - loss: 0.2647 - acc: 0.8807 - val_loss: 0.2629 - val_acc: 0.8745
Epoch 3/15
 - 1s - loss: 0.2459 - acc: 0.8885 - val_loss: 0.2602 - val_acc: 0.8825
Epoch 4/15
 - 1s - loss: 0.2375 - acc: 0.8930 - val_loss: 0.2524 - val_acc: 0.8870
Epoch 5/15
 - 1s - loss: 0.2291 - acc: 0.8960 - val_loss: 0.2423 - val_acc: 0.8905
Epoch 6/15
 - 1s - loss: 0.2229 - acc: 0.8976 - val_loss: 0.2495 - val_acc: 0.8870
12602/12602 [==============================] - 0s 21us/step
loss 23.95 acc 88.81
准确性检查:

prediction = model.predict(validation_features , batch_size=64)

res = []
for p in prediction:
    res.append(p[0].round(0))

# Accuracy with sklearn
acc_score = accuracy_score(validation_results, res)
print("Sklearn acc", acc_score)  # 0.887
保存模型:

model.save("new keras fake news acc 88.7.h5")
scaler_filename = "keras nn scaler.save"
joblib.dump(scaler, scaler_filename)
我保存了那个模型和那个定标器。 当我加载那个模型和那个定标器,当我想做预测时,我得到了52%的准确率,这是非常低的,因为我训练那个模型时,准确率是88.7%。 我在新数据上应用了
.transform
,以进行测试

validation_df = pd.read_csv("validation.csv")
validation_features = validation_df.iloc[:,:-1]
validation_results = validation_df.iloc[:,-1].tolist()

scaler = joblib.load("keras nn scaler.save") 
validation_features = scaler.transform(validation_features)


my_model_1 = load_model("new keras fake news acc 88.7.h5")
prediction = my_model_1.predict(validation_features , batch_size=64)

res = []
for p in prediction:
    res.append(p[0].round(0))

# Accuracy with sklearn - much lower 
acc_score = accuracy_score(validation_results, res)
print("Sklearn acc", round(acc_score,2))  # 0.52

你能告诉我我做错了什么吗?我在github和stackoverflow上读了很多关于这方面的文章,但我找不到答案?

没有你的实际数据,很难回答这个问题。但有一个确凿的证据,让人怀疑你的验证数据可能(非常)不同于你的培训和测试数据;它来自于你对这一点的理解:

如果我在我的[validation set]功能上使用
fit_transform
,我不会得到错误,但我得到了52%的准确率,这太糟糕了(因为我有89.1%)

虽然在验证数据上使用
fit\u transform
确实是错误的方法(正确的方法就是您在这里所做的),但在实践中,它应该而不是导致精度上的高度差异

换句话说,我实际上看到过许多情况,人们错误地将这种
fit_transform
方法应用于他们的验证/部署数据,却从未意识到其中有任何错误,这仅仅是因为他们没有得到任何性能差异-因此他们没有得到警告。如果所有这些数据在质量上确实相似,那么这种情况是可以预料的

但是,像您这样的差异导致人们强烈怀疑您的验证数据实际上(非常)不同于您的培训和测试数据。如果是这种情况,那么这种性能差异是可以预期的:整个ML实践是建立在(通常是隐含的)假设之上的,即我们的数据(培训、验证、测试、实际部署数据等)不会发生质的变化,并且它们都来自相同的统计分布

因此,下一步是对您的培训和验证数据进行探索性分析,以调查这一点(实际上,在任何预测性任务中,这总是假定为第0步)。我猜想,即使是基本度量(平均值和最大/最小值等)也会显示它们之间是否有很大的差异,正如我所怀疑的那样

特别是,scikit learn的用途


对于转换,其中
u
是数据的平均值,
s
是数据的标准偏差。如果您的训练集和验证集之间的这些值存在显著差异,那么性能差异也不会出乎意料。

好吧,例如,这是假新闻检测的模型,如果我的训练数据有关于金融、经济、政治的新闻,并且我将体育新闻作为验证传递,我会得到坏结果?@taga对此不确定;但由于你最终得到的是数字数据,这样的调查应该非常困难——见更新的答案。我有头脑,我需要保存重量,并加载重量,是真的吗?我教过当我做模型的时候一切都被保存了。save@taga是的,这就是想法:在model.fit中有参数验证数据,我把validation\u data=(validation\u features,validation\u results),这是正确的做法,还是我应该把测试数据放在那里?
z = (x - u) / s