neural_network_rb 0.1.0 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0b0d6401b734f3aaf9ceb8fd0f500e5e8b587c90
4
- data.tar.gz: c050c4adb730e487cbe4602d405d5e609e648808
3
+ metadata.gz: 181ecc0a7feea433a3e23e7de5aa9a34538d4550
4
+ data.tar.gz: dee6381c4cfa993f16f15d4759d3e2dd27a51533
5
5
  SHA512:
6
- metadata.gz: 2966e79612f5a59b6b78961669ace3ea6181e3709da18f94fdbbdd0501f21d8ad98acb2dfacbee6e7db2d40032ec7824f1bd812339943ea385bb6ca5e25d06dc
7
- data.tar.gz: 6f8b34eac283b5710018e16fbce57938ca135ea86b13b2d9f776f38f0945b9706c8c19c7a1308109da9f9ad665849a5ea643216d9790781fd5df058d67a1b357
6
+ metadata.gz: d212a1cb5bbf93ece105db806dfb3ee28e848b3ed3f8aa7a8e4dfb46a9b9fd214c2d964e55e332c3872056322638ae2f83026f97cf8fff630b0a92912fd05170
7
+ data.tar.gz: 0b981b368bb4f3cc8d6fef832cdb8b73c97208ead0d8e9a9ae832d447d2072f35d2bda849057ab0905b41c1dc69d8c2b89dcb7b8f3a87a4624402f4fa51d1ade
data/.gitignore CHANGED
@@ -10,4 +10,5 @@
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
12
  *.gz
13
- *.png
13
+ *.png
14
+ *.gem
@@ -3,6 +3,7 @@ PATH
3
3
  specs:
4
4
  neural_network_rb (0.1.0)
5
5
  chunky_png (~> 1.3.10)
6
+ numo-linalg (~> 0.1.1)
6
7
  numo-narray (~> 0.9.1.1)
7
8
 
8
9
  GEM
@@ -36,6 +37,8 @@ GEM
36
37
  notiffany (0.1.1)
37
38
  nenv (~> 0.1)
38
39
  shellany (~> 0.0)
40
+ numo-linalg (0.1.1)
41
+ numo-narray (>= 0.9.0.7)
39
42
  numo-narray (0.9.1.1)
40
43
  pry (0.11.3)
41
44
  coderay (~> 1.1.0)
@@ -1,9 +1,16 @@
1
1
  require 'numo/narray'
2
+ require 'numo/linalg/autoloader'
3
+ require 'neural_network_rb/embeddings/one_hot'
4
+ require 'neural_network_rb/activations/dot'
5
+ require 'neural_network_rb/activations/sigmoid'
6
+ require 'neural_network_rb/activations/relu'
7
+ require 'neural_network_rb/loss/softmax_cross_entropy'
8
+ require 'neural_network_rb/loss/cross_entropy_fetch'
2
9
  require 'neural_network_rb/narray'
3
10
  require 'neural_network_rb/mnist_image'
4
11
  require 'neural_network_rb/mnist'
5
12
  require "neural_network_rb/version"
6
- require 'neural_network_rb/softmax'
7
- require 'neural_network_rb/sigmoid'
13
+ require 'neural_network_rb/activations'
8
14
  require 'neural_network_rb/error'
9
15
  require 'neural_network_rb/neural_network'
