我需要使用SVM来将28×28的矩阵分类到9个类别中。有60,000个训练输入和10,000个测试输入。
我当前的程序如下:
clear;load mnist.matxtest = xtest ./ 255; <--- 归一化数据xtrain = xtrain ./ 255;SVMModels = cell(9,1);classes = unique(ytrain);rng(1); % 为了可重复性blah = fitcsvm(xtrain, ytrain);for j = 1:numel(classes); indx = strcmp(ytrain,classes(j)); % 为每个分类器创建二元类别 SVMModels{j} = fitcsvm(xtrain,indx, 'KernelFunction','rbf','BoxConstraint',1);end
我认为问题可能是因为输入是28×28的矩阵。我该如何解决这个问题?
附加信息:
xtest: 28x28x10000ytest = 1x10000xtrain = 28x28x60000ytrain = 1x60000
回答:
你是对的。fitcsvm
要求输入的训练样本是一个N x P
的矩阵,其中N
是样本总数,P
是特征总数。在你的情况下,你需要重塑你的数组,使xtrain
和xtest
变成60000 x 784
。784是由于28 x 28
。具体来说,你必须展开你的3D矩阵的每一层,使其适合一个单一的向量。同样,类别标签必须是N x 1
,所以你只需要转置ytrain
和ytest
即可。
为了实现所需的重塑,你可以像这样使用reshape
:
xtrain_final = reshape(xtrain, 784, 60000).'; %'xtest_final = reshape(xtest, 784, 60000).'; %'ytrain_final = ytrain.'; %'ytest_final = ytest.'; %'
现在,训练和测试样本的重塑有点奇怪。MATLAB在重塑时是以列为主的。这意味着在重塑时,它一次处理一列来生成结果。因此,因为你的矩阵是28 x 28 x 60000
,你的3D矩阵的每一层是28 x 28
。因此,为了适应列主顺序,你需要将每个2D层调整到一个单一的列。这样,你将有60000列对应于60000个训练样本。现在你需要做的最后一件事是转置这个结果,以获得fitcsvm
所需的格式。
完成这些后,你就可以训练你的模型了。