2011-02-03 16 views
8

Estoy revisando un código de Toronto perceptron MATLAB codeImplementación y ploting un perceptrón en MATLAB

El código es

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 

Así que estaba leyendo cómo aplicar esta función a los datos de la matriz X, Y y el objetivo, pero, no sé cómo usar esta función, entiendo, devuelve un vector de pesos, por lo que puede clasificar.

¿Podría dar un ejemplo y explicarlo?

He tratado

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);  

Gracias

Gracias por los anwers, tengo uno más, Si cambio de la Y = [0, 1], lo que ocurre con el algoritmo ?.

Por lo tanto, cualquier dato de entrada no funcionarán con Y = [0,1] con este código de la perceptrón derecho ?,

-------------- --------------- EDITAR ------------------------

Una pregunta más, si Quiero trazar la línea que divide las 2 clases, sé que podemos conseguir que la línea de la resolución de sistemas de ecuaciones lineales que tiene que ver con los pesos, sino cómo, ¿qué podía hacer ?, estoy intentando algo así como

% 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??? 

Respuesta

17

primero debe entender lo que es el significado de cada una de las entradas:

  • X es la matriz de entrada de ejemplos, de tamaño M x N, donde M es la dimensión del vector de características, y N es el número de muestras. Dado que el modelo perceptrón para la predicción es Y=w*X+b, usted tiene que suministrar una dimensión extra en X que es constante, por lo general se establece en 1, por lo que el término b es "integrado" en X. En el ejemplo siguiente para X, establecí la última entrada de X en 1 en todas las muestras.
  • Y es la clasificación correcta para cada muestra de X (la clasificación que desea que aprenda el perceptrón), por lo que debe ser un vector de fila N dimensiones, una salida para cada ejemplo de entrada. Dado que el perceptron es un clasificador binario binario, debe tener solo 2 valores posibles distintos. Al observar el código, verá que comprueba el signo de la predicción, que le indica que los valores permitidos de Y deben ser -1,+1 (y no 0,1 por ejemplo).
  • w es el vector de peso que está tratando de aprender.

tanto, tratar de llamar a la función con:

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

EDITAR

Utilice el siguiente código para llamar la ALG perceptrón y ver los resultados de forma gráfica:

% 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

¡¡¡Buena respuesta !! – qdjm

+1

Muchas gracias, realmente entiendo tu ejemplo, pero tengo una pregunta más: ¿Qué harías si la clase 1 tuviera más ejemplos que la clase 0? en el ejemplo que proporcionó hay el mismo número de ejemplos para ambas clases, X1 y X2 – cMinor

+0

¿Es correcto, no puedo probarlo ahora mismo? X1 = [rand (1,100); rand (1,100); unos (1,100)]; % clase '+1' X2 = [rand (1300); 1 + rand (1300); unos (1300)]; % clase '-1' X = [X1, X2]; % clase de salida [-1, + 1]; Y = [- unos (1,100), unos (1,300)]; % init vector de peso w = [.5 .5 .5] '; wtag = perceptron (X, Y, w); – cMinor

1

Prueba esto:

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

Su ejemplo no funcionará, ya que el algoritmo asume valores de salida de [-1, + 1], no [0,1]. El vector 'w' no se actualizará en absoluto. –

+3

Además, la entrada debe ser al menos de la dimensión 2, de lo contrario, usted explícitamente asume que 'b = 0' en' y = a * x + b' –

10

Si te interesa, aquí hay una pequeña demostración de perceptron escrita de manera bastante 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 
Cuestiones relacionadas