报告训练和泛化性能的正确做法和方法
Correct practice and approach for reporting the training and generalization performance
我正在尝试学习为 classification 训练神经网络的正确程序。那里有很多教程,但它们从不解释如何报告泛化性能。有人可以告诉我以下方法是否正确。我使用了来自 fisheriris 数据集的前 100 个示例,这些示例具有标签 1,2,并将它们分别称为 X
和 Y
。然后我将 X
拆分为 trainData
和 Xtest
,拆分比例为 90/10。使用 trainData
我训练了 NN 模型。现在 NN 在内部进一步将 trainData
拆分为 tr、val、test 子集。我的困惑是,在向 conferences/Journals 中的未见数据报告模型性能时,通常使用哪一个来进行泛化?
可以在 link 中找到数据集:https://www.mathworks.com/matlabcentral/fileexchange/71468-simple-neural-networks-with-k-fold-cross-validation-manner
rng('default')
load iris.mat;
X = [f(1:100,:) l(1:100)];
numExamples = size(X,1);
indx = randperm(numExamples);
X = X(indx,:);
Y = X(:,end);
split1 = cvpartition(Y,'Holdout',0.1,'Stratify',true); %90% trainval 10% test
istrainval = training(split1); % index for fitting
istest = test(split1); % indices for quality assessment
trainData = X(istrainval,:);
Xtest = X(istest,:);
Ytest = Y(istest);
numExamplesXtrainval = size(trainData,1);
indxXtrainval = randperm(numExamplesXtrainval);
trainData = trainData(indxXtrainval,:);
Ytrain = trainData(:,end);
hiddenLayerSize = 10;
% data format = rows = number of dim, column = number of examples
net = patternnet(hiddenLayerSize);
net = init(net);
net.performFcn = 'crossentropy';
net.trainFcn = 'trainscg';
net.trainParam.epochs=50;
[net tr]= train(net,trainData', Ytrain');
Trained = sim(net, trainData'); %outputs predicted labels
train_predict = net(trainData');
performanceTrain = perform(net,Ytrain',train_predict)
lbl_train=grp2idx(Ytrain);
Yhat_train = (train_predict >= 0.5);
Lbl_Yhat_Train = grp2idx(Yhat_train);
[cmMatrixTrain]= confusionmat(lbl_train,Lbl_Yhat_Train )
accTrain=sum(lbl_train ==Lbl_Yhat_Train)/size(lbl_train,1);
disp(['Training Set: Total Train Acccuracy by MLP = ',num2str(100*accTrain ), '%'])
[confTest] = confusionmat(lbl_train(tr.testInd),Lbl_Yhat_Train(tr.testInd) )
%unknown test
test_predict = net(Xtest');
performanceTest = perform(net,Ytest',test_predict);
Yhat_test = (test_predict >= 0.5);
test_lbl=grp2idx(Ytest);
Lbl_Yhat_Test = grp2idx(Yhat_test);
[cmMatrix_Test]= confusionmat(test_lbl,Lbl_Yhat_Test )
这是输出。
问题1:似乎没有对另一个class的预测。为什么?
问题 2:我是否需要像我创建的 Xtest
那样的单独数据集来报告泛化错误,还是使用数据 trainData(tr.testInd,:)
作为泛化测试集的做法?我是否创建了一个不必要的子集?
performanceTrain =
2.2204e-16
cmMatrixTrain =
45 0
45 0
Training Set: Total Train Acccuracy by MLP = 50%
confTest =
9 0
5 0
cmMatrix_Test =
5 0
5 0
代码存在一些问题。在回答您的问题之前,让我们先了解一下它们。首先,您将决策阈值设置为 0.5 (Yhat_train = (train_predict >= 0.5);
),而您的净预测的所有点都在 0.5 以上。这意味着您只会在混淆矩阵中得到零。您可以绘制分数以选择更好的阈值:
figure;
plot(train_predict(Ytrain == 1),'.b')
hold on
plot(train_predict(Ytrain == 2),'.r')
legend('label 1','label 2')
cvpartition 给我一个错误。它 运行 成功地 split1 = cvpartition(Y,'Holdout',0.1);
在任何情况下,人工神经网络通常会在训练过程中管理分区,因此您输入 X 和 Y 以及一些参数来了解如何进行。例如,请参见此处:link 设置
的位置
net.divideParam.trainRatio = .4;
net.divideParam.valRatio = .3;
net.divideParam.testRatio = .3;
那么怎么上报结果呢?仅用于测试数据。火车数据会过度拟合,并会显示错误的、太好的结果。如果您使用验证数据(您没有),那么您将无法显示它的结果,因为它也会出现过度拟合。如果你让训练为你做验证,你的测试结果将不会过拟合。
我正在尝试学习为 classification 训练神经网络的正确程序。那里有很多教程,但它们从不解释如何报告泛化性能。有人可以告诉我以下方法是否正确。我使用了来自 fisheriris 数据集的前 100 个示例,这些示例具有标签 1,2,并将它们分别称为 X
和 Y
。然后我将 X
拆分为 trainData
和 Xtest
,拆分比例为 90/10。使用 trainData
我训练了 NN 模型。现在 NN 在内部进一步将 trainData
拆分为 tr、val、test 子集。我的困惑是,在向 conferences/Journals 中的未见数据报告模型性能时,通常使用哪一个来进行泛化?
可以在 link 中找到数据集:https://www.mathworks.com/matlabcentral/fileexchange/71468-simple-neural-networks-with-k-fold-cross-validation-manner
rng('default')
load iris.mat;
X = [f(1:100,:) l(1:100)];
numExamples = size(X,1);
indx = randperm(numExamples);
X = X(indx,:);
Y = X(:,end);
split1 = cvpartition(Y,'Holdout',0.1,'Stratify',true); %90% trainval 10% test
istrainval = training(split1); % index for fitting
istest = test(split1); % indices for quality assessment
trainData = X(istrainval,:);
Xtest = X(istest,:);
Ytest = Y(istest);
numExamplesXtrainval = size(trainData,1);
indxXtrainval = randperm(numExamplesXtrainval);
trainData = trainData(indxXtrainval,:);
Ytrain = trainData(:,end);
hiddenLayerSize = 10;
% data format = rows = number of dim, column = number of examples
net = patternnet(hiddenLayerSize);
net = init(net);
net.performFcn = 'crossentropy';
net.trainFcn = 'trainscg';
net.trainParam.epochs=50;
[net tr]= train(net,trainData', Ytrain');
Trained = sim(net, trainData'); %outputs predicted labels
train_predict = net(trainData');
performanceTrain = perform(net,Ytrain',train_predict)
lbl_train=grp2idx(Ytrain);
Yhat_train = (train_predict >= 0.5);
Lbl_Yhat_Train = grp2idx(Yhat_train);
[cmMatrixTrain]= confusionmat(lbl_train,Lbl_Yhat_Train )
accTrain=sum(lbl_train ==Lbl_Yhat_Train)/size(lbl_train,1);
disp(['Training Set: Total Train Acccuracy by MLP = ',num2str(100*accTrain ), '%'])
[confTest] = confusionmat(lbl_train(tr.testInd),Lbl_Yhat_Train(tr.testInd) )
%unknown test
test_predict = net(Xtest');
performanceTest = perform(net,Ytest',test_predict);
Yhat_test = (test_predict >= 0.5);
test_lbl=grp2idx(Ytest);
Lbl_Yhat_Test = grp2idx(Yhat_test);
[cmMatrix_Test]= confusionmat(test_lbl,Lbl_Yhat_Test )
这是输出。
问题1:似乎没有对另一个class的预测。为什么?
问题 2:我是否需要像我创建的 Xtest
那样的单独数据集来报告泛化错误,还是使用数据 trainData(tr.testInd,:)
作为泛化测试集的做法?我是否创建了一个不必要的子集?
performanceTrain =
2.2204e-16
cmMatrixTrain =
45 0
45 0
Training Set: Total Train Acccuracy by MLP = 50%
confTest =
9 0
5 0
cmMatrix_Test =
5 0
5 0
代码存在一些问题。在回答您的问题之前,让我们先了解一下它们。首先,您将决策阈值设置为 0.5 (Yhat_train = (train_predict >= 0.5);
),而您的净预测的所有点都在 0.5 以上。这意味着您只会在混淆矩阵中得到零。您可以绘制分数以选择更好的阈值:
figure;
plot(train_predict(Ytrain == 1),'.b')
hold on
plot(train_predict(Ytrain == 2),'.r')
legend('label 1','label 2')
cvpartition 给我一个错误。它 运行 成功地 split1 = cvpartition(Y,'Holdout',0.1);
在任何情况下,人工神经网络通常会在训练过程中管理分区,因此您输入 X 和 Y 以及一些参数来了解如何进行。例如,请参见此处:link 设置
net.divideParam.trainRatio = .4;
net.divideParam.valRatio = .3;
net.divideParam.testRatio = .3;
那么怎么上报结果呢?仅用于测试数据。火车数据会过度拟合,并会显示错误的、太好的结果。如果您使用验证数据(您没有),那么您将无法显示它的结果,因为它也会出现过度拟合。如果你让训练为你做验证,你的测试结果将不会过拟合。