FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
ClassicComputerScienceProblemsInPython/Chapter7/network.py at master · msouto/ClassicComputerScienceProblemsInPython · GitHub
msouto
/
ClassicComputerScienceProblemsInPython
Public
forked from
davecom/ClassicComputerScienceProblemsInPython
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
ClassicComputerScienceProblemsInPython
/
Chapter7
/
network.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
81 lines (72 loc) · 4.05 KB
Breadcrumbs
ClassicComputerScienceProblemsInPython
/
Chapter7
/
network.py
Copy path
File metadata and controls
81 lines (72 loc) · 4.05 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
# network.py
# From Classic Computer Science Problems in Python Chapter 7
# Copyright 2018 David Kopec
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from
__future__
import
annotations
from
typing
import
List
,
Callable
,
TypeVar
,
Tuple
from
functools
import
reduce
from
layer
import
Layer
from
util
import
sigmoid
,
derivative_sigmoid
T
=
TypeVar
(
'T'
)
# output type of interpretation of neural network
class
Network
:
def
__init__
(
self
,
layer_structure
:
List
[
int
],
learning_rate
:
float
,
activation_function
:
Callable
[[
float
],
float
]
=
sigmoid
,
derivative_activation_function
:
Callable
[[
float
],
float
]
=
derivative_sigmoid
)
->
None
:
if
len
(
layer_structure
)
<
3
:
raise
ValueError
(
"Error: Should be at least 3 layers (1 input, 1 hidden, 1 output)"
)
self
.
layers
:
List
[
Layer
]
=
[]
# input layer
input_layer
:
Layer
=
Layer
(
None
,
layer_structure
[
0
],
learning_rate
,
activation_function
,
derivative_activation_function
)
self
.
layers
.
append
(
input_layer
)
# hidden layers and output layer
for
previous
,
num_neurons
in
enumerate
(
layer_structure
[
1
::]):
next_layer
=
Layer
(
self
.
layers
[
previous
],
num_neurons
,
learning_rate
,
activation_function
,
derivative_activation_function
)
self
.
layers
.
append
(
next_layer
)
# Pushes input data to the first layer, then output from the first
# as input to the second, second to the third, etc.
def
outputs
(
self
,
input
:
List
[
float
])
->
List
[
float
]:
return
reduce
(
lambda
inputs
,
layer
:
layer
.
outputs
(
inputs
),
self
.
layers
,
input
)
# Figure out each neuron's changes based on the errors of the output
# versus the expected outcome
def
backpropagate
(
self
,
expected
:
List
[
float
])
->
None
:
# calculate delta for output layer neurons
last_layer
:
int
=
len
(
self
.
layers
)
-
1
self
.
layers
[
last_layer
].
calculate_deltas_for_output_layer
(
expected
)
# calculate delta for hidden layers in reverse order
for
l
in
range
(
last_layer
-
1
,
0
,
-
1
):
self
.
layers
[
l
].
calculate_deltas_for_hidden_layer
(
self
.
layers
[
l
+
1
])
# backpropagate() doesn't actually change any weights
# this function uses the deltas calculated in backpropagate() to
# actually make changes to the weights
def
update_weights
(
self
)
->
None
:
for
layer
in
self
.
layers
[
1
:]:
# skip input layer
for
neuron
in
layer
.
neurons
:
for
w
in
range
(
len
(
neuron
.
weights
)):
neuron
.
weights
[
w
]
=
neuron
.
weights
[
w
]
+
(
neuron
.
learning_rate
*
(
layer
.
previous_layer
.
output_cache
[
w
])
*
neuron
.
delta
)
# train() uses the results of outputs() run over many inputs and compared
# against expecteds to feed backpropagate() and update_weights()
def
train
(
self
,
inputs
:
List
[
List
[
float
]],
expecteds
:
List
[
List
[
float
]])
->
None
:
for
location
,
xs
in
enumerate
(
inputs
):
ys
:
List
[
float
]
=
expecteds
[
location
]
outs
:
List
[
float
]
=
self
.
outputs
(
xs
)
self
.
backpropagate
(
ys
)
self
.
update_weights
()
# for generalized results that require classification this function will return
# the correct number of trials and the percentage correct out of the total
def
validate
(
self
,
inputs
:
List
[
List
[
float
]],
expecteds
:
List
[
T
],
interpret_output
:
Callable
[[
List
[
float
]],
T
])
->
Tuple
[
int
,
int
,
float
]:
correct
:
int
=
0
for
input
,
expected
in
zip
(
inputs
,
expecteds
):
result
:
T
=
interpret_output
(
self
.
outputs
(
input
))
if
result
==
expected
:
correct
+=
1
percentage
:
float
=
correct
/
len
(
inputs
)
return
correct
,
len
(
inputs
),
percentage
Back
|
FazBrowse Home
|
New Git URL