from __future__ import division # import numpy as np import math def activeFunc(value): '''Setzt den Wert in die Sigmoid-Funktion ein.''' # print "input:", value return 1/(1+math.e**(-value)) def derivedActFunc(value): return (math.e**-value)/(1+math.e**-value)**2 class Neuron(): def __init__(self, weights): self.weights = weights self.additionalInput = 0 self.inputs = 0 self.value = 0 self.isActive = False # print "Weights:", self.weights, "(" + str(len(self.weights)) + ")" def processInput(self, inputs): '''Verarbeitet den Input, indem es jeden Wert mit seinem Gewicht multipliziert und das Ergebnis in die Sigmoid-Funktion einsetzt.''' value = self.additionalInput self.inputs = inputs for i in range(len(inputs)): value += self.weights[i]*inputs[i] self.value = value self.output = activeFunc(value) self.isActive = self.output >= 0.5 def setWeights(self, weights): self.weights = weights def printNeuron(self): return 'N:' + str(len(self.weights)), self.weights
# -*-coding:utf8-*- from __future__ import division import neuron as nr import random import math import readfile as rf def sProduct(list1, list2, prit=False): '''Berechnet das SkalarProdukt zweier Vektoren''' value = 0 for i in range(len(list1)): if prit: print list1[i] print list2[i] value += list1[i]*list2[i] return value class Network(): def __init__(self, neuronNum): '''Generiert ein neues Netzwerk jeweils neuronNum verschiedenen Neuronen in layers Layern und inputNum Gewichten pro Neuron.''' self.layers = [] # Neues Layer anlegen for layer in range(len(neuronNum)-1): # So viele Neuronen anlegen, wie das Layer Outputs hat neurons = [] for i in range(neuronNum[layer+1]): weights = [] # Fuer jedes Neuron so viele Gewichte anlegen, # wie das Layer Inputs hat for j in range(neuronNum[layer]): weights.append(random.uniform(-0.03, 0.03)) neurons.append(nr.Neuron(weights)) self.layers.append(neurons) self.learningRate = 0.015 self.softmax = 1 self.decay = 0.05 # for layer in range(len(self.layers)): # print "Layer:", layer, [neuron.printNeuron() # for neuron in self.layers[layer]] def getOutput(self, inputs): '''Testet das Netzwerk auf einen Input-Vektor und den korrekten Output''' end_output = [] for layer in self.layers: output = [] for nrn in layer: nrn.processInput(inputs) output.append(nrn.output) end_output.append(nrn.value) inputs = output[:] # self.softmax = sum([math.e**value for value in end_output]) return inputs def compareOutputs(self, output, expOutput): '''Berechnet den quadratischen Fehler zwischen erwartetem und tatsaechlichem Output''' error = 0 for i in range(output): error += (output[i]-expOutput[i])**2 return 0.5*error def update(self, inputs, expOutput): output = self.getOutput(inputs) newWeightsList = [] deltas = [] # zunächst werden die Deltas berechnet for i in range(len(self.layers[-1])): deltas.append((output[i] - expOutput[i]) * nr.derivedActFunc(self.layers[-1][i].value)) for layer in range(len(self.layers)): # print "Layer", len(self.layers)-layer-1, "of", len(self.layers) newWeights = [] for n in range(len(self.layers[-(layer+1)])): # print "Neuron", n, "of", len(self.layers[-layer-1]) newNeuronWeights = [] for w in range(len(self.layers[-(layer+1)][n].weights)): weight = self.layers[-(layer+1)][n].weights[w] newNeuronWeights.append(weight*(1-self.decay) - self.learningRate * deltas[n]*self.layers[-(layer+1)][n].inputs[w]) newWeights.append(newNeuronWeights) newWeightsList.append(newWeights) # deltas update newdeltas = [] for l in range(len(self.layers[-(layer+1)][0].weights)): value = 0 # print -(layer+2) if -(layer+1) == -len(self.layers): value = inputs[l] else: value = self.layers[-(layer+2)][l].value newdeltas.append(sum([deltas[k]*self.layers[-(layer+1)][k].weights[l] for k in range(len(deltas))])*nr.derivedActFunc(value)) deltas = newdeltas for layer in range(len(self.layers)): for n in range(len(self.layers[layer])): self.layers[layer][n].setWeights(newWeightsList[-layer-1][n]) def updateDataset(self, dataset): '''Trainiert das Neuronale Netz anhand einer Liste von Inputs und erwarteten Outputs''' for data in range(len(dataset)): # print data+1, "/", len(dataset) self.update(dataset[data][0], dataset[data][1]) def testDataset(self, dataset): correctAnswers = 0 for data in dataset: res = self.getOutput(data[0]) # print res # print res, data[1] maxvalue = 0 for i in range(len(res)): if (res[i] > res[maxvalue]): maxvalue = i if (data[1][maxvalue] == 1): correctAnswers += 1 print " " * maxvalue, maxvalue # print maxvalue, [round(num, 5) for num in res] # else: # print data[1], [round(num, 5) for num in res] print correctAnswers / len(dataset) return correctAnswers / len(dataset) if __name__ == "__main__": n = Network([256, 12, 10]) traindata = rf.readFile("zip.train") testdata = rf.readFile("zip.test") value = n.testDataset(testdata) n.updateDataset(traindata) newvalue = n.testDataset(testdata) while newvalue - value > 10**-4: value = newvalue n.updateDataset(traindata) newvalue = n.testDataset(testdata)
import numpy as np import matplotlib.pyplot as plt def readFile(filename, skip=257): file = open(filename, 'r') all = file.read() numbers = [float(num) for num in all.split()] data = [] for i in range(len(numbers)//skip): number = numbers[i*skip:(i+1)*skip] # print number im = [1+num for num in number][1:] data.append((im, [0]*int(number[0])+[1]+[0]*(9-int(number[0])))) return data def convertToMatrix(data, x=16, y=16): arr = np.reshape(np.array(data), (x, y)) return arr def showData(data): for dat in data: print (dat[1]) plt.imshow(convertToMatrix(dat[0]), cmap="Greys") plt.show()