16
+ require 'neural_network_rb/builder'
@@ -0,0 +1,26 @@
1
+ module NeuralNetworkRb
2
+
3
+ E = Math.exp(1)
4
+
5
+ class << self
6
+ def sigmoid(array)
7
+ max_array = array.max(1)
8
+ array.map_with_index {|a, i| a - max_array[i]}
9
+ .map_with_index {|x, i| 1/(1 + E**(-x))}
10
+ end
11
+
12
+ def sigmoid_prime(x)
13
+ s = sigmoid(x)
14
+ s * (1-s)
15
+ end
16
+
17
+ def softmax(array)
18
+ max_array = array.max(1)
19
+ exp_array = array.map_with_index {|a, i| a - max_array[i]}.map {|x| Math.exp(x)}
20
+ sum_array = exp_array.sum(1)
21
+ exp_array.map_with_index {|a, i| a/sum_array[i]}
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,5 @@
1
+ module NeuralNetworkRb
2
+ module Activations
3
+
4
+ end
5
+ end
@@ -0,0 +1,56 @@
1
+ require_relative 'activations'
2
+
3
+ module NeuralNetworkRb
4
+ module Activations
5
+ class Dot
6
+
7
+ attr_reader :width, :height
8
+ attr_reader :weight, :bias
9
+
10
+ def initialize(next_layer, width: width, learning_rate: learning_rate)
11
+ @width = width
12
+ @learning_rate = learning_rate
13
+ @next_layer = next_layer
14
+ end
15
+
16
+ def train(input, target)
17
+ output = calc(input)
18
+ next_grad = @next_layer.train(output, target)
19
+
20
+ # learn by adjusting the weight and bias
21
+ @weight -= input.transpose.dot(next_grad) * @learning_rate
22
+ @bias -= next_grad.sum(axis=0) * @learning_rate
23
+
24
+ next_grad.dot(@weight.transpose)
25
+ end
26
+
27
+ def predict(input)
28
+ @next_layer.predict(calc(input))
29
+ end
30
+
31
+ def calc(input)
32
+ if @height.nil?
33
+ @height = input.shape[1]
34
+ @weight = init_weight(@width, @height)
35
+ @bias = init_bias(@width)
36
+ end
37
+ Numo::Linalg.matmul(input, @weight) + @bias
38
+ end
39
+
40
+ private
41
+
42
+ def init_weight(width, height)
43
+ balanced_distr = Numo::DFloat.new( height, width).rand -
44
+ Numo::DFloat.ones(height, width)/2
45
+ balanced_distr * 0.01 / Math.sqrt(width)
46
+ end
47
+
48
+ def init_bias(width)
49
+ balanced_distr = Numo::DFloat.new(width).rand -
50
+ Numo::DFloat.ones(width)/2
51
+ balanced_distr * 0.01 / Math.sqrt(width)
52
+ end
53
+
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,29 @@
1
+ require_relative 'activations'
2
+
3
+ module NeuralNetworkRb
4
+ module Activations
5
+ class ReLU
6
+
7
+ def initialize(next_layer, options = {})
8
+ @next_layer = next_layer
9
+ end
10
+
11
+ def train(input, target)
12
+ output = calc(input)
13
+ grad(output) * @next_layer.train(output, target)
14
+ end
15
+
16
+ def predict(input)
17
+ @next_layer.predict(calc(input))
18
+ end
19
+
20
+ def calc(x)
21
+ x * (x > 0)
22
+ end
23
+
24
+ def grad(output)
25
+ 1.0 * (output > 0)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,39 @@
1
+ require_relative 'activations'
2
+
3
+ module NeuralNetworkRb
4
+ module Activations
5
+ class Sigmoid
6
+
7
+ def initialize(next_layer, options = {})
8
+ @next_layer = next_layer
9
+ end
10
+
11
+ def train(input, target)
12
+ output = calc(input)
13
+ grad(output) * @next_layer.train(output, target)
14
+ end
15
+
16
+ def predict(input)
17
+ @next_layer.predict(calc(input))
18
+ end
19
+
20
+ def call(input, target)
21
+ output = calc(input)
22
+ if target
23
+ grad(output) * @next_layer.call(output, target)
24
+ else
25
+ @next_layer.call(output, target)
26
+ end
27
+ end
28
+
29
+ def calc(x)
30
+ 1/(1+ Numo::NMath.exp(-(x - x.max(axis: 1, keepdims: true))))
31
+ end
32
+
33
+ def grad(output)
34
+ # s = calc(x)
35
+ output * (1 - output)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,35 @@
1
+ module NeuralNetworkRb
2
+ class NeuralNetwork
3
+ class Builder
4
+
5
+ attr_reader :layers, :named_layers
6
+
7
+ def initialize(random_seed = 1234, &block)
8
+ @layers = []
9
+ @named_layers = {}
10
+ @app = nil
11
+ Numo::NArray.srand(random_seed)
12
+ instance_eval(&block) if block_given?
13
+ end
14
+
15
+ def use(clazz, options = {}, &block)
16
+ @layers.unshift [clazz, options, block]
17
+ end
18
+
19
+ def to_network
20
+ layer = nil
21
+ @layers.each do |clazz, options, block|
22
+ layer_name = options.delete(:name)
23
+ layer = clazz.new(layer, options, &block)
24
+ @named_layers[layer_name] = layer if layer_name
25
+ end
26
+ @app = layer
27
+ end
28
+
29
+ def train(input, target)
30
+
31
+ end
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,13 @@
1
+ module NeuralNetworkRb
2
+ module Embeddings
3
+ class << self
4
+ def one_hot(labels, class_count)
5
+ Numo::Int8.zeros(labels.shape[0], class_count).tap do |matrix|
6
+ labels.each_with_index do |v, i|
7
+ matrix[i, v] = 1
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -8,8 +8,21 @@ module NeuralNetworkRb
8
8
  (v1 - v2).abs.sum
