0
\$\begingroup\$

I wrote a 2-layer neural net with just Python & NumPy to implement the XOR Gate, here is the code

import time
start_time = time.time()

import numpy as np

def sigmoid(z):
    return 1 / (1 + np.exp(-z))

class MLPClassifier:
    def __init__(self, eta=.05, n_epoch=10, n_0=2, n_1=2, n_2=1,
          model_w1=[], model_b1=[], model_w2=[], model_b2=[]):
        self.eta = eta
        self.n_epoch = n_epoch
        self.model_w1 = model_w1
        self.model_b1 = model_b1
        self.model_w2 = model_w2
        self.model_b2 = model_b2
        self.n_1 = n_1
        self.n_2 = n_2
        
    def initialize_params(self, n_0, n_1, n_2):
        if len(self.model_w1) == 0:
            self.model_w1 = np.full((n_0, n_1), .5)
        if len(self.model_w2) == 0:
            self.model_w2 = np.random.uniform(size=(n_1, n_2))
        if len(self.model_b1) == 0:
            self.model_b1 = np.random.uniform(size=(1, n_1))
        if len(self.model_b2) == 0:
            self.model_b2 = np.random.uniform(size=(1, n_2))
        
    def predict(self, x):
        _, a2 = self.forward_propagation(x)
        yhat = a2 >= 0.5
        return 1*yhat

    def forward_propagation(self, x):
        z1 = np.dot(x, self.model_w1) + self.model_b1
        a1 = sigmoid(z1)
        z2 = np.dot(a1, self.model_w2) + self.model_b2
        a2 = sigmoid(z2)
        return a1, a2
    
    def backward_propagation(self, x, y, a1, a2):
        m = len(x)
        n_1 = self.n_1
        n_2 = self.n_2
        a1 = a1.reshape(m, -1)
        dz2 = a2 - y
        dw2 = np.dot(a1.T, dz2)/m
        dw2 = dw2.reshape(n_1, n_2)
        db2 = np.mean(dz2, keepdims = True)
        dz1 = np.dot(dz2, self.model_w2.T) * (a1*(1-a1))
        dw1 = np.dot(x.T, dz1)/m
        db1 = np.mean(dz1, axis=0)
        return dw2, db2, dw1, db1

    def update_params(self, dw2, db2, dw1, db1):
        self.model_w2 -= self.eta * dw2
        self.model_b2 -= self.eta * db2
        self.model_w1 -= self.eta * dw1
        self.model_b1 -= self.eta * db1

    def fit(self, x, y, verbose=False):
        n_0 = x.shape[-1]
        n_1 = self.n_1
        n_2 = self.n_2
        self.initialize_params(n_0, n_1, n_2)        
        for i in range(self.n_epoch):
            a1, a2 = self.forward_propagation(x)
            dw2, db2, dw1, db1 = self.backward_propagation(x, y, a1, a2)
            self.update_params(dw2, db2, dw1, db1)

x_train = np.array([[0,0],[0,1],[1,0],[1,1]])
y_train = np.array([0,1,1,0]).reshape(4,1)

print('preparation took {:.5f} s'.format(time.time() - start_time))

classifier = MLPClassifier(.1, 10000)
classifier.fit(x_train, y_train, verbose=True)

print('training took {:.5f} s'.format(time.time() - start_time))

acc = np.count_nonzero(np.squeeze(classifier.predict(x_train)) == np.squeeze(y_train))
print('train accuracy {:.5f}'.format(acc/len(y_train)))

print(*classifier.predict(x_train))
print('the whole app took {:.5f} s'.format(time.time() - start_time))

The code works as expected.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.