报告训练和泛化性能的正确做法和方法

Correct practice and approach for reporting the training and generalization performance

我正在尝试学习为 classification 训练神经网络的正确程序。那里有很多教程,但它们从不解释如何报告泛化性能。有人可以告诉我以下方法是否正确。我使用了来自 fisheriris 数据集的前 100 个示例,这些示例具有标签 1,2,并将它们分别称为 XY。然后我将 X 拆分为 trainDataXtest,拆分比例为 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;

那么怎么上报结果呢?仅用于测试数据。火车数据会过度拟合,并会显示错误的、太好的结果。如果您使用验证数据(您没有),那么您将无法显示它的结果,因为它也会出现过度拟合。如果你让训练为你做验证,你的测试结果将不会过拟合。