9
9
  end
10
10
 
11
+ def plain_diff(v1, v2)
12
+ v1 - v2
13
+ end
14
+
11
15
  def cross_entropy(values, labels)
12
16
  - (labels * values.map {|x| Math.log(x)}).sum/values.ndim
13
17
  end
18
+
19
+ def accuracy(values, labels)
20
+ size = values.shape[0]
21
+ hits = 0
22
+ size.times.each do |i|
23
+ hits += 1 if labels[i] == values[i, true].max_index
24
+ end
25
+ hits.to_f/size
26
+ end
14
27
  end
15
28
  end
@@ -0,0 +1,33 @@
1
+ module NeuralNetworkRb
2
+ module Loss
3
+ class CrossEntropyFetch
4
+
5
+ attr_reader :epoch
6
+
7
+ def initialize(next_layer, options = {}, &block)
8
+ @next_layer = next_layer
9
+ @every = options[:every]
10
+ @block = block if block_given?
11
+ @epoch = 0
12
+ end
13
+
14
+ def train(input, target)
15
+ error = cross_entropy(input, target)
16
+ @block.call(@epoch, error) if @block && (@epoch % @every == 0)
17
+ @epoch +=1
18
+ @next_layer.nil? ? 1 : @next_layer.train(input, target)
19
+ end
20
+
21
+ def predict(input)
22
+ @next_layer.nil? ? input : @next_layer.predict(input)
23
+ end
24
+
25
+ private
26
+
27
+ def cross_entropy(input, target)
28
+ - (target * input.map {|x| Math.log(x)}).sum/input.ndim
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,36 @@
1
+ module NeuralNetworkRb
2
+ module Loss
3
+ class SoftmaxCrossEntropy
4
+
5
+ def initialize(next_layer, options = {})
6
+ @next_layer = next_layer
7
+ end
8
+
9
+ def train(input, target)
10
+ output = softmax(input)
11
+ grad(output, target) * @next_layer.train(output, target)
12
+ end
13
+
14
+ def predict(input)
15
+ @next_layer.predict(softmax(input))
16
+ end
17
+
18
+ def call(input, target)
19
+ error = cross_entropy(softmax(input), target)
20
+ grad(input, target) if target
21
+ end
22
+
23
+ private
24
+
25
+ def grad(input, target)
26
+ input - target
27
+ end
28
+
29
+ def softmax(x)
30
+ e_x = Numo::NMath.exp(x - x.max(axis: 1, keepdims: true))
31
+ e_x / e_x.sum(axis: 1, keepdims: true)
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -7,44 +7,93 @@ module NeuralNetworkRb
7
7
 
8
8
  N_FEATURES = 28 * 28
9
9
  N_CLASSES = 10
