bp_net 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/bp_net.rb +108 -0
  3. metadata +43 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4ae78900480ba50a21932b089dfb61c8008e4094255da4c76f1b8897ee3a9b8b
4
+ data.tar.gz: ea012ac44327f5e91df5da58c131c0df5a637aa27a613200ae21b1a2f2ed92f7
5
+ SHA512:
6
+ metadata.gz: 9fe9e7a877f4dbc80c403bcb072bf9051dc9c77a7ad182ce5a4f737beb3d0e082e6fa7b40af6bd4ce954c919d17d0b11e7dd9b49ccac0b1ec01b0e37910a5fbe
7
+ data.tar.gz: e4b2b7e6a1269ea7659e0de5bb8ade20e247172490a74432e6aa3a0a219ba3c0ba1f037fa4b5d15ef2b1d40d92cc5b23e4047037f7a0286499de2476874b7f8f
data/lib/bp_net.rb ADDED
@@ -0,0 +1,108 @@
1
+ require 'matrix'
2
+
3
+ class Matrix
4
+ def disp(line_feed: 1)
5
+ row_vectors.each do |row| # self.row_vectors...
6
+ row.each do |ele| # print elements by row
7
+ print "#{ele}\t"
8
+ end
9
+ line_feed.times { puts } # Line Feed
10
+ end
11
+ self
12
+ end
13
+ end
14
+
15
+ class BpNet
16
+ # accessable attributes
17
+ ACCESSABLE_ATTRS = %i[inodes hnodes onodes lr wih who]
18
+ attr_accessor(*ACCESSABLE_ATTRS)
19
+
20
+ # initialization
21
+ def initialize(inputnodes:, hiddennodes:, outputnodes:, learningrate:)
22
+ @inodes = inputnodes # input nodes
23
+ @hnodes = hiddennodes # hidden nodes
24
+ @onodes = outputnodes # output nodes
25
+ @lr = learningrate # learning rate
26
+
27
+ # weight matrixes
28
+ @wih = Matrix.build(hiddennodes, inputnodes) { rand - 0.5 }
29
+ @who = Matrix.build(outputnodes, hiddennodes) { rand - 0.5 }
30
+ end
31
+
32
+ # train
33
+ def train(inputs_mat, targets_mat)
34
+ inputs_mat = arr2mat(inputs_mat) # convert array to matrix
35
+ targets_mat = arr2mat(targets_mat) # convert arr 2 mat
36
+
37
+ hidden_inputs = @wih * inputs_mat # Hi = Wih * I
38
+ hidden_outputs = BpNet.sigmoid(hidden_inputs) # H = sigmoid(Hi)
39
+ outputs_inputs = @who * hidden_outputs # Oi = Who * H
40
+ outputs_outputs = BpNet.sigmoid(outputs_inputs) # O = sigmoid(Oi)
41
+
42
+ output_errors = targets_mat - outputs_outputs
43
+ @who += update(output_errors, outputs_inputs, hidden_outputs)
44
+
45
+ hidden_errors = @who.t * output_errors
46
+ @wih += update(hidden_errors, hidden_inputs, inputs_mat)
47
+ end
48
+
49
+ # query
50
+ # Hi = Wih * I
51
+ # H = sigmoid(Hi)
52
+ # Oi = Who * H
53
+ # O = sigmoid(Oi)
54
+ def query(inputs_mat)
55
+ inputs_mat = arr2mat(inputs_mat) # convert array to matrix
56
+
57
+ hidden_inputs = @wih * inputs_mat # Hi = Wih * I
58
+ hidden_outputs = BpNet.sigmoid(hidden_inputs) # H = sigmoid(Hi)
59
+ outputs_inputs = @who * hidden_outputs # Oi = Who * H
60
+ outputs_outputs = BpNet.sigmoid(outputs_inputs) # O = sigmoid(Oi)
61
+ end
62
+
63
+ def arr2mat(arr)
64
+ if arr.is_a? Array
65
+ Matrix[arr].t
66
+ else
67
+ arr
68
+ end
69
+ end
70
+
71
+ ## calculations goes here
72
+ # singular sigmoid
73
+ @singular_sigmoid = ->(x) { 1 / (1 + Math::E**-x) }
74
+
75
+ # singular sigmoid differentiation
76
+ @singular_sigmoid_diff = lambda do |x|
77
+ @singular_sigmoid.call(x) * (1 - @singular_sigmoid.call(x))
78
+ end
79
+
80
+ def update(errors, next_inputs, prev_outputs)
81
+ @lr *
82
+ errors.hadamard_product(BpNet.sigmoid_diff(next_inputs)) *
83
+ prev_outputs.t
84
+ end
85
+
86
+ ## packed enumerable calculations
87
+ # sigmoid
88
+ def self.sigmoid(x)
89
+ enum_calc(x, @singular_sigmoid) { |param| sigmoid(param) }
90
+ end
91
+
92
+ # sigmoid differentiation
93
+ def self.sigmoid_diff(x)
94
+ enum_calc(x, @singular_sigmoid_diff) { |param| sigmoid_diff(param) }
95
+ end
96
+
97
+ ## enumerable calculation
98
+ def self.enum_calc(x, calc, &block)
99
+ if x.is_a? Enumerable
100
+ x.map(&block) # return values recursively
101
+ else
102
+ calc.call(x) # return value
103
+ end
104
+ end
105
+
106
+ # private class methods
107
+ private_class_method :enum_calc
108
+ end
metadata ADDED
@@ -0,0 +1,43 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bp_net
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Rurika Misaka
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-05-08 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A sipmle BP Neural Network gem
14
+ email: goblinmaiden1931@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/bp_net.rb
20
+ homepage:
21
+ licenses:
22
+ - MIT
23
+ metadata: {}
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ requirements: []
39
+ rubygems_version: 3.2.3
40
+ signing_key:
41
+ specification_version: 4
42
+ summary: Simple BP Neural Network
43
+ test_files: []