Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/315.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 val acc与Keras神经网络预测精度差异较大_Python_Machine Learning_Keras_Neural Network - Fatal编程技术网

Python val acc与Keras神经网络预测精度差异较大

Python val acc与Keras神经网络预测精度差异较大,python,machine-learning,keras,neural-network,Python,Machine Learning,Keras,Neural Network,我有一个用于在Keras中创建NN模型的数据集,我从该数据集中提取了2000行作为验证数据,这2000行应该添加到.predict函数中 我为Keras NN编写了一个代码,目前它运行良好,但我注意到一些对我来说非常奇怪的事情。它给了我超过83%的非常好的准确性,损失大约为0.12,但是当我想用看不见的数据(那2000行)进行预测时,它只预测平均正确率为65%。 当我添加掉层时,它只会降低精度 然后我添加了earlystoping,它给了我大约86%的准确率,损失大约是0.10,但是当我用看不见

我有一个用于在Keras中创建NN模型的数据集,我从该数据集中提取了2000行作为验证数据,这2000行应该添加到
.predict
函数中

我为Keras NN编写了一个代码,目前它运行良好,但我注意到一些对我来说非常奇怪的事情。它给了我超过83%的非常好的准确性,损失大约为0.12,但是当我想用看不见的数据(那2000行)进行预测时,它只预测平均正确率为65%。 当我添加掉层时,它只会降低精度

然后我添加了
earlystoping
,它给了我大约86%的准确率,损失大约是0.10,但是当我用看不见的数据进行预测时,我得到了67%的最终预测准确率


这是否意味着模型在87%的情况下做出了正确的预测?我的逻辑是,如果我在
.predict
函数中添加100个样本,那么该程序应该能够很好地预测87/100个样本,或者在该范围内的某个地方(比如超过80个)?我尝试在我的
.predict
函数中添加100、500、1000、1500和2000个样本,并且它总是在65-68%的样本中做出正确的预测

为什么,我做错什么了吗? 我尝试过使用层的数量、节点的数量、不同的激活函数和不同的优化器,但它只会改变1-2%的结果。 我的数据集如下所示:

DataFrame shape (59249, 33)
x_train shape (47399, 32)
y_train shape (47399,)
x_test shape (11850, 32)
y_test shape (11850,)
testing_features shape (1000, 32)
这是我的NN模型:

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

# compile the model, adam gradient descent (optimized)
model.compile(loss="binary_crossentropy", optimizer= "adam", metrics=['accuracy'])


