Machine learning 神经网络训练得很好,测试预测非常糟糕,近乎荒谬

Machine learning 神经网络训练得很好,测试预测非常糟糕,近乎荒谬,machine-learning,modeling,prediction,Machine Learning,Modeling,Prediction,我在使用R神经网络函数的神经网络模型方面遇到了很多麻烦。当我按照预期对所有数据进行网络训练时,预测非常准确。然而,当我将数据分为训练集和测试集时,测试预测非常糟糕。我不知道我到底做错了什么。我将感谢任何建议或帮助排除故障,因为我认为我自己无法解决这个问题。提前谢谢 我已经包括了R代码和一些图,完整数据下面的数据示例是3600个观测值 向帕特问好 2018年12月5日更新:根据反馈,这似乎是过度拟合,我尝试提前停止训练,发现测试预测的MSE从未变得非常低,在接近0个训练周期时是最低的,并从包含的图

我在使用R神经网络函数的神经网络模型方面遇到了很多麻烦。当我按照预期对所有数据进行网络训练时,预测非常准确。然而,当我将数据分为训练集和测试集时,测试预测非常糟糕。我不知道我到底做错了什么。我将感谢任何建议或帮助排除故障,因为我认为我自己无法解决这个问题。提前谢谢

我已经包括了R代码和一些图,完整数据下面的数据示例是3600个观测值

向帕特问好

2018年12月5日更新:根据反馈,这似乎是过度拟合,我尝试提前停止训练,发现测试预测的MSE从未变得非常低,在接近0个训练周期时是最低的,并从包含的图和附加的代码中上升

###########
#ANN Models
###########

#Load libraries
library(plyr)
library(ggplot2)
library(gridExtra)
library(neuralnet)

#Retain only numerically coded data from data1 in (data2) for ANN fitting
data2 = data1[,c(3:7)]

#Calculate Min and Max for Scaling
max_data = apply(data2,2,max)
min_data = apply(data2,2,min)
#Scale data 0-1
data2_scaled = scale(data2,center=min_data,scale=max_data-min_data)
#Check data structure
data2_scaled

#Fit neural net model
model_nn1 = neuralnet(formula=time~instructions+nodes+machine_num+app_num,data=data2_scaled,hidden=c(8,8),stepmax=1000000,threshold=0.01)
#Calculate Min and Max Response for rescaling
max_time = max(data2$time)
min_time = min(data2$time)
#Rescale neural net response predictions
pred_nn1 = model_nn1$net.result[[1]][,1]*(max_time-min_time)+min_time
#Compare model predictions to actual values
a03 = cbind.data.frame(data1$time,pred_nn1,data1$machine,data1$app)
colnames(a03) = c("actual","prediction","machine","app")
attach(a03)
p01 = ggplot(a03,aes(x=actual,y=prediction))+
geom_point(aes(color=machine),size=1)+
scale_y_continuous("Predicted Execution Time [s]",breaks=seq(0,1000,100),limits=c(0,1000))+
scale_x_continuous("Actual Execution Time [s]",breaks=seq(0,1000,100),limits=c(0,1000))+
ggtitle("Neural Net Fit (ALL DATA):\nActual vs. Predicted Execution Time")+
geom_abline(intercept=0,slope=1)+
theme_light()
p02 = ggplot(a03,aes(x=actual,y=prediction))+
geom_point(aes(color=app),size=1)+
scale_y_continuous("Predicted Execution Time [s]",breaks=seq(0,1000,100),limits=c(0,1000))+
scale_x_continuous("Actual Execution Time [s]",breaks=seq(0,1000,100),limits=c(0,1000))+
ggtitle("Neural Net Fit (ALL DATA):\nActual vs. Predicted Execution Time")+
geom_abline(intercept=0,slope=1)+
theme_light()
grid.arrange(p01,p02,nrow=1)
#Visualize ANN
plot(model_nn1)
#Epochs taken to train "steps"
model_nn1$result.matrix[3,]

#########################
#Testing and Training ANN
#########################>