10
- FILE_NAMES = %w(train-images-idx3-ubyte.gz train-labels-idx1-ubyte.gz t10k-images-idx3-ubyte.gz t10k-labels-idx1-ubyte.gz)
10
+ TRAIN_FILE_NAMES = %w(train-images-idx3-ubyte.gz train-labels-idx1-ubyte.gz)
11
+ TEST_FILE_NAMES = %w(t10k-images-idx3-ubyte.gz t10k-labels-idx1-ubyte.gz)
11
12
  ROOT_URL = 'http://yann.lecun.com/exdb/mnist/'
12
13
 
13
14
  class << self
14
- def download!
15
- FILE_NAMES.each do |name|
16
- url = "#{ROOT_URL}#{name}"
17
- fetch_file(name, url)
15
+
16
+ def training_set
17
+ download(TRAIN_FILE_NAMES)
18
+ end
19
+
20
+ def test_set
21
+ download(TEST_FILE_NAMES)
22
+ end
23
+
24
+ def display_image(narray)
25
+ narray.shape[0].times do |r|
26
+ puts narray[r*28..((r+1)*28-1)].to_a.inspect
18
27
  end
19
- self.new
20
28
  end
21
29
 
22
- private
30
+ def embed_labels(labels, algorithm, class_count)
31
+ NeuralNetworkRb::Embeddings.send(algorithm, labels, class_count)
32
+ end
33
+
34
+ private
35
+ def download(files)
36
+ files.each do |name|
37
+ if !File.exists?(name)
38
+ url = "#{ROOT_URL}#{name}"
39
+ fetch_file(name, url)
40
+ end
41
+ end
42
+ self.new(*files)
43
+ end
44
+
23
45
  def fetch_file(filePath, url)
24
46
  File.open(filePath, "w") do |output|
25
47
  IO.copy_stream(open(url), output)
26
48
  end
27
49
  end
50
+
28
51
  end
29
52
 
30
- def training_labels
31
- labels(FILE_NAMES[1])
53
+ attr_accessor :labels, :data, :validation_data, :validation_labels
54
+
55
+ def initialize(data_file = nil, label_file = nil)
56
+ @labels = get_labels(label_file) if label_file
57
+ @data = get_images(data_file) if data_file
32
58
  end
33
59
 
34
- def test_labels
35
- labels(FILE_NAMES[3])
60
+ def clone
61
+ self.class.new.tap do |m|
62
+ m.data = self.data.copy
63
+ m.labels = self.labels.copy
64
+ m.validation_data = self.validation_data.copy if self.validation_data
65
+ m.validation_labels = self.validation_labels.copy if self.validation_labels
66
+ end
67
+ end
68
+
69
+ def shuffle!(seed)
70
+ @data, @labels = NeuralNetworkRb.shuffle(@data, @labels, seed)
71
+ self
36
72
  end
37
73
 
38
- def training_images
39
- images(FILE_NAMES[0])
74
+ def partition!(train_ratio)
75
+ @data, @validation_data = NeuralNetworkRb.split(@data, train_ratio)
76
+ @labels, @validation_labels = NeuralNetworkRb.split(@labels, train_ratio)
77
+ self
40
78
  end
41
79
 
42
- def test_images
43
- images(FILE_NAMES[2])
80
+
81
+ def batches(batches_count)
82
+ total_size = self.data.shape[0]
83
+ batch_size = (total_size.to_f/batches_count).ceil
84
+ Array.new(batches_count).tap do |result|
85
+ batches_count.times do |i|
86
+ range = batch_size*i..batch_size*(i+1)-1
87
+ batch_data = NeuralNetworkRb.rows(@data, range) # self.data[batch_size*i..batch_size*(i+1)-1, true]
88
+ batch_labels = NeuralNetworkRb.rows(@labels, range) # self.labels[batch_size*i..batch_size*(i+1)-1]
89
+ result[i] = [batch_data, batch_labels]
90
+ end
91
+ end
44
92
  end
45
93
 
46
94
  private
47
- def images(file_name)
95
+
96
+ def get_images(file_name)
48
97
  images = []
