-
Notifications
You must be signed in to change notification settings - Fork 0
/
MLP.py
173 lines (139 loc) · 6.67 KB
/
MLP.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# -*- coding: utf-8 -*-
"""
Created on Fri Oct 23 16:33:00 2015
@author: Ralf Engelken, Franziska Neu
"""
import numpy as np
"""
Implementiert ein Multi-Layer-Perceptron
"""
class MLP:
"""
Erstellt ein neues MLP mit den übergeben Parametern
"""
def __init__(self, input_size, hidden_size, output_size, learning_rate, adaption_steps = 1000, adaption_rate = 1):
self.version = 2.0
self.input_size = input_size # Die learning-rate steuert die Anpassungsgeschwindigkeit der Gewichts-Matrix
self.hidden_size = hidden_size # Anzahl der Input-Neurone
self.output_size = output_size # Anzahl der Neurone im hidden layer
self.learning_rate = learning_rate # ANzahl der Neurone der output-Schicht
self.adaption_steps = adaption_steps
self.adaption_rate = adaption_rate
self.new_init()
"""
Reinitialisiert die Gewichtungs-Matrizen des MLP
"""
def new_init (self):
mini = -1.0
maxi = 1.0
self.counter = 0
#Zufällige Initialisierung der Gewichtsmatrix der Verbindungen input-hidden
self.W_i = np.random.uniform(mini, maxi, (self.input_size, self.hidden_size))
#Zufällige Initialisierung der Gewichtsmatrix der Verbindungen hidden-output
self.W_o = np.random.uniform(mini, maxi, (self.hidden_size, self.output_size))
# Erstellen vom Bias der Neurone
self.bias_hidden = np.random.uniform(0.0, 0.0, (self.hidden_size))
self.bias_output = np.random.uniform(0.0, 0.0, (self.output_size))
self.new_game()
#self.W_i = np.random.uniform(-0.2, 0.2, (self.input_size, self.hidden_size))
#self.W_o = np.random.uniform(-0.2, 0.2, (self.hidden_size, self.output_size))
#self.bias_hidden = np.random.uniform(-0.2, 0.2, (self.hidden_size))
#self.bias_output = np.random.uniform(-0.2, 0.2, (self.output_size))
def numpy_to_array (self, numpy_array):
if (np.ndim(numpy_array) == 1):
(dim_x,) = np.shape(numpy_array)
array = [0]*dim_x
for x in range(dim_x):
array[x] = numpy_array[x]
elif (np.ndim(numpy_array) == 2):
(dim_y, dim_x) = np.shape(numpy_array)
array = [[0]*dim_x]*dim_y
for x in range(dim_x):
for y in range(dim_y):
array[y][x] = numpy_array[y][x]
return array
def get_data (self):
#print self.numpy_to_array(self.W_i)
data = {"version" : self.version,
"input_size" : self.input_size,
"hidden_size" : self.hidden_size,
"output_size" : self.output_size,
"learning_rate" : self.learning_rate,
"adaption_steps" : self.adaption_steps,
"adaption_rate" : self.adaption_rate,
"W_i" : self.numpy_to_array(self.W_i),
"W_o" : self.numpy_to_array(self.W_o),
"bias_hidden" : self.numpy_to_array(self.bias_hidden),
"bias_output" : self.numpy_to_array(self.bias_output)}
return data
def set_data (self, data):
if (data["version"] <= self.version):
self.input_size = data["input_size"]
self.hidden_size = data["hidden_size"]
self.output_size = data["output_size"]
self.learning_rate = data["learning_rate"]
self.adaption_steps = data["adaption_steps"]
self.adaption_rate = data["adaption_rate"]
self.W_i = np.array(data["W_i"])
self.W_o = np.array(data["W_o"])
self.bias_hidden = np.array(data["bias_hidden"])
self.bias_output = np.array(data["bias_output"])
else:
raise ValueError('dataset is not usable by this MLP version : dataset version is higher than MLP version')
def new_game(self):
self.first_action = True
"""
berechnet die aktivierung nach sigmoid, return: array
"""
def sigmoidAktivierung(self, gewichtsmatrix, aktivierung, bias):
#try:
z_net = bias + np.dot(aktivierung, gewichtsmatrix)
z = 1/(1.0+np.exp(-z_net))
#except Exception as e:
# print z_net
# print np.exp(-z_net)
# print z
# exit
return z
"""
Trainiert das MLP mit den übergebenen Ein- und Ausgangsdaten
"""
def train (self, data_input, data_target_value, print_data=False):
output = self.get_action(data_input)
fehler_output = (data_target_value - output)
self.evaluate_action(data_input, fehler_output)
if (print_data == True):
#if (fehler_output < 0):
#print "Eingabe:", data_input, " Erwartet:", data_out[counter_daten],(" Ausgabe: %.16f" % output), (" Ausgabe-Fehler: %.16f" % fehler_output)
#print "Erwartet:", data_target_value,(" Ausgabe: %.16f" % output), (" Ausgabe-Fehler: %.16f" % fehler_output)
fehler_output_summe = 0
for i in range(len(fehler_output)):
fehler_output_summe += fehler_output[i]
print fehler_output_summe
#else:
#print "Eingabe:", data_input, " Erwartet:", data_out[counter_daten],(" Ausgabe: %.16f" % output), (" Ausgabe-Fehler: %.16f" % fehler_output)
# print "Erwartet:", data_target_value,(" Ausgabe: %.16f" % output), (" Ausgabe-Fehler: %.16f" % fehler_output)
#print "Hidden:", hidden
#print "Hidden-Fehler:", fehler_hidden
#print "W_o:", W_o
#print "W_i:", W_i
return fehler_output
"""
Ermittelt die Ausgangswerte zu den übergebenen Eingangswerten
"""
def get_action (self, data_input):
hidden = self.sigmoidAktivierung(self.W_i, data_input, self.bias_hidden)
data_output = np.dot(hidden, self.W_o) + self.bias_output
return hidden, data_output
"""
Trainiert das MLP mit den Eingangswerten und dem Fehler der Ausgangswerte
"""
def evaluate_action_RL (self, data_input, hidden, fehler_output):
self.counter += 1
steps = self.counter / self.adaption_steps
learning_rate = self.learning_rate * (self.adaption_rate ** steps)
fehler_hidden = hidden * (1.0 - hidden) * np.dot(self.W_o, fehler_output)
hilfsm_Wo = np.outer(hidden, fehler_output)
self.W_o = self.W_o + (learning_rate * hilfsm_Wo)
hilfsm_Wi = np.outer(data_input,fehler_hidden)
self.W_i = self.W_i + (learning_rate * hilfsm_Wi)