matlabneural-networkperceptron

Code for 3 class classifier single layer perceptron in MATLAB


For identifying 3 classes, I have taken 3 single layer perceptron such that,

If data belongs to class 1, then perceptron1=1, perceptron2=0,perceptron3=0

If data belongs to class 2, then perceptron1=0, perceptron2=1,perceptron3=0

If data belongs to class 3, then perceptron1=0, perceptron2=0,perceptron3=1

I did write the code, now strangely I can see that the perceptron for identifying class 1 and class 3 r working just fine but not class 2. Now I could not find where the mistake is. So can you please help me??

code for main program:



clc;
% INPUT
% amount of values
points = 300;
% stepsize
s = 1.0;
% INITIALIZE
% Booleans
TRUE  = 1;
FALSE = 0;
feature = 3;
% generate data
%D = generateRandomData(points);

%keeps tracks for hits for each classes in each iteration
p1=0;
p2=0;
p3=0;
ax = 10;
bx = 70;
d=zeros(3,points);
xx1 = 2 + 1.*randn(points/3,1);
xx2 = 10 + 1.*randn(points/3,1);
xx3 = 20 + 1.*randn(points/3,1);
D=(bx-ax).*rand(points,feature) + ax;
for k = 1:points/3
   D(k,1) = xx1(k);
   D(k+points/3,1) = xx2(k);
   D(k+2*points/3,1) = xx3(k);
end
D =  D(randperm(end),:);

for n = drange(1:points)
if D(n,1) <=5.0000   
  d(1,n)=1;
  d(2,n)=0;
  d(3,n)=0;

elseif D(n,1) >=7.0000 && D(n,1) <= 13.0000
d(1,n)=0;
d(2,n)=1;
d(3,n)=0;

elseif D(n,1) >= 17.0000   
  d(1,n)=0;
  d(2,n)=0;
  d(3,n)=1;
end
end

% x-values
% training set
%d = D(:,feature+1);
% weights
w1 = zeros(feature+1,1);
w2 = zeros(feature+1,1);
w3 = zeros(feature+1,1);
% bias
b  = 1;
% sucsess flag
isCorrect = FALSE;
% correctly predicted values counter
p = 0;
% COMPUTE 

% while at east one point is not correctly classified
while isCorrect == FALSE
% for every point in the dataset


for i=1 : points
    % calculate outcome with current weight

    %CLASS 1
    sumx=0;sum1=0;
    for n =1 : feature
    sumx=D(i,n) * w1(n+1);
    sum1=sum1+sumx;
    end
    bias1=b*w1(1);
    m1=bias1+sum1;
    c1 = activate( m1 );
    a1 = errorFunction(c1,d(1,i)); 
    if a1 ~= 0
        % ajust weights
        for n1 = 1 : feature
            h=n1+1;
        w1(h) = w1(h)+a1*s*D(i,n1);
        end
        w1(1)=w1(1)+a1*s*b;
        else
        % increase correctness counter
        p1 = p1 + 1;
    end


    %CLASS 2
    sumy=0;sum2=0;
    for n =1 : feature
    sumy=D(i,n) * w2(n+1);
    sum2=sumy+sum2;
    end
    bias2=b*w2(1);
    m2=bias2+sum2;
    c2 = activate( m2 );
    disp('-------------');
    disp(c2);
    disp(d(2,i));
    disp('-------------');
    a2 = errorFunction(c2,d(2,i)); 
    if a2 ~= 0
        % ajust weights
        for n1 = 1 : feature
            h=n1+1;
        w2(h) = w2(h)+a2*s*D(i,n1);
        end
        w2(1)=w2(1)+a2*s*b;
        else
        % increase correctness counter
        p2 = p2 + 1;

    end


    %CLASS 3
    sumz=0;sum3=0;
    for n =1 : feature
    sumz=D(i,n) * w3(n+1);
    sum3=sumz+sum3;
    end
    bias3=b*w3(1);
    m3=bias3+sum3;
    c3 = activate( m3 );
    a3 = errorFunction(c3,d(3,i)); 
    if a3 ~= 0
        % ajust weights
        for n1 = 1 : feature
            h=n1+1;
        w3(h) = w3(h)+a3*s*D(i,n1);
        end
        w3(1)=w3(1)+a3*s*b;
    else
        % increase correctness counter
        p3 = p3 + 1;
    end

