matlab利用hinge loss实现多分类SVM

1 介绍

本文将介绍hinge loss E(w) 以及其梯度 E(w) 。并利用批量梯度下降方法来优化hinge loss实现SVM多分类。利用hinge loss在手写字数据库上实验,能达到87.040%的正确识别率。


2. hinge loss

  1. 根据二分类的SVM目标函数,我们可以定义多分类的SVM目标函数:
    E(w1,,wk)=kj=112||wj||2+Cni=1L((w1,,wk),(xi,yi)) .

其中 T={(x1,y1),,(xn,yn)} 为训练集。 L((w1,,wk),(x,y))=max(0,maxyywTyx+1wTyx) . 二分类SVM转化为多分类SVM的相关资料和公式推导可以参见其他文献。
2. 接下介绍 E(w) 的梯度计算。
(a) 如果 wTywTy^x+1 , 那么

L((w1,w2,,wk),(x,y))wj,l=0

(b) 如果 wTy<wTy^x+1 j=y , 那么

L((w1,w2,,wk),(x,y))wj,l=xl

(c) 如果 wTy<wTy^x+1 j=y^ , 那么

L((w1,w2,,wk),(x,y))wj,l=xl

(d) 如果 wTy<wTy^x+1 jy and jy^ , 那么

L((w1,w2,,wk),(x,y))wj,l=0

  1. 利用梯度下降法更新 W={w1,,wk} :
    Wt=Wt1rE(Wt1)

3 code

Muliticlass_svm.m

% 作者:何凌霄
% 中科院自动化所
% 2017315
clear all
clc
%% STEP 0: Initialise constants and parameters
inputSize = 28 * 28; % Size of input vector (MNIST images are 28x28)
numClasses = 10;     % Number of classes (MNIST images fall into 10 classes)
lambda = 1e-2; % Weight decay parameter
learning_rate = 0.1;
iteration=400;
%%======================================================================
%% STEP 1: Load data
load('digits.mat')
images = [train1; train2; train3; train4; train5; train6; train7; train8; train9;train0];
images = images';
labels = [ones(500,1);2*ones(500,1);3*ones(500,1);4*ones(500,1);5*ones(500,1);6*ones(500,1);7*ones(500,1);8*ones(500,1);9*ones(500,1);10*ones(500,1)];
index = randperm(500*10);
images = images(:,index);
labels = labels(index);
inputData = images;
%% STEP 2: Train multiclass svm
[cost, grad, svmOptTheta] = multisvmtrain(numClasses, inputSize, lambda, inputData, labels, iteration, learning_rate);
%% STEP 3: Test
images = [test1; test2; test3; test4; test5; test6; test7; test8; test9;test0];
images = images';
labels = [ones(500,1);2*ones(500,1);3*ones(500,1);4*ones(500,1);5*ones(500,1);6*ones(500,1);7*ones(500,1);8*ones(500,1);9*ones(500,1);10*ones(500,1)];

inputData = images;
svmModel.optTheta = reshape(svmOptTheta, numClasses, inputSize);
svmModel.inputSize = inputSize;
svmModel.numClasses = numClasses;

% You will have to implement softmaxPredict in softmaxPredict.m
[pred] = Multi_SVMPredict(svmModel, inputData);
acc = mean(labels(:) == pred(:));
num_in_class = 500*ones(10,1)';
for i=1:10
    name_class{i}=num2str(i);