# call the function to fit to the data training the network)
es = EarlyStopping(monitor='val_loss', min_delta=0.0, patience=1, verbose=0, mode='auto')
model.fit(x_train, y_train, epochs = 15, shuffle = True, batch_size=32, validation_data=(x_test, y_test), 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 47399 samples, validate on 11850 samples
Epoch 1/15
 - 25s - loss: 0.3648 - acc: 0.8451 - val_loss: 0.2825 - val_acc: 0.8756
Epoch 2/15
 - 9s - loss: 0.2949 - acc: 0.8689 - val_loss: 0.2566 - val_acc: 0.8797
Epoch 3/15
 - 9s - loss: 0.2741 - acc: 0.8773 - val_loss: 0.2468 - val_acc: 0.8849
Epoch 4/15
 - 9s - loss: 0.2626 - acc: 0.8816 - val_loss: 0.2416 - val_acc: 0.8845
Epoch 5/15
 - 10s - loss: 0.2566 - acc: 0.8827 - val_loss: 0.2401 - val_acc: 0.8867
Epoch 6/15
 - 8s - loss: 0.2503 - acc: 0.8858 - val_loss: 0.2364 - val_acc: 0.8893
Epoch 7/15
 - 9s - loss: 0.2480 - acc: 0.8873 - val_loss: 0.2321 - val_acc: 0.8895
Epoch 8/15
 - 9s - loss: 0.2450 - acc: 0.8886 - val_loss: 0.2357 - val_acc: 0.8888
11850/11850 [==============================] - 2s 173us/step
loss 23.57 acc 88.88
这是为了预测:

#testing_features are 2000 rows that i extracted from dataset (these samples are not used in training, this is separate dataset thats imported)

prediction = model.predict(testing_features , batch_size=32)

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


# Accuracy with sklearn - also much lower 
acc_score = accuracy_score(testing_results, res)
print("Sklearn acc", acc_score)    

result_df = pd.DataFrame({"label":testing_results,
                          "prediction":res})


result_df["prediction"] = result_df["prediction"].astype(int)

s = 0
for x,y in zip(result_df["label"], result_df["prediction"]):
    if x == y:
        s+=1

print(s,"/",len(result_df))
acc = s*100/len(result_df)
print('TOTAL ACC:', round(acc,2))
问题是…现在我用sklearn和
my_acc获得了52%的准确率。

为什么我在验证时得到如此低的准确度,当它说它要大得多时?

您发布的训练数据提供了很高的验证准确度,所以我有点困惑您从何处获得65%的准确度,但一般来说,当您的模型在训练数据上比在看不见的数据上表现得好得多时,这意味着您是错误的。这是机器学习中经常出现的一个大问题,没有任何方法可以保证防止这种情况发生,但您可以尝试以下几种方法:

  • 正则化网络的权重,例如使用l2正则化
  • 使用随机正则化技术,例如在培训期间退出
  • 降低模型复杂性(但你说你已经尝试过了)

您发布的培训数据提供了很高的验证准确性,因此我有点困惑您从何处获得65%的数据,但通常情况下,当您的模型在培训数据上的性能比在看不见的数据上的性能好得多时,这就意味着您的验证是错误的。这是机器学习中经常出现的一个大问题,没有任何方法可以保证防止这种情况发生,但您可以尝试以下几种方法:

  • 正则化网络的权重,例如使用l2正则化
  • 使用随机正则化技术,例如在培训期间退出
  • 降低模型复杂性(但你说你已经尝试过了)

我将列出我在您的机型上看到的问题/建议

  • 你想预测什么?您在最后一层中使用了
    sigmoid
    激活功能,这似乎是一个二进制分类,但在
    loss
    功能中,您使用了
    mse
    ,这似乎很奇怪。您可以尝试为您的模型使用
    binary\u crossentropy
    而不是
    mse
    损失函数
  • 您的模型似乎存在过度拟合问题,因此您可以增加问题。也可以在其他隐藏层之间添加新的退出,或者您可以删除其中一个隐藏层,因为您的模型似乎太复杂了
  • 您可以在层中更改神经元的数量,如更窄的=>64->32->16->1或尝试不同的NN架构
  • 尝试使用
    adam
    优化器而不是
    sgd
  • 如果您有
    57849
    sample,您可以在training+validation中使用47000个样本,剩下的将是您的测试集
  • 不要使用相同的集合进行评估和验证。首先将数据拆分为训练集和测试集。然后,当您拟合模型时,给出
    验证\u分割\u比率
    ,然后它将自动从您的训练集中给出验证集

  • 我将列出我在您的模型上看到的问题/建议

  • 你想预测什么?您在最后一层中使用了
    sigmoid
    激活功能,这似乎是一个二进制分类,但在
    loss
    功能中,您使用了
    mse
    ,这似乎很奇怪。您可以尝试为您的模型使用
    binary\u crossentropy
    而不是
    mse
    损失函数
  • 您的模型似乎存在过度拟合问题,因此您可以增加问题。也可以在其他隐藏层之间添加新的退出,或者您可以删除其中一个隐藏层,因为您的模型似乎太复杂了
  • 您可以在层中更改神经元的数量,如更窄的=>64->32->16->1或尝试不同的NN架构
  • 尝试使用
    adam
    优化器而不是
    sgd
  • 如果您有
    57849
    sample,您可以在training+validation中使用47000个样本,剩下的将是您的测试集
  • 不要使用相同的集合进行评估和验证。首先将数据拆分为训练集和测试集。然后,当您拟合模型时,给出
    验证\u分割\u比率
    ,然后它将自动从您的训练集中给出验证集

  • 你的型号可能太合适了。阅读有关避免过度装配的方法请在这个新的测试集中包含预测代码,并且损失不是一个百分比。@MatiasValdenegro完成了,并且我更改了它,使损失不是%。请告诉我我做错了什么。我的训练集和测试集是0.75/0.25如果计算精度不正确,只需使用model.evaluate,返回元组i中的第二个元素