Skip to main content
6 of 6
deleted 57 characters in body

How to improve my self-written Neural Network?

I created the following Neural Network in Python. It uses weights and biases which should follow standard procedure.

# Define size of the layers, as well as the learning rate alpha and the max error
inputLayerSize = 2
hiddenLayerSize = 3
outputLayerSize = 1
alpha = 0.5
maxError = 0.001

# Import dependencies
import numpy
from sklearn import preprocessing

# Make random numbers predictable
numpy.random.seed(1)

# Define our activation function
# In this case, we use the Sigmoid function
def sigmoid(x):
    output = 1/(1+numpy.exp(-x))
    return output
def sigmoid_derivative(x):
    return x*(1-x)

# Define the cost function
def calculateError(Y, Y_predicted):
    totalError = 0
    for i in range(len(Y)):
        totalError = totalError + numpy.square(Y[i] - Y_predicted[i])
    return totalError

# Set inputs
# Each row is (x1, x2)
X = numpy.array([
            [7, 4.7],
            [6.3, 6],
            [6.9, 4.9],
            [6.4, 5.3],
            [5.8, 5.1],
            [5.5, 4],
            [7.1, 5.9],
            [6.3, 5.6],
            [6.4, 4.5],
            [7.7, 6.7]
            ])

# Normalize the inputs
#X = preprocessing.scale(X)

# Set goals
# Each row is (y1)
Y = numpy.array([
            [0],
            [1],
            [0],
            [1],
            [1],
            [0],
            [0],
            [1],
            [0],
            [1]
            ])

# Randomly initialize our weights with mean 0
weights_1 = 2*numpy.random.random((inputLayerSize, hiddenLayerSize)) - 1
weights_2 = 2*numpy.random.random((hiddenLayerSize, outputLayerSize)) - 1

# Randomly initialize our bias with mean 0
bias_1 = 2*numpy.random.random((hiddenLayerSize)) - 1
bias_2 = 2*numpy.random.random((outputLayerSize)) - 1

# Loop 10,000 times
for i in xrange(100000):

    # Feed forward through layers 0, 1, and 2
    layer_0 = X
    layer_1 = sigmoid(numpy.dot(layer_0, weights_1)+bias_1)
    layer_2 = sigmoid(numpy.dot(layer_1, weights_2)+bias_2)

    # Calculate the cost function
    # How much did we miss the target value?
    layer_2_error = layer_2 - Y
        
    # In what direction is the target value?
    # Were we really sure? if so, don't change too much.
    layer_2_delta = layer_2_error*sigmoid_derivative(layer_2)

    # How much did each layer_1 value contribute to the layer_2 error (according to the weights)?
    layer_1_error = layer_2_delta.dot(weights_2.T)
    
    # In what direction is the target layer_1?
    # Were we really sure? If so, don't change too much.
    layer_1_delta = layer_1_error * sigmoid_derivative(layer_1)
    
    # Update the weights
    weights_2 -= alpha * layer_1.T.dot(layer_2_delta)
    weights_1 -= alpha * layer_0.T.dot(layer_1_delta)
    
    # Update the bias    
    bias_2 -= alpha * numpy.sum(layer_2_delta, axis=0)
    bias_1 -= alpha * numpy.sum(layer_1_delta, axis=0)
    
    # Print the error to show that we are improving
    if (i% 1000) == 0:
        print "Error after "+str(i)+" iterations: " + str(calculateError(Y, layer_2))
        
    # Exit if the error is less than maxError
    if(calculateError(Y, layer_2)<maxError):
        print "Goal reached after "+str(i)+" iterations: " + str(calculateError(Y, layer_2)) + " is smaller than the goal of " + str(maxError)
        break

# Show results
print ""
print "Weights between Input Layer -> Hidden Layer"
print weights_1
print ""

print "Bias of Hidden Layer"
print bias_1
print ""

print "Weights between Hidden Layer -> Output Layer"
print weights_2
print ""

print "Bias of Output Layer"
print bias_2
print ""

print "Computed probabilities for SALE (rounded to 3 decimals)"
print numpy.around(layer_2, decimals=3)
print ""

print "Real probabilities for SALE"
print Y
print ""

print "Final Error"
print str(calculateError(Y, layer_2))

Using 32,000 epochs I manage to get on average a final error of 0.001.

However, compared to the MLPClassifier (Scikit-Learn package) using the same parameters:

mlp = MLPClassifier(
     hidden_layer_sizes=(3,),
     max_iter=32000,
     activation='logistic',
     tol=0.00001,
     verbose='true')

My result is pretty bad. The MLPClassifier gets a final error of 0 when I run it on the same data, after about 10,000 epochs. For both networks I use an input layer size of 2, hidden layer size of 3 and an output layer of 1.

Why does my network need that many more epochs to train? Am I missing an important part?