Hopfield network의 루비 구현

신경망 | 2009/02/14 18:39 | Posted by DMW
크리에이티브 커먼즈 라이선스
Creative Commons License
역시 별 내용은 업ㅂ구 소스 코드만 나온다능

require "matrix"
require "pp"

class Hopfield
    attr_reader :output_pattern
    
    def initialize(pattern_size)
        @pattern_size = pattern_size
        @w = Matrix[ *[].fill([].fill(0, 0, @pattern_size), 0, @pattern_size) ]
    end
    
    def learn(pattern)
        delta_w = Matrix[pattern].t * Matrix[pattern]        
        @w += delta_w - Matrix.I(@pattern_size)
    end
    
    def recall(input_pattern, iteration_sequence)
        old_output = [].fill(rand, 0, @pattern_size)
        new_output = input_pattern
        
        while true
            iteration_sequence.each do |iter|
                net = input_pattern[iter] + Vector[*input_pattern].inner_product(@w.column(iter))
                new_output[iter] = af(net, new_output[iter])
                print "#{iter+1} : "
                pp new_output
            end
            puts
            if old_output == new_output
                @output_pattern = new_output
                break
            else
                old_output = new_output
            end
        end
    end
    
    private
    def af(x, net)
        if x > 0
            +1
        elsif x == 0
            net
        else
            -1
        end
    end
end

x = [ [+1, +1, -1, -1], [-1, -1, +1, +1] ]

net = Hopfield.new(4)

x.each do |i|
    net.learn i
end

puts "sequence [2, 1, 4, 3]"
net.recall [+1, -1, -1, -1], [1, 0, 3, 2]
puts "sequence [4, 1, 3, 2]"
net.recall [+1, -1, -1, -1], [3, 0, 2, 1]


Output:
sequence [2, 1, 4, 3]
2 : [1, 1, -1, -1]
1 : [1, 1, -1, -1]
4 : [1, 1, -1, -1]
3 : [1, 1, -1, -1]

2 : [1, 1, -1, -1]
1 : [1, 1, -1, -1]
4 : [1, 1, -1, -1]
3 : [1, 1, -1, -1]

sequence [4, 1, 3, 2]
4 : [1, -1, -1, -1]
1 : [1, -1, -1, -1]
3 : [1, -1, -1, -1]
2 : [1, 1, -1, -1]

4 : [1, 1, -1, -1]
1 : [1, 1, -1, -1]
3 : [1, 1, -1, -1]
2 : [1, 1, -1, -1]


저작자 표시 비영리 동일 조건 변경 허락

댓글을 달아 주세요

  1. Favicon of http://www.filepang.co.kr BlogIcon DMW 2009/02/19 13:33  댓글주소  수정/삭제  댓글쓰기

    지금보니까 좀 이상하네....하지만 귀차느니까 고치진 않는다능. recall 메소드에서
    new_output = input_pattern 를 new_output = input_pattern.clone 로
    net = input_pattern[iter] + Vector[*input_pattern].inner_product(@w.column(iter)) 를
    net = new_output[iter] + Vector[*new_output].inner_product(@w.column(iter)) 로 바꿔야 될꺼임

  2. Favicon of http://marocchino.tistory.com BlogIcon progr_ 2009/02/22 19:10  댓글주소  수정/삭제  댓글쓰기

    이론을 보르니 입력 * 결과가 무슨 의미인지 모르겠다능 ..;ㅅ; 어흐흐흐 늅늅.