Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
ss15:nncode [2015/07/24 22:13] mr.lazy |
ss15:nncode [2016/05/10 14:46] (aktuell) |
||
---|---|---|---|
Zeile 41: | Zeile 41: | ||
def printNeuron(self): | def printNeuron(self): | ||
return 'N:' + str(len(self.weights)), self.weights | return 'N:' + str(len(self.weights)), self.weights | ||
+ | |||
+ | </code> | ||
+ | =====network===== | ||
+ | <code python> | ||
+ | # -*-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) | ||
+ | |||
+ | </code> | ||
+ | =====readfile===== | ||
+ | <code python> | ||
+ | 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() | ||
</code> | </code> |