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
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
dim 1 x dim 2
dim 1 x dim3
dim 2 x dim 3
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.