188 lines
5.3 KiB
Python
Executable File
188 lines
5.3 KiB
Python
Executable File
#!/usr/bin/python
|
|
|
|
from numpy import *
|
|
import sys
|
|
|
|
class ann:
|
|
|
|
def __init__(self, nof_input, nof_hidden, nof_output):
|
|
|
|
# Learning rate
|
|
self.learning_rate = 0.1
|
|
|
|
# Number of neurons in each layer
|
|
self.nof_input = nof_input
|
|
self.nof_hidden = nof_hidden
|
|
self.nof_output = nof_output
|
|
|
|
# Outputs of neurons
|
|
self.input_value = zeros((self.nof_input + 1, 1), dtype=float) # bias
|
|
self.hidden_value = zeros((self.nof_hidden + 1, 1), dtype=float) # bias
|
|
self.output_value = zeros((self.nof_output), dtype=float)
|
|
|
|
# Deltas for hidden and output layers
|
|
self.hidden_delta = zeros((self.nof_hidden), dtype=float)
|
|
self.output_delta = zeros((self.nof_output), dtype=float)
|
|
|
|
# Activation level of neurons (sum of input)
|
|
self.hidden_activation = zeros((self.nof_hidden, 1), dtype=float)
|
|
self.output_activation = zeros((self.nof_output, 1), dtype=float)
|
|
|
|
# Weights in the two links
|
|
self.inner_weights = random.random((self.nof_hidden, self.nof_input + 1))
|
|
self.outer_weights = random.random((self.nof_output, self.nof_hidden + 1))
|
|
|
|
def feed_forward(self, input_list):
|
|
|
|
# Input layer
|
|
self.input_value[:-1, 0] = input_list
|
|
|
|
# Set bias neuron in input layer to 1.0
|
|
self.input_value[-1:, 0] = 1.0
|
|
|
|
# Hidden layer
|
|
self.hidden_activation = dot(self.inner_weights, self.input_value)
|
|
self.hidden_value[:-1, :] = tanh(self.hidden_activation)
|
|
|
|
# Set bias neuron in hidden layer
|
|
self.hidden_value[-1:, :] = 1.0
|
|
|
|
# Output layer
|
|
self.output_activation = dot(self.outer_weights, self.hidden_value)
|
|
self.output_value = tanh(self.output_activation)
|
|
|
|
def back_propagation(self, correct):
|
|
|
|
# Find the error between the output and the actual solution
|
|
error = self.output_value - correct
|
|
|
|
# Delta of the output neurons
|
|
self.output_delta = (1 - self.output_value) * self.output_value * error
|
|
|
|
# Delta of the hidden neurons
|
|
self.hidden_delta = (1 - tanh(self.hidden_activation)) * tanh(self.hidden_activation) * dot(self.outer_weights[:,:-1].transpose(), self.output_delta)
|
|
|
|
# Apply weight changes
|
|
self.inner_weights -= self.learning_rate * dot(self.hidden_delta, self.input_value.transpose())
|
|
self.outer_weights -= self.learning_rate * dot(self.output_delta, self.hidden_value.transpose())
|
|
|
|
def print_ann(self):
|
|
print
|
|
print self.inner_weights
|
|
print self.outer_weights
|
|
|
|
def xor_ann():
|
|
xor_in = [[0,0], [0,1], [1,0], [1,1]]
|
|
xor_out = [[0], [1], [1], [0]]
|
|
xor_ann = ann(2,2,1)
|
|
|
|
cnt = 0
|
|
try:
|
|
while(True):
|
|
sample = random.randint(0,4)
|
|
|
|
xor_ann.feed_forward(xor_in[sample])
|
|
xor_ann.back_propagation(xor_out[sample])
|
|
|
|
result = xor_ann.output_value[0]
|
|
true = 'neutral'
|
|
|
|
print cnt, xor_in[sample], result,
|
|
if result > 0.8:
|
|
print '\033[92mTRUE\033[0m'
|
|
true = 'true'
|
|
elif result < 0.2 and result >= 0:
|
|
print '\033[93mFALSE\033[0m'
|
|
true = 'false'
|
|
else:
|
|
print '\033[91mNO ANSWER\033[0m'
|
|
xor_ann.print_ann()
|
|
cnt += 1
|
|
|
|
except(KeyboardInterrupt, SystemExit):
|
|
xor_ann.print_ann()
|
|
|
|
|
|
def and_ann():
|
|
and_in = [[0,0], [0,1], [1,0], [1,1]]
|
|
and_out = [[0], [0], [0], [1]]
|
|
and_ann = ann(2,1,1)
|
|
|
|
# Weights in the two links
|
|
and_ann.inner_weights = [[1,1,-1.5]]
|
|
and_ann.outer_weights = [[1,-0.5]]
|
|
|
|
print and_ann.inner_weights
|
|
print and_ann.input_value
|
|
|
|
cnt = 0
|
|
try:
|
|
while(True):
|
|
sample = random.randint(0,4)
|
|
|
|
and_ann.feed_forward(and_in[sample])
|
|
|
|
result = and_ann.hidden_value[0]
|
|
true = 'neutral'
|
|
|
|
print cnt, and_in[sample], result,
|
|
if result > 0.1:
|
|
print '\033[92mTRUE\033[0m'
|
|
true = 'true'
|
|
elif result < -0.1:
|
|
print '\033[93mFALSE\033[0m'
|
|
true = 'false'
|
|
else:
|
|
print '\033[91mNO ANSWER\033[0m'
|
|
cnt += 1
|
|
|
|
except(KeyboardInterrupt, SystemExit):
|
|
and_ann.print_ann()
|
|
|
|
|
|
def or_ann():
|
|
or_in = [[0,0], [0,1], [1,0], [1,1]]
|
|
or_out = [[0], [1], [1], [1]]
|
|
or_ann = ann(2,1,1)
|
|
|
|
# Weights in the two links
|
|
or_ann.inner_weights = [[0.5,0.5,-0.3]]
|
|
or_ann.outer_weights = [[1,-0.5]]
|
|
|
|
print or_ann.inner_weights
|
|
print or_ann.input_value
|
|
|
|
cnt = 0
|
|
try:
|
|
while(True):
|
|
sample = random.randint(0,4)
|
|
|
|
or_ann.feed_forward(or_in[sample])
|
|
|
|
result = or_ann.hidden_value[0]
|
|
true = 'neutral'
|
|
|
|
print cnt, or_in[sample], result,
|
|
if result > 0.1:
|
|
print '\033[92mTRUE\033[0m'
|
|
true = 'true'
|
|
elif result < -0.1:
|
|
print '\033[93mFALSE\033[0m'
|
|
true = 'false'
|
|
else:
|
|
print '\033[91mNO ANSWER\033[0m'
|
|
cnt += 1
|
|
|
|
except(KeyboardInterrupt, SystemExit):
|
|
or_ann.print_ann()
|
|
|
|
if len(sys.argv) > 1:
|
|
if sys.argv[1] == 'xor':
|
|
xor_ann()
|
|
elif sys.argv[1] == 'and':
|
|
and_ann()
|
|
elif sys.argv[1] == 'or':
|
|
or_ann()
|
|
|
|
|