import math import random import tkinter as tk output_fnpair = 0 function_to_learn = 0 if output_fnpair == 1: # ReLu def logi(x): if x > 0: return x return 0 def dlogi(x): if x > 0: return 1 return 0 elif output_fnpair == 2: # tanh def logi(x): y = math.exp(x) return (y - 1 / y) / (y + 1 / y) def dlogi(x): y = math.exp(x) s = 2 / (y + 1 / y) return s * s elif output_fnpair == 3: # softplus def logi(x): return math.log(1 + math.exp(x)) def dlogi(x): return 1 / (1 + math.exp(- x)) else: # logistic def logi(x): return 1 / (1 + math.exp(- x)) def dlogi(x): y = logi(x) return y * (1 - y) class neuron: def __init__(self, numin): self.num = numin self.wts = [random.random() * 2 - 1 for i in range(0, numin)] self.bias = random.random() * 2 - 1 self.out = 0 self.rate = 0.0005 def compute(self, inps): self.inps = inps self.total = self.bias for i in range(0, self.num): self.total += self.wts[i] * self.inps[i] self.out = logi(self.total) def correct_towards(self, correct, verbose = False): change = self.rate * (correct - self.out) * dlogi(self.total) for i in range(0, self.num): self.wts[i] = self.wts[i] + change * self.inps[i] self.bias = self.bias + change if function_to_learn == 0: interesting = [ 0.666 ] def correct_answers(inps): global interesting return [ 1 if inps[0] > interesting[0] else 0 ] name = "> " + str(interesting[0]) elif function_to_learn == 1: interesting = [ 0.2 ] def correct_answers(inps): global interesting return [ 1 if inps[0] < interesting[0] else 0 ] name = "< " + str(interesting[0]) elif function_to_learn == 2: interesting = [ 0.3, 0.5 ] def correct_answers(inps): global interesting return [ 1 if inps[0] > interesting[0] and inps[0] < interesting[1] else 0 ] name = "between " + str(interesting[0]) + " and " + str(interesting[1]) def test(): global net, name, interesting win = tk.Tk() win.title(name) ca = tk.Canvas(win, width = 500, height = 500, background = "white") ca.pack() for x in interesting: ca.create_line(x * 500, 0, x * 500, 500, width = 2, fill = "black") ca.create_line(0, 250, 500, 250, width = 2, fill = "black") prevx = None prevy = None all = 0 wrong = 0 for v in range(0, 501): ins = [(v + random.random()) / 500] coras = correct_answers(ins) x = v net[0].compute(ins) out = net[0].out ans = 1 if out > 0.5 else 0 y = 500 - out * 500 if prevx != None: colour = "green" if ans == coras[0] else "red" ca.create_line(prevx, prevy, x, y, width = 3, fill = colour) prevx = x prevy = y all += 1 if ans != coras[0]: wrong += 1 print(wrong, "wrong out of", 501) print(net[0].wts, net[0].bias) def random_inputs(): return [random.random()] def start(): global net net = [ neuron(1) ] def step(n): global net, ins totaltotalerror = 0 for j in range(0, n): ins = random_inputs() corrects = correct_answers(ins) totalerror = 0 errors = [] for i in range(0, len(net)): net[i].compute(ins) error = net[i].out - corrects[i] errors.append(error) totalerror += error * error net[i].correct_towards(corrects[i]) totaltotalerror += totalerror print("mean error", totaltotalerror / n) test() start() test()