49
98
  Zlib::GzipReader.open(file_name) do |f|
50
99
  _, n_images = f.read(8).unpack('N2')
@@ -57,7 +106,7 @@ module NeuralNetworkRb
57
106
  Numo::Int16.cast(images)
58
107
  end
59
108
 
60
- def labels(file_name)
109
+ def get_labels(file_name)
61
110
  labels = nil
62
111
  Zlib::GzipReader.open(file_name) do |f|
63
112
  _, @n_labels = f.read(8).unpack('N2')
@@ -2,24 +2,21 @@ module NeuralNetworkRb
2
2
 
3
3
  class << self
4
4
 
5
- def shuffle(data, target)
5
+ def shuffle(data, target, seed)
6
6
  sample_size = data.shape[0]
7
- new_order = Numo::DFloat[*(0..sample_size-1).to_a.shuffle]
8
- [data[*subset(data, new_order)], target[*subset(target, new_order)]]
7
+ new_order = Numo::DFloat[*(0..sample_size-1).to_a.shuffle(random: Random.new(seed))]
8
+ [rows(data, new_order), rows(target, new_order)]
9
9
  end
10
10
 
11
11
  def split(data, ratio)
12
12
  sample_size = (data.shape[0] * ratio).to_i
13
- [data[*subset(data, 0..sample_size-1)], data[*subset(data, sample_size..-1)]]
13
+ [rows(data, 0..sample_size-1), rows(data, sample_size..-1)]
14
+ end
15
+
16
+ def rows(data, obj)
17
+ data[obj, *Array.new(data.ndim-1, true)]
14
18
  end
15
-
16
- private
17
19
 
18
- def subset(data, obj)
19
- Array.new(data.ndim, true).tap do |x|
20
- x[0] = obj
21
- end
22
- end
23
20
  end
24
21
 
25
22
  end
@@ -5,41 +5,57 @@ module NeuralNetworkRb
5
5
  attr_reader :target, :output, :epoch
6
6
 
7
7
  def input=(input)
8
- @input = input
8
+ @input = input/255.0
9
9
  input_width = input.shape[1]
10
- @w_hidden = Numo::DFloat.new(input_width, @neurons_count).rand
10
+ @w1 = (Numo::DFloat.new(input_width, @neurons_count).rand -
11
+ Numo::DFloat.ones(input_width, @neurons_count)/2) * 0.01 / Math.sqrt(input_width)
12
+ @b1 = Numo::DFloat.zeros(@neurons_count)
11
13
  end
12
14
 
13
15
  def target=(target)
14
16
  @target = target
15
17
  output_width = target.shape[1]
16
- @w_output = Numo::DFloat.new(@neurons_count, output_width).rand
18
+ @w2 = (Numo::DFloat.new(@neurons_count, output_width).rand -
19
+ Numo::DFloat.ones(@neurons_count, output_width)/2) * 0.01 / Math.sqrt(@neurons_count)
20
+ @b2 = Numo::DFloat.zeros(output_width)
17
21
  end
18
22
 
19
- def initialize(neurons_count, learning_rate)
23
+ def initialize(neurons_count, learning_rate, random_seed)
20
24
  @neurons_count = neurons_count
21
25
  @learning_rate = learning_rate
22
26
  @epoch = 0
27
+ Numo::NArray.srand(random_seed)
23
28
  end
24
29
 
25
- def train()
26
- # forward
27
- @hidden = NeuralNetworkRb.sigmoid(@input.dot(@w_hidden))
28
- @output = @hidden.dot(@w_output)
30
+ def fit()
31
+ forward
32
+ backprop
33
+ @epoch += 1
34
+ yield self if block_given?
35
+ end
29
36
 
30
- # calculate error
31
- error = @target - @output
37
+ def forward
38
+ # forward
39
+ @hidden = NeuralNetworkRb.sigmoid(
40
+ Numo::Linalg.matmul(@input, @w1) +
41
+ @b1)
42
+ @output = NeuralNetworkRb.softmax(
43
+ Numo::Linalg.matmul(@hidden, @w2) +
44
+ @b2)
45
+ end
32
46
 
