-
Notifications
You must be signed in to change notification settings - Fork 0
/
layer.py
92 lines (70 loc) · 2.84 KB
/
layer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import random
import numpy
import math
def logistic(value):
return 1 / (1 + math.exp(value * (-1)))
def countHiddenLayerErrors(nextLayer, size):
sigmas = nextLayer.sigmas
weights = numpy.transpose(nextLayer.weights)
errors = numpy.dot(weights, sigmas)
return errors
def generateWeights(layerSize, prevLayerSize):
weights = []
for i in range(layerSize):
unitWeights = []
for k in range(prevLayerSize):
unitWeight = random.uniform(-1, 1)
unitWeights.append(unitWeight)
weights.append(unitWeights)
return numpy.array(weights)
class InputLayer():
def __init__(self, layerSize):
self.nextLayer = None
self.prevLayer = None
self.activationType = 'logistic'
self.activation = logistic
self.size = layerSize
def activate(self, inputs):
self.outputs = [self.activation(val) for val in inputs]
return self.nextLayer.activate(self.outputs)
def add(self, layer):
self.nextLayer = layer
class Layer():
def __init__(self, layerSize, prevLayer):
self.nextLayer = None
self.prevLayer = prevLayer
self.activationType = 'logistic'
self.activation = logistic
self.size = layerSize
self.weights = generateWeights(layerSize, prevLayer.size)
def activate(self, inputs):
inputsCol = numpy.transpose([inputs])
self.inputs = [inputs]
dot = numpy.dot(self.weights, inputsCol)
self.outputs = [self.activation(row[0]) for row in dot]
if self.nextLayer: return self.nextLayer.activate(self.outputs)
else: return self.outputs
def add(self, layer):
self.nextLayer = layer
def setWeights(self, weights):
self.weights = numpy.array(weights)
def updateWeights(self, requiredOutput, coef):
if not self.nextLayer:
requiredOutput = numpy.transpose([requiredOutput])
errors = requiredOutput - numpy.transpose([self.outputs])
constants = [val * (1 - val) for val in self.outputs]
dot = numpy.dot(errors, [constants])
diagonal = [numpy.diagonal(dot)]
self.sigmas = numpy.transpose(diagonal)
self.weights = self.weights + numpy.dot(self.sigmas, self.inputs) * coef
if self.prevLayer.prevLayer:
self.prevLayer.updateWeights(None, coef)
else:
errors = countHiddenLayerErrors(self.nextLayer, self.size)
constants = [val * (1 - val) for val in self.outputs]
dot = numpy.dot(errors, [constants])
diagonal = [numpy.diagonal(dot)]
self.sigmas = numpy.transpose(diagonal)
self.weights = self.weights + numpy.dot(self.sigmas, self.inputs) * coef
if self.prevLayer.prevLayer:
self.prevLayer.updateWeights(None, coef)