Perceptron training in Matlab

4.4k views Asked by At

I am trying to create a simple perceptron training function in MATLAB. I want to return the weights when no errors are found.

Here is the data I want to classify.

d = rand(10,2);
figure

labels = ones(10,1);
diff =  d(:,1) + d(:,2) - 1;
labels( diff + 1 >= 1) = 2;

pathWidth = 0.05;
labels( abs(diff) < pathWidth) = [];
d(abs(diff) < pathWidth,:) = [];

plot(d(labels == 1,1),d(labels == 1,2),'k.','MarkerSize',10)
plot(d(labels == 2,1),d(labels == 2,2),'r.','MarkerSize',10)

It produces a labelled data set, where the division between the two classes (red, black) are more visible if you increase the number of points for d.

For my perceptron function I pass the data (d) and labels. I have 3 inputs, the x values, y values and bias which is one. Each input has a random weight between 0 and 1 assigned. Note that the dataset d I have named Z in the perceptron function. I did use a sigmoid activation function but that would run once through the while loop and always return true after that, the sigmoid function also gave me values of either inf or 1. Below I am using just a threshold activation but it seems to continually loop and not returning my weights. I think the problem may lie in the if-statement below

if(v >= 0 && labels(i) == 1 || v < 0 && labels(i) == 2)

Perceptron function:

function perceptron(data,labels)

sizea = numel(data(:,1));
weights = rand(sizea,3);

Z = data(:,:)
eta = 0.5;
errors = 1;
count = 0;

while errors > 0 
    errors = 0;
    v = sum((1*weights(1,1)) + (Z(:,1)*weights(1,2)) + (Z(:,2)*weights(1,3)));
    if v >= 1
        v = 1;
    else 
        v = 0;
    end
    count = count + 1
    for i = 1:sizea % for each object in dataset
        if(v == 1 && labels(i) == 1 || v == 0 && labels(i) == 2)
            errors = 1;
            weights(1,1) = weights(1,1) - (2*v-1) * eta * 1;
            weights(1,2) = weights(1,2) - (2*v-1) * eta * Z(i,1);
            weights(1,3) = weights(1,3) - (2*v-1) * eta * Z(i,2);
            v = sum((1*weights(1,1)) + (Z(:,1)*weights(1,2)) + (Z(:,2)*weights(1,3)));
            if v >= 1
                v = 1;
            else 
                v = 0;
            end
        end
    end 
end
1

There are 1 answers

3
lennon310 On

There are two major problems in your code:

  1. You need to update v in your loop every time your weights vectors are updated.
  2. It seems like you have 10 training set. So you have to update v sequentially in the loop instead of simultaneously. Keep iterating for every training set, update weights, then use the new weights to calculate the v for the next training set, so on and so forth, until there is no error (errors = 0 in your case).

Minor issue:

if(v >= 0 && labels(i) == 1 || v < 0 && labels(i) == 2)

should be

if(v == 1 && labels(i) == 1 || v == 0 && labels(i) == 2)

You may refer to this example to get more details of the algorithm.