2

I built a numpy only neural network originally based on an online tutorial and have come to realise that I should have some kind of bias neuron. However I have really been struggling to figure out how to implement it into my code and would greatly appreciate some guidance.

import numpy as np

class NN():   
    def __init__(self, layers, type):
        """
        layers: a list of layers, eg:
              2 input neurons
              1 hidden layer of 3 neurons
              2 output neurons
              will look like [2,3,2]
        type: initialisation type, "random" or "uniform" distribution
        """

        self.p = 0.1

        self.layers = len(layers) - 1

        self.inputSize = layers[0]
        self.outputSize = layers[self.layers]

        self.layerSizes = layers[:-1] #input layer, hiddens, discard output layer

        self.inputs = np.zeros(self.inputSize, dtype=float)
        self.outputs = np.zeros(self.outputSize, dtype=float)

        self.L = {}

        if type == "random":
            for i in range(1,self.layers+1):
                if i < self.layers:
                    self.L[i] = (np.random.ranf(( self.layerSizes[i-1] , self.layerSizes[i] )).astype(np.float) - 0.5) * 2
                else:
                    self.L[i] = (np.random.ranf(( self.layerSizes[i-1] , self.outputSize )).astype(np.float) - 0.5)*2
        elif type == "uniform":            
            for i in range(1,self.layers+1):
                if i < self.layers:
                    self.L[i] = np.random.uniform( -1 , 1 , (self.layerSizes[i-1],self.layerSizes[i]) )
                else:
                    self.L[i] = np.random.uniform( -1 , 1 , (self.layerSizes[i-1],self.outputSize) )

        else:
            print("unknown initialization type")

    def updateS(self): #forward propogation Sigmoid
        for i in range(1,self.layers+1):
            if 1 == self.layers:  #dodgy no hidden layers fix
                self.z = np.dot(self.inputs, self.L[i])
                self.outputs = ( self.sigmoid(self.z) - 0.5)*2           
            elif i == 1:  #input layer
                self.z = np.dot(self.inputs, self.L[i])
                self.temp = self.sigmoid(self.z)
            elif i < self.layers: #hidden layers
                self.z = np.dot(self.temp, self.L[i])
                self.temp = self.sigmoid(self.z)
            else: #output layer
                self.z = np.dot(self.temp, self.L[i])
                self.outputs = ( self.sigmoid(self.z) - 0.5)*2

    def sigmoid(self, s):
        #activation funtion
        return 1/(1+np.exp(-s/self.p))
  • , please read the help for SO here: stackoverflow.com/help/dont-ask。 You have made no attempt to explain what you have tried, show input/output, explain what went wrong and ask a specific question for what you want help on. Could you please edit your question with that information, and then people will be able to help you. – Richard Nov 22 '19 at 18:27

1 Answers1

0

Bias is just a variable you add to each neuron as you progress through the neural network feed forward process. Thus the feed forward process from one neuron layer to the next will be the sum of all the weights multiplied by the previous neuron that feed into the next neuron, then the bias of that neuron will be added, or:

output = sum(weights * inputs) + bias

To put this into context, look at the picture below:

Neural network example picture

where:

X1: Input value 1.
X2: Input value 2.
B1n: Layer 1, neuron n bias.
H1: Hidden layer neuron 1.
H2: Hidden layer neuron 2.
a(…): activation function.
B2n: Layer 2, neuron n bias.
Y1: network output neuron 1.
Y2: network output neuron 2.
Y1out: network output 1.
Y2out: network output 2.
T1: Training output 1.
T2: Training output 2.

when working out H1, you would need to use the following formula:

H1 = (X1 * W1) + (X2 * W2) + B11    

Note that is is before the value for the neuron has been completely calculated via the activation function.

Therefore, im pretty sure that the bias would be entered within the feed forward function:

def updateS(self): #forward propogation Sigmoid
        for i in range(1,self.layers+1):
            if 1 == self.layers:  #dodgy no hidden layers fix
                self.z = np.dot(self.inputs, self.L[i])
                self.outputs = ( self.sigmoid(self.z) - 0.5)*2           
            elif i == 1:  #input layer
                self.z = np.dot(self.inputs, self.L[i])
                self.temp = self.sigmoid(self.z)
            elif i < self.layers: #hidden layers
                self.z = np.dot(self.temp, self.L[i])
                self.temp = self.sigmoid(self.z)
            else: #output layer
                self.z = np.dot(self.temp, self.L[i])
                self.outputs = ( self.sigmoid(self.z) - 0.5)*2

by adding a value to the end of the self.z values. I think these values can be anything you want as a bias simply moves the intercept of the linear equation

Dave
  • 3,073
  • 7
  • 20
  • 33
Boc Dev
  • 313
  • 2
  • 8
  • Thanks for the help. I made a single bias weight per layer which gets multiplied by the bias value. I then add that at the end of the self.z line as suggested. Does that sound correct? – Ethicalfive Dec 02 '19 at 15:52
  • Ye sounds about right. I have a little java project investigating neural networks which might shed some light on GitHub if you want to look through it: https://github.com/Qualia91/NeuralNetwork – Boc Dev Dec 03 '19 at 17:00