end
 %  p/3 >= points/1.4 
 %p2 == p1 && p1 == p
if (p1+p2+p3)/2>=points
    %disp(p);
   isCorrect = TRUE;
else
    %p33=p22;
    %p22=p11;
    %p11=p;
    %p=0;
    p1=0;
    p2=0;
    p3=0;
end

end
disp(p1);
disp(p2);
disp(p3);

test=15;
ax = 10;
bx = 70;
D1=(bx-ax).*rand(test,feature) + ax;

xy1 = 2 + 1.*randn(test/3,1);
xy2 = 10 + 1.*randn(test/3,1);
xy3 = 20 + 1.*randn(test/3,1);

for k = 1:test/3
D1(k,1) = xy1(k);
D1(k+test/3,1) = xy2(k);
D1(k+2*test/3,1) = xy3(k);
end
D1 =  D1(randperm(end),:);

test1=zeros(3,test);

for n = drange(1:test)
if D1(n,1) <= 5.0000   
  test1(1,n)=1;
  test1(2,n)=0;
  test1(3,n)=0;
end
if D1(n,1) >=7.0000 && D1(n,1) <= 13.0000
  test1(1,n)=0;
  test1(2,n)=1;
  test1(3,n)=0;
end
if D1(n,1) >= 17.0000   
  test1(1,n)=0;
  test1(2,n)=0;
  test1(3,n)=1;
end
end

for i=1 : test

  sumx=0;sum1=0;sum2=0;sum3=0;
    for n =1 : feature
    sumx=D1(i,n) * w1(n+1);
    sum1=sumx+sum1;
    end
    bias=b*w1(1);
    m=bias+sum1;
    c = activate( m );
    a1 = errorFunction(c,test1(1,i)); 


    %CLASS 2
    for n =1 : feature
    sumx=D1(i,n) * w2(n+1);
    sum2=sumx+sum2;
    end
    bias=b*w2(1);
    m=bias+sum2;
    c = activate( m );
    a2 = errorFunction(c,test1(2,i)); 

    %CLASS 3
    for n =1 : feature
    sumx=D1(i,n) * w3(n+1);
    sum3=sumx+sum3;
    end
    bias=b*w3(1);
    m=bias+sum3;
    c = activate( m );
    a3 = errorFunction(c,test1(3,i)); 

    % if outcome was wrong
    if a1 == 0.0 && a2 == 0.0 && a3 == 0.0
        disp('correct');
   else disp('incorrect');
    end
end





code for activation function

function f = activate(x)
f = (1/2)*(sign(x)+1);
%f = 1 / (1 + exp(-x));
%f = tanh(x);
end



code for error function checking

function f = errorFunction(c,d)
% w has been classified as c - w should be d

if c < d 
 %reaction too small 
f = +1;
elseif c > d
 %reaction too large
f = -1;
else
 %reaction correct
f = 0.0;
end

end


Solution

  • A quick look at the code seems fine overall, but it seems that the data is not suitable for perceptron training.

    It seems that the data generated for training is not linearly separable, which is evident from the 3d plot and the other 2d plots for each of the dimensions. Specifically the data is not linearly separable on the dimensions 2 and 3.

    3d plot

    3D plot of dataset for one run

    dim 1 x dim 2

    d1 x d2 plot

    dim 1 x dim3

    d1 x d3 plot

    dim 2 x dim 3

    d2 x d3 plot

    The generated data is not linearly separable along the dimension 2 and 3, and therefore the perceptron units will never converge. Therefore the way the training is done it definitely will give poor accuracy.

    I will recommend to use the Pocket algorithm in this case, which is the closest to the present algorithm, possibly multi-layer perceptron, logistic unit or a neural network would be appropriate. Although the dim 2 and dim 3 plot seems that it is pretty hard to classify them. Possibly trying the currently implemented code on a clearly linearly separable dataset would work.

    Another recommendation is to write functions for the training and the prediction steps, makes it easier to maintain and read.