Perceptron learning algorithm

ML
Author

Nipun Batra

Published

January 1, 2024

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y_and = np.array([0, 0, 0, 1])
y_or = np.array([0, 1, 1, 1])
y_xor = np.array([0, 1, 1, 0])
class Perceptron(object):
    def __init__(self, lr=0.01, iterations=100):
        self.lr = lr
        self.iterations = iterations
        
    def activation(self, z):
        ac = np.zeros_like(z)
        ac[z>0] = 1
        return ac
    
    def fit(self, X, y):
        X_with_one = np.append(np.ones((len(X), 1)), X, axis=1)
        self.W = np.zeros((X_with_one.shape[1], 1))
        for i in range(self.iterations):
            for j in range(len(X)):
                summation = (X_with_one@self.W).flatten()
                y_hat = self.activation(summation)
                err = y - y_hat.flatten() 
                self.W = self.W + (self.lr*err[j]*X_with_one[j]).reshape(*(self.W.shape))
        
    def predict(self, X):
        X_with_one = np.append(np.ones((len(X), 1)), X, axis=1)
        summation = (X_with_one@self.W).flatten()
        y_hat = self.activation(summation)           
        return y_hat

    
perceptron = Perceptron()
perceptron.fit(X, y_or)
perceptron.W
array([[0.  ],
       [0.01],
       [0.01]])
perceptron.predict(X)
array([0., 1., 1., 1.])
perceptron.fit(X, y_and)
perceptron.W
array([[-0.02],
       [ 0.02],
       [ 0.01]])
perceptron.predict(X)
array([0., 0., 0., 1.])
perceptron.fit(X, y_xor)
perceptron.W
array([[ 0.01],
       [-0.01],
       [ 0.  ]])
perceptron.predict(X)
array([1., 1., 0., 0.])

XOR using feature transformation

# Transformation: 1 
# x1, x2, x1x2
X_xor_1 = np.append(X, (X[:, 0]*X[:, 1]).reshape(-1, 1), axis=1)
perceptron = Perceptron()
perceptron.fit(X_xor_1, y_xor)
perceptron.W
array([[ 0.  ],
       [ 0.01],
       [ 0.01],
       [-0.04]])
np.allclose(perceptron.predict(X_xor_1), y_xor)
True
(X[:, 0]*X[:, 1]).reshape(-1, 1)
array([[0],
       [0],
       [0],
       [1]])
# Transformation: 1 
# x1, x2, x1x2
X_xor_2 = np.array([(1-X[:, 0])*X[:,1], (1-X[:, 1])*X[:,0]]).T
perceptron = Perceptron()
perceptron.fit(X_xor_2, y_xor)
perceptron.W
array([[0.  ],
       [0.01],
       [0.01]])