Skip to content

Commit

Permalink
Add neural network
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-lairan committed Sep 24, 2018
1 parent b719331 commit 5081af6
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 0 deletions.
6 changes: 6 additions & 0 deletions shard.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: 1.0
shards:
linalg:
github: konovod/linalg
commit: 3467699ad720d5f4c2e55cbfe925bec5addce227

4 changes: 4 additions & 0 deletions shard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ targets:
crystal: 0.26.1

license: MIT

dependencies:
linalg:
github: konovod/linalg
7 changes: 7 additions & 0 deletions src/deep_learning.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
require "linalg"

require "./mnist/**"
require "./neural/**"

module DeepLearning
VERSION = "0.1.0"
Expand All @@ -11,3 +14,7 @@ labels = File.open("./data/train-labels.idx1-ubyte")

loader = Mnist::Loader.new(images, labels)
data = loader.call

network = Neural::Builder.new([28 * 28, 16, 16, 10]).call(Neural::Builder::RANDOM_VALUE)
image = LA::GMat.new(28 * 28, 1) { |i, _| data.first.image[i] }
pp network.call(image)
23 changes: 23 additions & 0 deletions src/neural/builder.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require "./network"

module Neural
class Builder
DEFAULT_VALUE = Proc(Float64).new { 0.0 }
RANDOM_VALUE = Proc(Float64).new { rand(-1.0..1.0) }

def initialize(@levels : Array(Int32))
end

def call(default_value = DEFAULT_VALUE) : Network
nodes = Array.new(@levels.size) do |i|
LA::GMat.new(@levels[i], 1) { default_value.call }
end

links = Array.new(@levels.size - 1) do |i|
LA::GMat.new(@levels[i + 1], @levels[i]) { default_value.call }
end

Network.new(nodes, links)
end
end
end
34 changes: 34 additions & 0 deletions src/neural/network.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,38 @@
module Neural
class Network
getter nodes, links

def initialize(@nodes : Array(LA::GMat), @links : Array(LA::GMat))
end

def call(image : LA::GMat)
vector_for(@nodes.size - 1, image)
end

private def vector_for(x : Int32, image : LA::GMat)
if x == 0
bias = @nodes[x]
matrix = image
matrix_sigmoid(matrix + bias)
else
matrix = @links[x - 1]
bias = @nodes[x]

matrix_sigmoid(matrix * vector_for(x - 1, image) + bias)
end
end

private def sigmoid(x)
1 / (1 + Math.exp(-x))
end

private def matrix_sigmoid(matrix)
matrix.map { |val| sigmoid(val) }
end

private def matrix_sigmoid_derivative(matrix)
ones = Matrix.build(matrix.column_size, matrix.row_size) { 1 }
matrix_sigmoid(matrix) * (ones - matrix_sigmoid(matrix))
end
end
end

0 comments on commit 5081af6

Please sign in to comment.