如何正确绘制训练和验证集的损耗曲线?

时间:2020-10-24 18:28:02

标签: python machine-learning scikit-learn

我想像Keras一样为训练和验证集绘制损耗曲线,但要使用Scikit。我选择了具体的数据集,这是一个回归问题,该数据集位于:

http://archive.ics.uci.edu/ml/machine-learning-databases/concrete/compressive/

因此,我已将数据转换为CSV,并且程序的第一个版本如下:

模型1

df=pd.read_csv("Concrete_Data.csv")
train,validate,test=np.split(df.sample(frac=1),[int(.8*len(df)),int(.90*len(df))])
Xtrain=train.drop(["ConcreteCompStrength"],axis="columns")
ytrain=train["ConcreteCompStrength"]
Xval=validate.drop(["ConcreteCompStrength"],axis="columns")
yval=validate["ConcreteCompStrength"]
mlp=MLPRegressor(activation="relu",max_iter=5000,solver="adam",random_state=2)
mlp.fit(Xtrain,ytrain)

plt.plot(mlp.loss_curve_,label="train")
mlp.fit(Xval,yval)                           #doubt
plt.plot(mlp.loss_curve_,label="validation") #doubt
plt.legend()

结果图如下:

enter image description here

在这个模型中,我怀疑它是否是正确的标记部分,因为只要我知道应该分开验证或测试集,那么拟合函数可能在那里不正确。我得到的分数是0.95。

模型2

在此模型中,我尝试使用验证分数,如下所示:

df=pd.read_csv("Concrete_Data.csv")
train,validate,test=np.split(df.sample(frac=1),[int(.8*len(df)),int(.90*len(df))])
Xtrain=train.drop(["ConcreteCompStrength"],axis="columns")
ytrain=train["ConcreteCompStrength"]
Xval=validate.drop(["ConcreteCompStrength"],axis="columns")
yval=validate["ConcreteCompStrength"]
mlp=MLPRegressor(activation="relu",max_iter=5000,solver="adam",random_state=2,early_stopping=True)
mlp.fit(Xtrain,ytrain)

plt.plot(mlp.loss_curve_,label="train")
plt.plot(mlp.validation_scores_,label="validation")   #line changed
plt.legend()

对于这个模型,我必须将早期停止设置的部分添加为true并进行validation_scores_进行绘制,但是图形结果有点奇怪:

enter image description here

我得到的分数是0.82,但是我读到这种情况发生在模型发现更容易预测训练集中的验证集中的数据时。我相信这是因为我正在使用validation_scores_部分,但无法找到有关此特定说明的任何在线参考。

在Scikit中绘制这些损耗曲线以调整我的超参数的正确方法是什么?

更新 我已经对模块进行了编程,就像这样:

mlp=MLPRegressor(activation="relu",max_iter=1,solver="adam",random_state=2,early_stopping=True)
training_mse = []
validation_mse = []
epochs = 5000
for epoch in range(1,epochs):
    mlp.fit(X_train, Y_train) 
    Y_pred = mlp.predict(X_train)
    curr_train_score = mean_squared_error(Y_train, Y_pred) # training performances
    Y_pred = mlp.predict(X_valid) 
    curr_valid_score = mean_squared_error(Y_valid, Y_pred) # validation performances
    training_mse.append(curr_train_score) # list of training perf to plot
    validation_mse.append(curr_valid_score) # list of valid perf to plot
plt.plot(training_mse,label="train")
plt.plot(validation_mse,label="validation")
plt.legend()

但获得的图是两条扁平线:

enter image description here

似乎我在这里缺少什么。

1 个答案:

答案 0 :(得分:2)

您不应该将模型适合验证集。验证集通常用于决定要使用的超参数,而不是参数值。

进行训练的标准方法是将数据集分为三部分

  • 培训
  • 验证
  • 测试

例如,分别分配80%,10%,10%

通常,您将选择一个神经网络(多少层,节点,什么激活函数),然后仅对训练集进行训练,在验证中检查结果,然后在测试中

我将展示一个伪算法来阐明这一点:

for model in my_networks: #hyperparameters selection
    model.fit(X_train, Y_train) # parameters fitting
    model.predict(X_valid) # no train, only check on performances
    save model performances on validation

pick the best model (the one with best scores on the validation set)
then check results on the test set
model.predict(X_test) # this will be the estimated performance of your model

如果数据集足够大,则还可以使用交叉验证之类的方法

无论如何,请记住:

  • 参数是网络权重
  • 您将参数与训练集拟合
  • 超参数是定义网络体系结构(层,节点,激活功能)的参数
  • 您选择最佳的超参数,以检查验证集中的模型结果
  • 选择(最佳参数,最佳超参数)后,您将获得在测试集上测试模型的模型性能

要获得相同的keras结果,您应该理解,当使用默认参数在模型上调用方法.fit时,训练将在固定数量的时期(200)后以您定义的次数停止历元(在您的情况下为5000)或您定义early_stopping时。

max_iter:整数,默认为200

最大迭代次数。求解器迭代直到收敛(由“ tol”确定)或此迭代次数为止。对于 随机求解器(“ sgd”,“ adam”),请注意,这决定了 时期数(每个数据点将使用多少次),而不是 梯度步数。

scikit page

上检查模型定义和参数

要获得相同的角膜结果,您可以修复训练纪元(例如,每次训练1个步骤),在验证后检查结果,然后再次训练,直到达到所需的纪元数

例如,如下所示(如果您的模型使用mse):

from sklearn.metrics import mean_squared_error
epochs = 5000

mlp = MLPRegressor(activation="relu", max_iter=1, solver="adam", random_state=2, early_stopping=True)
training_mse = []
validation_mse = []
for epoch in epochs:
    mlp.fit(X_train, Y_train) 
    Y_pred = mlp.predict(X_train)
    curr_train_score = mean_squared_error(Y_train, Y_pred) # training performances
    Y_pred = mlp.predict(X_valid) 
    curr_valid_score = mean_squared_error(Y_valid, Y_pred) # validation performances
    training_mse.append(curr_train_score) # list of training perf to plot
    validation_mse.append(curr_valid_score) # list of valid perf to plot