Monday, February 7, 2022

Linear vs nonlinear neural network

Code 1 

(.env) [boris@fedora34server NUMPY]$ python NonLinear.py

input: [0 0] - output: [0.]

input: [0 1] - output: [1.]

input: [1 0] - output: [1.]

input: [1 1] - output: [-0.]

(.env) [boris@fedora34server NUMPY]$ cat NonLinear.py

import numpy as np


#Data

data = np.array([[0, 0, 0],[0, 1, 1],[1, 0, 1],[1, 1, 0]])

np.random.shuffle(data)

train_data = data[:,:2]

target_data = data[:,2]


#XOR architecture

class XOR_class():


    def __init__(self, train_data, target_data, alpha=.1, epochs=10000):

        self.train_data = train_data

        self.target_data = target_data

        self.alpha = alpha

        self.epochs = epochs

        

        #Random weights

        self.W0 = np.random.uniform(low=-1, high=1, size=(2)).T

        self.b0 = np.random.uniform(low=-1, high=1, size=(1))

        self.W2 = np.random.uniform(low=-1, high=1, size=(2)).T

        self.b2 = np.random.uniform(low=-1, high=1, size=(1))


    #xor network (linear transfer functions only)

    def xor_network(self, X0):

        n0 = np.dot(X0, self.W0) + self.b0

        X1 = n0*X0

        a = np.dot(X1, self.W2) + self.b2

        return(a, X1)


    #Training the xor network

    def train(self):

        for epoch in range(self.epochs):

            for i in range(len(self.train_data)):

                # Forward Propagation:

                X0 = self.train_data[i]

                a, X1 = self.xor_network(X0)

        

                # Backward Propagation:

                e = self.target_data[i] - a

                s_2 = -2*e

        

                # Update Weights:

                self.W0 = self.W0 - (self.alpha*s_2*X0)

                self.b0 = self.b0 - (self.alpha*s_2)

                self.W2 = self.W2 - (self.alpha*s_2*X1)

                self.b2 = self.b2 - (self.alpha*s_2)

        

        #Restart training if we get lost in the parameter space.

        if np.isnan(a) or (a > 1) or (a < -1):

            print('Bad initialization, reinitializing.')

            self.W0 = np.random.uniform(low=-1, high=1, size=(2)).T

            self.b0 = np.random.uniform(low=-1, high=1, size=(1))

            self.W2 = np.random.uniform(low=-1, high=1, size=(2)).T

            self.b2 = np.random.uniform(low=-1, high=1, size=(1))

            self.train()

    

    #Predicting using the trained weights.

    def predict(self, test_data):

        for i in train_data:

            a, X1 = self.xor_network(i)

            #I cut off decimals past 12 for convienience, not necessary.

            print(f'input: {i} - output: {np.round(a, 12)}')


# Execution

xor = XOR_class(train_data, target_data)

xor.train()

np.random.shuffle(data)

test_data = data[:,:2]

xor.predict(test_data)































References







No comments:

Post a Comment