neural_network_rb 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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