#Split the data into a test and training set
index = sample(1:nrow(data2_scaled),round(0.80*nrow(data2_scaled)))
train_data = as.data.frame(data2_scaled[index,])
test_data = as.data.frame(data2_scaled[-index,])
model_nn2 = neuralnet(formula=time~instructions+nodes+machine_num+app_num,data=train_data,hidden=c(3,2),stepmax=1000000,threshold=0.01)
pred_nn2_scaled = compute(model_nn2,test_data[,c(1,2,4,5)])
pred_nn2 = pred_nn2_scaled$net.result*(max_time-min_time)+min_time
test_data_time = test_data$time*(max_time-min_time)+min_time
a04 = cbind.data.frame(test_data_time,pred_nn2,data1[-index,2],data1[-index,1])
colnames(a04) = c("actual","prediction","machine","app")
attach(a04)
p01 = ggplot(a04,aes(x=actual,y=prediction))+
geom_point(aes(color=machine),size=1)+
scale_y_continuous("Predicted Execution Time [s]",breaks=seq(0,1000,100),limits=c(0,1000))+
scale_x_continuous("Actual Execution Time [s]",breaks=seq(0,1000,100),limits=c(0,1000))+
ggtitle("Neural Net Fit (TEST DATA):\nActual vs. Predicted Execution Time")+
geom_abline(intercept=0,slope=1)+
theme_light()
p02 = ggplot(a04,aes(x=actual,y=prediction))+
geom_point(aes(color=app),size=1)+
scale_y_continuous("Predicted Execution Time [s]",breaks=seq(0,1000,100),limits=c(0,1000))+
scale_x_continuous("Actual Execution Time [s]",breaks=seq(0,1000,100),limits=c(0,1000))+
ggtitle("Neural Net Fit (TEST DATA):\nActual vs. Predicted Execution Time")+
geom_abline(intercept=0,slope=1)+
theme_light()
grid.arrange(p01,p02,nrow=1)

#EARLY STOPPING TEST

i = 1000
summary_data = data.frame(matrix(rep(0,4*i),ncol=4))
colnames(summary_data) = c("treshold","epochs","train_mse","test_mse")
for (j in 1:i){
a = runif(1,min=0.01,max=10)
#Train the model
model_nn2 = neuralnet(formula=time~instructions+nodes+machine_num+app_num,data=train_data,hidden=3,stepmax=1000000,threshold=a)
#Calculate Min and Max Response for rescaling
max_time = max(data2$time)
min_time = min(data2$time)
#Predict test data from trained nn
pred_nn2_scaled = compute(model_nn2,test_data[,c(1,2,4,5)])
#Rescale test prediction
pred_test_data_time = pred_nn2_scaled$net.result*(max_time-min_time)+min_time
#Rescale test actual
test_data_time = test_data$time*(max_time-min_time)+min_time
#Rescale train prediction
pred_train_data_time = model_nn2$net.result[[1]][,1]*(max_time-min_time)+min_time
#Rescale train actual
train_data_time = train_data$time*(max_time-min_time)+min_time
#Calculate mse
test_mse = mean((pred_test_data_time-test_data_time)^2)
train_mse = mean((pred_train_data_time-train_data_time)^2)
#Summarize
summary_data[j,1] = a
summary_data[j,2] = model_nn2$result.matrix[3,]
summary_data[j,3] = round(train_mse,3)
summary_data[j,4] = round(test_mse,3)
print(summary_data[j,])
}

plot(summary_data$epochs,summary_data$test_mse,pch=19,xlim=c(0,2000),ylim=c(0,300000),cex=0.5,xlab="Training Steps",ylab="MSE",main="Early Stopping Test: Comparing MSE : TEST=BLACK TRAIN=RED")
points(summary_data$epochs,summary_data$train_mse,pch=19,col=2,cex=0.5)

我猜这太过合适了。网络正在学习像字典一样重现数据,而不是学习数据中的基本功能。有各种各样的事情可以导致这种情况,也有解决的方法。 导致过度装配的因素有:

网络的训练时间可能太长。 该网络可能比训练示例拥有更多的权重。 减少过度装配的方法有:

创建验证数据集,并在测试完成后立即停止网络培训 验证集的丢失开始增加。这是必要的。 减少网络规模。轻量化 使用正则化技术,如权重衰减或衰减。
此外,根据给定的数据,神经网络可能难以解决该问题。再现训练数据并不能证明网络可以解决问题,它只能证明网络可以记住字典之类的东西。

感谢Nathan的指导,你的回答很有道理。嗨Nathan,我要尝试调整neuralnet函数的一些参数,基于您的3个项目,以减少过度装配。关于你的第一个要点,在验证集培训期间监控丢失,你有什么好的参考资料吗?@PatrickJ,我在谷歌上搜索了一下,但没有找到一篇关于它的好文章。训练神经网络是一个迭代过程,当你训练网络时,网络的损失或误差会减少。我没有和R一起工作过,所以R可能在幕后做了一些事情。考虑一下这个形象:随着网络的训练,“训练错误”会减少超时时间。“测试误差”最初开始减小,但一旦开始出现过拟合,则开始增大。这一点被标记为“提前停止”,因为这是你将停止训练的地方。1/2您将数据集分为3组:测试集、验证集、训练集。您可以使用验证集测试过拟合。训练的算法如下所示:虽然正确:有训练集的训练网络;新的\u验证\u分数=使用验证集时的损失;如果新的验证分数>旧的验证分数,则退出While循环;如果结束;结束时;最终得分=使用测试集时的损失;2/2. 很抱歉格式不好,但我不知道如何在注释中添加换行符。所以我用,;Nathan,谢谢你的精彩描述,我想我可以根据你的例子用R来编写