Class: Hopfield::Network

Inherits:
Object
  • Object
show all
Defined in:
lib/hopfield/network.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(training, perturbed_pattern) ⇒ Network

Returns a new instance of Network.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/hopfield/network.rb', line 5

def initialize(training, perturbed_pattern)
  unless training.class.to_s == 'Hopfield::Training'
    raise TypeError, 'Training has to be an instance of Hopfield::Training'
  end
  
  unless training.patterns.first.size == perturbed_pattern.flatten.size
    raise SyntaxError, 'Given pattern does not match size of the training patterns'
  end
  
  # Turn 0 into -1
  perturbed_pattern = perturbed_pattern.flatten.map { |value| (value == 0 ? -1 : value) }
  
  self.neurons =  training.neurons
  self.patterns = training.patterns
  self.weights =  training.weights
  self.pattern_dimensions = training.pattern_dimensions
  
  self.neurons.count.times do |i|
    self.neurons[i].state = perturbed_pattern[i]
  end
  
  self.last_error = [1]
  self.runs =       0
end

Instance Attribute Details

#last_errorObject

Returns the value of attribute last_error.



3
4
5
# File 'lib/hopfield/network.rb', line 3

def last_error
  @last_error
end

#neuronsObject

Returns the value of attribute neurons.



3
4
5
# File 'lib/hopfield/network.rb', line 3

def neurons
  @neurons
end

#pattern_dimensionsObject

Returns the value of attribute pattern_dimensions.



3
4
5
# File 'lib/hopfield/network.rb', line 3

def pattern_dimensions
  @pattern_dimensions
end

#patternsObject

Returns the value of attribute patterns.



3
4
5
# File 'lib/hopfield/network.rb', line 3

def patterns
  @patterns
end

#runsObject

Returns the value of attribute runs.



3
4
5
# File 'lib/hopfield/network.rb', line 3

def runs
  @runs
end

#stateObject

Returns the value of attribute state.



3
4
5
# File 'lib/hopfield/network.rb', line 3

def state
  @state
end

#weightsObject

Returns the value of attribute weights.



3
4
5
# File 'lib/hopfield/network.rb', line 3

def weights
  @weights
end

Instance Method Details

#associated?Boolean

Returns:

  • (Boolean)


30
31
32
# File 'lib/hopfield/network.rb', line 30

def associated?
  return self.last_error.include? 0
end

#calculate_error(current_pattern) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/hopfield/network.rb', line 78

def calculate_error(current_pattern)
  errors = Array.new(0)
  
  self.patterns.each do |pattern|
    sum = 0
  
    expected = pattern.flatten
    actual = current_pattern
  
    expected.each_with_index do |v, i|
      sum += 1 if expected[i]!=actual[i]
    end
    errors << sum
  end
  return errors
end

#get_weight(i, j) ⇒ Object



38
39
40
41
# File 'lib/hopfield/network.rb', line 38

def get_weight(i , j)
  ij = [i, j].sort
  return self.weights[ij.first][ij.last]
end

#patternObject



34
35
36
# File 'lib/hopfield/network.rb', line 34

def pattern
  return self.state
end

#propagateObject



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/hopfield/network.rb', line 43

def propagate
  # Select random neuron
  i = rand(self.neurons.count)
  
  activation = 0.0
  
  self.neurons.each_with_index do |other, j|
    next if i == j
    activation += get_weight(i, j)*other.state
  end
  
  output = transfer(activation)
  change = output != self.neurons[i].state
  self.neurons[i].state = output
  
  # Compile state of outputs
  state = Array.new(self.neurons.count){ |i| self.neurons[i].state }

  # Calculate the current error
  self.last_error = calculate_error(state)

  # Convert state to binary and back to a multi dimensional array
  state = to_binary(state)
  state = state.each_slice(self.pattern_dimensions[:width]).to_a
  self.state = state
  
  self.runs += 1
  
  return {
    :did_change => change, 
    :state => self.state,
    :error => self.last_error
  } 
end

#to_binary(vector) ⇒ Object



99
100
101
# File 'lib/hopfield/network.rb', line 99

def to_binary(vector)
  return Array.new(vector.size){|i| ((vector[i] == -1) ? 0 : 1)}
end

#transfer(activation) ⇒ Object



95
96
97
# File 'lib/hopfield/network.rb', line 95

def transfer(activation)
  (activation >= 0 ? 1 : -1)
end