2011-02-03 7 views
8

sto rivedendo un codice da Toronto perceptron MATLAB codeImplementazione e ploting un percettrone in MATLAB

Il codice è

function [w] = perceptron(X,Y,w_init) 

w = w_init; 
for iteration = 1 : 100 %<- in practice, use some stopping criterion! 
    for ii = 1 : size(X,2)   %cycle through training set 
    if sign(w'*X(:,ii)) ~= Y(ii) %wrong decision? 
     w = w + X(:,ii) * Y(ii); %then add (or subtract) this point to w 
    end 
    end 
    sum(sign(w'*X)~=Y)/size(X,2) %show misclassification rate 
end 

Così stavo leggendo come applicare questa funzione per i dati matrice X e Y bersaglio, ma, non so come usare questa funzione, capisco, restituisce un vettore di pesi, quindi può classificarlo.

Potrebbe per favore dare un esempio e spiegarlo ??

Ive ha provato

X=[0 0; 0 1; 1 1] 
Y=[1 0; 2 1] 
w=[1 1 1] 
Result = perceptron(X, Y, w) 

??? Error using ==> mtimes 
Inner matrix dimensions must agree. 

Error in ==> perceptron at 15 
      if sign(w'*X(:,ii)) ~= Y(ii) 

    Result = perceptron(X, Y, w') 

??? Error using ==> ne 
Matrix dimensions must agree. 

Error in ==> perceptron at 19 
     sum(sign(w'*X)~=Y)/size(X,2);  

Grazie

Grazie per i anwers, ho avuto uno di più, Se cambio la Y = [0, 1], che cosa succede all'algoritmo ?.

Quindi, eventuali dati di ingresso non funzionano con Y = [0,1] con questo codice del percettrone destra ?,

-------------- --------------- EDIT ------------------------

Un'altra domanda, se Voglio tracciare la linea che divide le 2 classi, so che possiamo ottenere quella linea che risolve il sistema di equazioni lineari che ha a che fare con i pesi, ma come, cosa posso fare ?, sto provando qualcosa come

% the initial weights 
w_init = [ 1 1 1]'; 
% the weights returned from perceptron  
wtag = perceptron(X,Y,w_init,15); 

% concatenate both 
Line = [wtag,w_init] 

% solve the linear system, am I correct doing this? 
rref(Line') 

% plot??? 

risposta

17

Si dovrebbe prima capire che cosa è il significato di ciascuno degli ingressi:

  • X è la matrice di ingresso di esempi, di dimensione M x N, dove M è la dimensione del vettore funzione e N il numero di campioni. Poiché il modello perceptron per la previsione è Y=w*X+b, è necessario fornire una dimensione aggiuntiva in X che è costante, in genere impostata su 1, quindi il termine b è "incorporato" in X. Nell'esempio seguente per X, ho impostato l'ultima voce di X in 1 in tutti gli esempi.
  • Y è la classificazione corretta per ciascun campione da X (la classificazione che si desidera che perceptron apprenda), quindi dovrebbe essere un vettore di riga N dimensionale - un output per ogni esempio di input. Poiché perceptron è un classificatore binario , dovrebbe avere solo 2 valori distinti possibili. Guardando nel codice, si vede che controlla il segno della previsione, che ti dice che i valori consentiti di Y dovrebbero essere -1,+1 (e non 0,1 per esempio).
  • w è il vettore di peso che si sta tentando di apprendere.

Quindi, cercare di chiamare la funzione con:

X=[0 0; 0 1; 1 1]; 
Y=[1 -1]; 
w=[.5; .5; .5]; 

EDIT

Utilizzare il seguente codice per chiamare l'alg perceptron e vedere i risultati graficamente:

% input samples 
X1=[rand(1,100);rand(1,100);ones(1,100)]; % class '+1' 
X2=[rand(1,100);1+rand(1,100);ones(1,100)]; % class '-1' 
X=[X1,X2]; 

% output class [-1,+1]; 
Y=[-ones(1,100),ones(1,100)]; 

% init weigth vector 
w=[.5 .5 .5]'; 

% call perceptron 
wtag=perceptron(X,Y,w); 
% predict 
ytag=wtag'*X; 


% plot prediction over origianl data 
figure;hold on 
plot(X1(1,:),X1(2,:),'b.') 
plot(X2(1,:),X2(2,:),'r.') 

plot(X(1,ytag<0),X(2,ytag<0),'bo') 
plot(X(1,ytag>0),X(2,ytag>0),'ro') 
legend('class -1','class +1','pred -1','pred +1') 
+0

Risposta piacevole !! – qdjm

+1

Grazie mille, ho davvero capito il tuo esempio, ma ho ancora una domanda: Cosa faresti se la classe 1 avesse più esempi della classe 0 ?? nell'esempio fornito ci sono lo stesso numero di esempi per entrambe le classi, X1 e X2 – cMinor

+0

È corretto, non posso verificarlo adesso: X1 = [rand (1.100); rand (1.100); uno (1.100)]; % classe '+1' X2 = [rand (1.300); 1 + rand (1.300); uno (1.300)]; % class '-1' X = [X1, X2]; classe di uscita% [-1, + 1]; Y = [- uno (1.100), uno (1.300)]; vettore peso iniziale% w = [.5 .5 .5] '; wtag = perceptron (X, Y, w); – cMinor

1

prova:

perceptron([1 2 1 2], [1 0 1 0], 0.5); 
+4

L'esempio non funzionerà, poiché l'algoritmo presuppone valori di uscita di [-1, + 1], non [0,1]. Il vettore 'w' non verrà aggiornato. –

+3

Inoltre, l'input dovrebbe essere almeno della dimensione 2, altrimenti si assume esplicitamente che 'b = 0' in' y = a * x + b' –

10

Se sei interessato, ecco una piccola demo perceptron scritta in modo abbastanza tutorial:

function perceptronDemo 
%PERCEPTRONDEMO 
% 
% A simple demonstration of the perceptron algorithm for training 
% a linear classifier, made as readable as possible for tutorial 
% purposes. It is derived from the treatment of linear learning 
% machines presented in Chapter 2 of "An Introduction to Support 
% Vector Machines" by Nello Cristianini and John Shawe-Taylor. 
% 
% 

    Data = createTrainingData; 
    Model = trainPerceptron(Data); 

end 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
function Model = trainPerceptron(Data) 
%TRAINPERCEPTRON 

    DOWN = 1; 
    ACROSS = 2; 

    assert(isequal(unique(Data.labels), [-1; +1]), ... 
     'Labels must be -1 or +1'); 

    % --------------------------------------------------------------------- 
    % Normalise the data by calculating z-scores 
    % 
    % This makes plotting easier, but is not needed by the algorithm. 
    % 

    sampleMean = mean(Data.samples); 
    sampleStdDev = std( Data.samples); 
    Data.samples = bsxfun(@minus, Data.samples, sampleMean ); 
    Data.samples = bsxfun(@rdivide, Data.samples, sampleStdDev); 

    % --------------------------------------------------------------------- 
    % Calculate the squared radius of the smallest ball that encloses the 
    % data and is centred on the origin. This is used to provide an 
    % appropriate range and step size when updating the threshold (bias) 
    % parameter. 
    % 

    sampleSize = size(Data.samples, DOWN); 
    maxNorm = realmin; 
    for iObservation = 1:sampleSize 
     observationNorm = norm(Data.samples(iObservation,:)); 
     if observationNorm > maxNorm 
      maxNorm = observationNorm; 
     end 
    end 
    enclosingBallRadius  = maxNorm; 
    enclosingBallRadiusSquared = enclosingBallRadius .^ 2; 

    % --------------------------------------------------------------------- 
    % Define the starting weight vector and bias. These should be zeros, 
    % as the algorithm omits a learning rate, and it is suggested in 
    % Cristianini & Shawe-Taylor that learning rate may only be omitted 
    % safely when the starting weight vector and bias are zero. 
    % 

    Model.weights = [0.0 0.0]; 
    Model.bias = 0.0; 

    % --------------------------------------------------------------------- 
    % Run the perceptron training algorithm 
    % 
    % To prevent program running forever when nonseparable data are 
    % provided, limit the number of steps in the outer loop. 
    % 

    maxNumSteps = 1000; 

    for iStep = 1:maxNumSteps 

     isAnyObsMisclassified = false; 

     for iObservation = 1:sampleSize; 

      inputObservation = Data.samples(iObservation, :); 
      desiredLabel  = Data.labels( iObservation ); % +1 or -1 

      perceptronOutput = sum(Model.weights .* inputObservation, ACROSS) + Model.bias; 
      margin   = desiredLabel * perceptronOutput; 

      isCorrectLabel = margin > 0; 

      % ------------------------------------------------------------- 
      % If the model misclassifies the observation, update the 
      % weights and the bias. 
      % 

      if ~isCorrectLabel 

       isAnyObsMisclassified = true; 

       weightCorrection = desiredLabel * inputObservation; 
       Model.weights = Model.weights + weightCorrection; 

       biasCorrection = desiredLabel .* enclosingBallRadiusSquared; 
       Model.bias  = Model.bias + biasCorrection; 

       displayPerceptronState(Data, Model); 

      end % if this observation misclassified. 

     end % loop over observations 

     if ~isAnyObsMisclassified 
      disp('Done!'); 
      break; 
     end 

    end % outer loop 

end % TRAINPERCEPTRON 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
function Data = createTrainingData 
%CREATETRAININGDATA 
% 
% Return a structure containing training data suitable for linear 
% classification. 
% 

    sampleAsize = 1024; 
    sampleBsize = 1024; 

    sampleAmean = [ 5.5 5.0 ]; 
    sampleAstdDev = [ 0.5 1.0 ]; 

    sampleBmean = [ 2.5 3.0 ]; 
    sampleBstdDev = [ 0.3 0.7 ]; 

    Data.samples = [ normallyDistributedSample(sampleAsize, sampleAmean, sampleAstdDev); ... 
         normallyDistributedSample(sampleBsize, sampleBmean, sampleBstdDev) ]; 

    Data.labels = [ ones(sampleAsize,1); ... 
         -ones(sampleBsize,1) ]; 

    % --------------------------------------------------------------------- 
    % Randomly permute samples & class labels. 
    % 
    % This is not really necessary, but done to illustrate that the order 
    % in which observations are evaluated does not matter. 
    % 

    randomOrder = randperm(sampleAsize + sampleBsize); 
    Data.samples = Data.samples(randomOrder, :); 
    Data.labels = Data.labels( randomOrder, :); 

end % CREATETRAININGDATA 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
function samples = normallyDistributedSample(sampleSize, sampleMean, sampleStdDev) 
%NORMALDISTRIBUTIONSAMPLE 
% 
% Draw a sample from a normal distribution with specified mean and 
% standard deviation. 
% 

    assert( isequal(size(sampleMean), size(sampleStdDev)) ... 
      && 1 == size(sampleMean, 1),       ... 
     'Sample mean and standard deviation must be row vectors of equal length.'); 

    numFeatures = numel(sampleMean); 
    samples  = randn(sampleSize, numFeatures); 
    samples  = bsxfun(@times, samples, sampleStdDev); 
    samples  = bsxfun(@plus, samples, sampleMean ); 

end % NORMALDISTRIBUTIONSAMPLE 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
function displayPerceptronState(Data, Model) 
%DISPLAYPERCEPTRONSTATE 

    hFig = figure(1); 
    clf; 
    set(hFig,      ... 
     'NumberTitle', 'off',   ... 
     'Name',   mfilename, ... 
     'MenuBar',  'none',  ... 
     'Color',  [1.0 1.0 1.0]); 

    displayXmin = -4; 
    displayXmax = 4; 
    displayYmin = -4; 
    displayYmax = 4; 

    hAx = subplot(1, 1, 1); 
    axis('equal'); 
    set(hAx,         ... 
     'Box',  'on',      ... 
     'NextPlot', 'add',      ... 
     'xgrid', 'on',      ... 
     'ygrid', 'on',      ... 
     'xlim',  [displayXmin displayXmax], ... % Bounds suitable for Z-scored data 
     'ylim',  [displayYmin displayYmax] ); 
    xlabel('x_1'); 
    ylabel('x_2'); 

    % --------------------------------------------------------------------- 
    % Plot data points from the two classes 
    % 

    isPositiveClass = Data.labels > 0; 
    isNegativeClass = Data.labels <= 0; 

    plot(hAx, Data.samples(isPositiveClass,1), Data.samples(isPositiveClass,2), 'b+'); 
    plot(hAx, Data.samples(isNegativeClass,1), Data.samples(isNegativeClass,2), 'rx'); 

    % --------------------------------------------------------------------- 
    % Display parameters for separating hyperplane in title 
    % 

    xWeight = Model.weights(1); 
    yWeight = Model.weights(2); 
    bias  = Model.bias; 

    szTitle = sprintf('Linear classifier parameters: %0.2f x_1 + %0.2f x_2 + %0.2f = 0', xWeight, yWeight, bias); 
    title(szTitle); 

    % --------------------------------------------------------------------- 
    % Plot separating hyperplane 
    % 

    y1 = ((xWeight*displayXmin) + bias) ./ -yWeight; 
    y2 = ((xWeight*displayXmax) + bias) ./ -yWeight; 

    plot(hAx, [displayXmin; displayXmax], [y1, y2], 'k-', 'linewidth', 2); 

    pause(0.1); 

end % DISPLAYPERCEPTRONSTATE 
Problemi correlati