end
[confusion_matrix]=compute_confusion_matrix(pred,num_in_class,name_class);
figure; visualize(svmOptTheta');
fprintf('Accuracy: %0.3f%%\n', acc * 100);

multisvmtrain.m

% 作者:何凌霄
% 中科院自动化所
% 2017年3月15
function [lcost, grad, theta] = multisvmtrain(numClasses, inputSize, lambda, data, labels, iteration, learning_rate)
theta = 0.005 * randn(numClasses * inputSize, 1);
theta = reshape(theta, numClasses, inputSize);%将输入的参数列向量变成一个矩阵
numCases = size(data, 2);%输入样本的个数
groundTruth = full(sparse(labels, 1:numCases, 1));%这里sparse是生成一个稀疏矩阵,该矩阵中的值都是第三个值1
cost = 0;
thetagrad = zeros(numClasses, inputSize);
for i = 1:iteration
    [Q, X, cost] = multi_hingeloss_cost(theta, data, groundTruth,lambda);
    [thetagrad] = multi_hingeloss_grad(data,theta, Q, groundTruth, lambda, labels);
    theta = theta - learning_rate*thetagrad;
    lcost(i) = cost;
    grad(i) = sum(sum(thetagrad));
    fprintf('%d, %f\n', i, cost);
end
end

multi_hingeloss_cost.m

% 作者:何凌霄
% 中科院自动化所
% 2017年3月15
function [Q, X, cost] = multi_hingeloss_cost(theta, data, groundTruth,lambda)
groundTruth1 = groundTruth;
groundTruth(find(groundTruth==1)) = -inf;  
groundTruth(find(groundTruth==0)) = 1; 
X = theta*data;
Q = X;
Q = Q.*groundTruth;
Q(find(Q==inf)) = -inf;
temp = X.*groundTruth1;
temp(find(temp==0))=[];
t = max(0, 1 - temp + max(Q));
cost = 1/size(data,2)*sum(t)+lambda*sum(theta(:).^2);

multi_hingeloss_grad.m

% 作者:何凌霄
% 中科院自动化所
% 2017年3月15
function [thetagrad] = multi_hingeloss_grad(data, theta, Q, groundTruth, lambda, labels)
X = theta*data;
[~,q] = max(Q);
Xq = full(sparse(q, 1:size(X,2), 1));
if size(Xq,1)<10
    for i = 1:10-size(Xq,1)
        Xq = [Xq;zeros(1, size(Xq,2))];
    end
end
temp = X.*groundTruth;
temp1 = X.*Xq;
temp1(find(temp1==0))=[];
temp(find(temp==0))=[];
W=(temp - temp1)<1;
Y = zeros(size(X));

for i=1:size(X,2)
    Y(labels(i),i) = -W(i);
    Y(q(i),i) = W(i);
end
thetagrad = 1/size(X,2)*Y*data' + lambda * theta;

Multi_SVMPredict.m

% 作者:何凌霄
% 中科院自动化所
% 2017年3月15
function [pred] = Multi_SVMPredict(svmModel, data)
theta = svmModel.optTheta;  % this provides a numClasses x inputSize matrix
pred = zeros(1, size(data, 2));
[nop, pred] = max(theta * data);
end

compute_confusion_matrix.m

[confusion_matrix]=compute_confusion_matrix(predict_label,num_in_class,name_class)%预测标签,每一类的数目,类别数目  
%predict_label为一维行向量  
%num_in_class代表每一类的个数  
%name_class代表类名  
num_class=length(num_in_class);  
num_in_class=[0 num_in_class];  
confusion_matrix=size(num_class,num_class);  

for ci=1:num_class  
    for cj=1:num_class  
        summer=0;%统计对应标签个数  
        c_start=sum(num_in_class(1:ci))+1;  
        c_end=sum(num_in_class(1:ci+1));  
        summer=size(find(predict_label(c_start:c_end)==cj),2);  
        confusion_matrix(ci,cj)=summer/num_in_class(ci+1);  
    end  
end  

draw_cm(confusion_matrix,name_class,num_class);  

end  

function draw_cm.m

function draw_cm(mat,tick,num_class)  

imagesc(1:num_class,1:num_class,mat);            %# in color  
colormap(flipud(gray));  %# for gray; black for large value.  

textStrings = num2str(mat(:),'%0.2f');    
textStrings = strtrim(cellstr(textStrings));   
[x,y] = meshgrid(1:num_class);   
hStrings = text(x(:),y(:),textStrings(:), 'HorizontalAlignment','center');  
midValue = mean(get(gca,'CLim'));   
textColors = repmat(mat(:) > midValue,1,3);   
set(hStrings,{'Color'},num2cell(textColors,2));  %# Change the text colors  

set(gca,'xticklabel',tick,'XAxisLocation','top');  
set(gca, 'XTick', 1:num_class, 'YTick', 1:num_class);  
set(gca,'yticklabel',tick);  
rotateXLabels(gca, 315 );% rotate the x tick  

visualize.m

function r=visualize(X, mm, s1, s2)
%FROM RBMLIB http://code.google.com/p/matrbm/
%Visualize weights X. If the function is called as a void method,
%it does the plotting. But if the function is assigned to a variable 
%outside of this code, the formed image is returned instead.
if ~exist('mm','var')
    mm = [min(X(:)) max(X(:))];
end
if ~exist('s1','var')
    s1 = 0;
end
if ~exist('s2','var')
    s2 = 0;
end

[D,N]= size(X);
s=sqrt(D);
if s==floor(s) || (s1 ~=0 && s2 ~=0)
    if (s1 ==0 || s2 ==0)
        s1 = s; s2 = s;
    end
    %its a square, so data is probably an image
    num=ceil(sqrt(N));
    a=mm(2)*ones(num*s2+num-1,num*s1+num-1);
    x=0;
    y=0;
    for i=1:N
        im = reshape(X(:,i),s1,s2)';
        a(x*s2+1+x : x*s2+s2+x, y*s1+1+y : y*s1+s1+y)=im;
        x=x+1;
        if(x>=num)
            x=0;
            y=y+1;
        end
    end
    d=true;
else
    %there is not much we can do
    a=X;
end

%return the image, or plot the image
if nargout==1
    r=a;
else

    imagesc(a, [mm(1) mm(2)]);
    axis equal
    colormap gray

end

得到的识别率为87.040%,hinge loss可以和任何深度网络结合完成分类任务。
最后得到的混淆矩阵如下:
这里写图片描述

损失函数图像:
这里写图片描述

数据集见资源,如引用此代码,请注明出处。

### 回答1: SVM多分类预测是指在SVM算法的基础上,对于多个类别的分类任务进行预测。MATLAB作为一种常用的科学计算软件,也提供了相应的SVM多分类预测函数。 首先,需要准备好带标签的训练数据集和测试数据集,用于训练和测试模型。然后,可以使用MATLAB中的fitcecoc函数来建立多分类SVM模型。fitcecoc函数的主要输入参数包括训练数据集和对应标签,SVM模型类型,以及其他相关参数,例如惩罚参数、核函数等。 建立好模型之后,可以使用predict函数来对测试数据进行预测。predict函数会返回每个测试数据属于哪个类别的概率值,在多分类情况下,概率值最大的类别即为预测结果。 具体的代码实现步骤如下: 1. 准备训练数据集和测试数据集。 2. 建立多分类SVM模型: svmModel = fitcecoc(trainData, trainLabel, 'KernelFunction', 'linear', 'Coding', 'onevsall', 'Verbose', 2); 其中,trainData是训练数据集,trainLabel是对应的标签信息,'KernelFunction'参数指定核函数为线性核,'Coding'参数指定使用one-vs-all方法进行多分类,'Verbose'参数为2表示输出详细的训练过程信息。 3. 使用模型进行预测: predictResult = predict(svmModel, testData); 其中,svmModel是已经建立好的SVM模型,testData是测试数据集,predictResult是预测结果。 需要注意的是,SVM模型的性能很大程度上取决于参数的选择和调整。如果模型的预测效果不佳,可以尝试调整参数来进行优化。例如,可以通过交叉验证等方法来选择合适的惩罚参数和核函数类型。 ### 回答2: SVM(支持向量机)是常见的分类算法之一,可以用于二分类和多分类问题。在MATLAB中,可以使用Classification Learner App来自动生成支持向量机分类器的代码,也可以手动编写代码实现SVM多分类预测的MATLAB代码如下: 1. 数据准备和预处理 首先需要准备数据集,将其划分为训练集和测试集,并进行数据预处理。 load fisheriris %导入数据 inds = ~strcmp(species,'setosa'); %将setosa类别排除在外,保留versicolor和virginica X = meas(inds,:); %获取特征向量数据 Y = species(inds); %获取标签数据 cvp = cvpartition(Y,'holdout',0.25); %将数据分为训练集和测试集 Xtrain = X(cvp.training,:); Ytrain = Y(cvp.training,:); Xtest = X(cvp.test,:); Ytest = Y(cvp.test,:); 2. SVM训练和预测 接着,需要定义SVM分类器的参数,并训练多分类SVM模型。 SVMmdl = fitcecoc(Xtrain,Ytrain,'KernelFunction','rbf','Standardize',true); %定义SVM分类器参数,训练多分类SVM模型 最后,使用测试集进行预测,并计算预测结果的准确率。 Ypred = predict(SVMmdl,Xtest); %使用测试集进行预测 accuracy = sum(Ypred==Ytest)/numel(Ytest) %计算预测结果的准确率 完整代码如下: %% 多分类SVM预测代码 % 数据准备和预处理 load fisheriris %导入数据 inds = ~strcmp(species,'setosa'); %将setosa类别排除在外,保留versicolor和virginica X = meas(inds,:); %获取特征向量数据 Y = species(inds); %获取标签数据 cvp = cvpartition(Y,'holdout',0.25); %将数据分为训练集和测试集 Xtrain = X(cvp.training,:); Ytrain = Y(cvp.training,:); Xtest = X(cvp.test,:); Ytest = Y(cvp.test,:); % SVM训练和预测 SVMmdl = fitcecoc(Xtrain,Ytrain,'KernelFunction','rbf','Standardize',true); %定义SVM分类器参数,训练多分类SVM模型 Ypred = predict(SVMmdl,Xtest); %使用测试集进行预测 accuracy = sum(Ypred==Ytest)/numel(Ytest) %计算预测结果的准确率 以上就是SVM多分类预测的MATLAB代码。需要注意的是,代码中使用的是径向基函数(RBF)作为核函数,也可以使用其他的核函数如线性核函数、多项式核函数等。此外,还可以通过调整模型参数和优化算法来提高预测准确率,这需要根据具体问题进行调整。 ### 回答3: SVM(支持向量机)是一种用于二分类或多分类的机器学习算法,它通过将数据映射到高维空间中进行分类。在MATLAB中,SVM多分类预测可以通过以下步骤实现: 1. 准备数据集:首先,需要准备一个包含标签和特征值的数据集。标签指数据集中的每个数据所属的类别,特征值指用来分辨不同类别的一些特征。在MATLAB中,可以使用table或array来表示数据集。 2. 拆分数据集:为了训练模型并测试其准确性,需要将数据集拆分成训练集和测试集。在MATLAB中,可以使用cvpartition函数将数据集拆分成训练集和测试集。 3. 训练SVM分类器:接下来,需要使用fitcecoc函数创建一个SVM分类器。fitcecoc函数允许使用一对一方法将多分类问题转化为多个二分类问题,并使用支持向量机来解决这些二分类问题。 4. 预测新的数据:使用predict函数可以对新的数据进行分类预测。预测结果是一个向量,包含数据集中每个数据的分类结果。 下面是一个简单的SVM多分类预测MATLAB代码示例: ```matlab % 准备数据集 data = readtable('data.csv'); labels = data(:,end); features = data(:,1:end-1); % 拆分数据集 cv = cvpartition(size(data,1),'HoldOut',0.3); train_data = features(training(cv),:); train_labels = labels(training(cv),:); test_data = features(test(cv),:); test_labels = labels(test(cv),:); % 训练SVM分类器 svm_model = fitcecoc(train_data,train_labels); % 预测新的数据 predicted_labels = predict(svm_model,test_data); accuracy = sum(predicted_labels == test_labels)/numel(test_labels); disp(['分类准确率为:',num2str(accuracy)]); ``` 代码中,我们首先使用readtable函数读取数据文件,并将标签和特征值分别存储在labels和features变量中。然后,我们使用cvpartition函数将数据集拆分成训练集和测试集。根据一般惯例,我们将数据集拆分成70%的训练集和30%的测试集。接下来,我们使用fitcecoc函数创建一个SVM分类器,并使用训练集中的数据进行训练。最后,我们使用predict函数对测试集中的数据进行分类预测,并计算分类准确率。 需要注意的是,SVM算法的性能很大程度上依赖于特征选择和参数调整。通常需要对不同的特征选择和参数组合进行试验来找到最佳方案。
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值