SimpleNeuralNetwork 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 46f5556f65b4606a5e8314e7ba7791f73ba314fd
4
+ data.tar.gz: 72fdae81f4c25de9f57bf4295f064d414dcd5380
5
+ SHA512:
6
+ metadata.gz: 7149124f6817e608bba4ad2f9ca8419bbf50c27991fc1565b59f0f42cb8b2d1bdfa17fb4ad3bfeb4c41055eb19b7bec0b22e30361ead91c4c3251c4fb9a2c92a
7
+ data.tar.gz: 73e138bd6e0b474fcf57e576a884a407fe6512f2e0ae66ed8ab8ae2c22143247ac6b24aae5c2c409d3e19a83d3ea41075d71745b96c2ed34f9d5b5a31b4f9d35
@@ -0,0 +1,71 @@
1
+ require_relative "neuron"
2
+
3
+ class SimpleNeuralNetwork
4
+ class Layer
5
+ # Number of neurons
6
+ attr_accessor :size
7
+
8
+ attr_accessor :prev_layer
9
+ attr_accessor :next_layer
10
+
11
+ # List of #{size} neurons
12
+ attr_accessor :neurons
13
+
14
+ attr_accessor :network
15
+
16
+ def initialize(size, network)
17
+ @size = size
18
+ @neurons = []
19
+ @network = network
20
+
21
+ populate_neurons
22
+ end
23
+
24
+ # The method that drives network output resolution.
25
+ # get_output calculates the array of node values for this layer.
26
+ # This is calculated by recursively fetching the output from the previous layer, then applying edge/node weight rules.
27
+ # The first layer will fetch it's values from @network.inputs
28
+ def get_output
29
+ if !prev_layer
30
+ # This is the first layer, so the output set is simply the network input set
31
+ @network.inputs
32
+ else
33
+ # Each neuron output value is calculated by:
34
+ # output[i] = (
35
+ # (prev_layer.neurons[0] * prev_layer.neurons[0].edges[i])
36
+ # + (prev_layer.neurons[1] * prev_layer.neurons[1].edges[i])
37
+ # + ...
38
+ # ) + self.neurons[i].bias
39
+
40
+ prev_layer_output = prev_layer.get_output
41
+
42
+ # Generate the output values for the layer
43
+ (0..@size-1).map do |i|
44
+ value = 0
45
+
46
+ prev_layer_output.each_with_index do |output, index|
47
+ value += (output * prev_layer.neurons[index].edges[i])
48
+ end
49
+
50
+ value + @neurons[i].bias
51
+ end
52
+ end
53
+ end
54
+
55
+ def initialize_neuron_edges
56
+ return unless @next_layer
57
+
58
+ @neurons.each do |neuron|
59
+ neuron.initialize_edges(@next_layer.size)
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def populate_neurons
66
+ @size.times do
67
+ @neurons << Neuron.new(layer: self)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,78 @@
1
+ require_relative "layer"
2
+
3
+ # To properly initialze a network:
4
+ # - Initialize the new Network object
5
+ # - Create layers using Network#create_layer
6
+ # (This creates layers from left to right, input -> hidden layers -> output layer)
7
+ # - Call Network#initialize_edges to populate neuron edges in the network.
8
+ # This has to be done after creating all layers because the number of edges depends
9
+ # on the number on neurons in the next layer
10
+ class SimpleNeuralNetwork
11
+ class Network
12
+ class InvalidInputError < StandardError; end
13
+ # An array of layers
14
+ attr_accessor :layers
15
+
16
+ attr_accessor :inputs
17
+
18
+ def initialize
19
+ @layers = []
20
+ @inputs = []
21
+ end
22
+
23
+ # Run an input set against the neural network.
24
+ # Accepts an array of input integers between 0 and 1 of length #input_size
25
+ # Returns
26
+ def run(inputs)
27
+ unless inputs.size == input_size && inputs.all? { |input| input >= 0 && input <= 1 }
28
+ raise InvalidInputError.new("Invalid input passed to Network#run")
29
+ end
30
+
31
+ @inputs = inputs
32
+
33
+ # Get output from last layer. It recursively depends on layers before it.
34
+ @layers[-1].get_output
35
+ end
36
+
37
+ # Returns the number of input nodes
38
+ def input_size
39
+ @layers[0].size
40
+ end
41
+
42
+ # Returns the number of output nodes
43
+ def output_size
44
+ @layers[-1].size
45
+ end
46
+
47
+ def create_layer(neurons:)
48
+ unless @layers.empty?
49
+ new_layer = Layer.new(neurons, self)
50
+ prev_layer = @layers.last
51
+
52
+ @layers << new_layer
53
+
54
+ new_layer.prev_layer = prev_layer
55
+ prev_layer.next_layer = new_layer
56
+ else
57
+ @layers << Layer.new(neurons, self)
58
+ end
59
+ end
60
+
61
+ # This traverses the network and initializes all neurons with edges
62
+ # Initializes with random weights between -5 and 5
63
+ def initialize_edges
64
+ @layers.each(&:initialize_neuron_edges)
65
+ end
66
+ end
67
+ end
68
+
69
+ # Sample usage:
70
+ #
71
+ # network = Network.new
72
+ #
73
+ # network.create_layer(neurons: 10)
74
+ # network.create_layer(neurons: 2)
75
+
76
+ # network.initialize_edges
77
+
78
+ # network.run([0.5]*10)
@@ -0,0 +1,28 @@
1
+ class SimpleNeuralNetwork
2
+ class Neuron
3
+ # Define the minimum and maximum edge weight
4
+ EDGE_RANGE = -5..5
5
+
6
+ attr_accessor :bias
7
+
8
+ # The neuron parent layer
9
+ attr_accessor :layer
10
+
11
+ # A neuron's edges connect it to the #{layer.next_layer.size} neurons of the next layer
12
+ attr_accessor :edges
13
+
14
+ def initialize(layer)
15
+ @layer = layer
16
+ @bias = 0
17
+ @edges = []
18
+ @value = nil
19
+ end
20
+
21
+ # A neuron should have one edge per neuron in the next layer
22
+ def initialize_edges(next_layer_size)
23
+ next_layer_size.times do
24
+ @edges << rand(EDGE_RANGE)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ class SimpleNeuralNetwork
2
+ require "network"
3
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: SimpleNeuralNetwork
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Nathaniel Woodthorpe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-02-20 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A very simple neural network implementation in Ruby.
14
+ email: njwoodthorpe@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/layer.rb
20
+ - lib/network.rb
21
+ - lib/neuron.rb
22
+ - lib/simple_neural_network.rb
23
+ homepage: https://github.com/d12/SimpleNeuralNetwork
24
+ licenses:
25
+ - MIT
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 2.5.2
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: A very simple neural network implementation in Ruby.
47
+ test_files: []