47
+ def backprop
33
48
  # backward
34
- dZ = error * @learning_rate
35
-
36
- @w_output += @hidden.transpose.dot(dZ)
37
- dH = dZ.dot(@w_output.transpose) * NeuralNetworkRb.sigmoid_prime(@hidden)
38
- @w_hidden += @input.transpose.dot(dH)
39
-
40
- @epoch += 1
41
- yield self if block_given?
49
+ dZ = NeuralNetworkRb.plain_diff(@target, @output)
50
+ @w2 += Numo::Linalg.matmul(@hidden.transpose, dZ) * @learning_rate
51
+ dH = Numo::Linalg.matmul(dZ, @w2.transpose) * NeuralNetworkRb.sigmoid_prime(@hidden)
52
+ @w1 += Numo::Linalg.matmul(@input.transpose, dH) * @learning_rate
42
53
  end
43
54
 
55
+ def predict(input)
56
+ hidden = NeuralNetworkRb.sigmoid(Numo::Linalg.matmul(input/255.0, @w1))
57
+ output = NeuralNetworkRb.softmax(Numo::Linalg.matmul(hidden, @w2))
58
+ output
59
+ end
44
60
  end
45
61
  end
@@ -1,3 +1,3 @@
1
1
  module NeuralNetworkRb
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.require_paths = ["lib"]
30
30
 
31
31
  spec.add_dependency "numo-narray", "~> 0.9.1.1"
32
+ spec.add_dependency "numo-linalg", "~> 0.1.1"
32
33
  spec.add_dependency "chunky_png", "~> 1.3.10"
33
34
 
34
35
  spec.add_development_dependency "bundler", "~> 1.16"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neural_network_rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jack Xu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-08 00:00:00.000000000 Z
11
+ date: 2018-03-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: numo-narray
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.9.1.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: numo-linalg
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.1.1
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: chunky_png
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -96,13 +110,20 @@ files:
96
110
  - README.md
97
111
  - Rakefile
98
112
  - lib/neural_network_rb.rb
113
+ - lib/neural_network_rb/activations.rb
114
+ - lib/neural_network_rb/activations/activations.rb
115
+ - lib/neural_network_rb/activations/dot.rb
116
+ - lib/neural_network_rb/activations/relu.rb
117
+ - lib/neural_network_rb/activations/sigmoid.rb
118
+ - lib/neural_network_rb/builder.rb
119
+ - lib/neural_network_rb/embeddings/one_hot.rb
99
120
  - lib/neural_network_rb/error.rb
121
+ - lib/neural_network_rb/loss/cross_entropy_fetch.rb
122
+ - lib/neural_network_rb/loss/softmax_cross_entropy.rb
100
123
  - lib/neural_network_rb/mnist.rb
101
124
  - lib/neural_network_rb/mnist_image.rb
102
125
  - lib/neural_network_rb/narray.rb
103
126
  - lib/neural_network_rb/neural_network.rb
104
- - lib/neural_network_rb/sigmoid.rb
105
- - lib/neural_network_rb/softmax.rb
106
127
  - lib/neural_network_rb/version.rb
107
128
  - neural_network_rb.gemspec
108
129
  homepage: https://github.com/jackxxu/neural_network_rb
@@ -1,16 +0,0 @@
1
- module NeuralNetworkRb
2
-
3
- E = Math.exp(1)
4
-
5
- class << self
6
- def sigmoid(x)
7
- 1/(1 + E**(-x))
8
- end
9
-
10
- def sigmoid_prime(x)
11
- s = sigmoid(x)
12
- s * (1-s)
13
- end
14
- end
15
-
16
- end
@@ -1,8 +0,0 @@
1
- module NeuralNetworkRb
2
-
3
- def self.softmax(array)
4
- exp_array = array.map {|x| Math.exp(x)}
5
- exp_array = exp_array/exp_array.sum
6
- end
7
-
8
- end