リカレントネットワークによる記憶画像の想起
こんばんは.
今日は課題で作ったリカレントネットワークによる記憶画像の想起スクリプトを載せます.画像ファイルはPBM形式のものを扱ってます.課題用なのでかなり課題に特化したものなので,特にファイル操作部分に関しては各自変更が必要でしょう.
import numpy as np import random as rnd import copy def sgn(num): return (1 if(num > 0.0) else (0 if(num == 0.0) else -1)) class AssociativeMemory: def __init__(self, patternNum=1): self.__patternNum = patternNum self.__pattern = [] #ファイル操作 tmpArray = [] lineNum = 0 for line in open('ファイル名','r'): if lineNum >= 2: line.rstrip('\n') for charNum in xrange(len(line)): if ((line[charNum] == "1") or (line[charNum] == "0")): tmpArray.append(1.0 if (int(line[charNum]) == 1) else -1.0) lineNum = lineNum + 1 self.__size = len(tmpArray) self.__lena = np.array(tmpArray) self.__pattern.append(self.__lena) #直交する記憶パターンの生成 for k in xrange(self.__patternNum): tmpNDArray = np.zeros(self.__size) for i in xrange(self.__size): tmpNDArray[i] = (1.0 if(rnd.random() > 0.5) else -1.0) self.__pattern.append(tmpNDArray) #重みの計算 self.__weight = np.zeros((self.__size, self.__size)) for i in xrange(self.__size): for j in xrange(i, self.__size): if i != j : for p in xrange(len(self.__pattern)): self.__weight[i][j] = self.__weight[i][j] + self.__pattern[p][i] * self.__pattern[p][j] self.__weight[i][j] = self.__weight[i][j] / (self.__size) self.__weight[j][i] = self.__weight[i][j] else: self.__weight[i][j] = 0.0 self.__weight[j][i] = 0.0 def recall(self, noiseRate = 0.0, step = 15): state = copy.deepcopy(self.__lena) self.__m = [] #原画像にノイズを加えてそれを初期状態とする for i in xrange(len(state)): if noiseRate > 0.0: state[i] = (state[i] if(rnd.random() > noiseRate)\ else (1.0 if(state[i] == -1)\ else -1.0)) #初期の誤差を計算 prodResult = np.dot(state, self.__lena.T) self.__m.append(prodResult / (self.__size)) for t in xrange(step): nextState = np.zeros(self.__size) #想起 for i in xrange(self.__size): prodResult = np.dot(self.__weight[i], state.T) nextState[i] = sgn(prodResult) #時刻tにおける誤差 prodResult = np.dot(nextState, self.__lena.T) self.__m.append(prodResult / (self.__size)) state = copy.deepcopy(nextState) return self.__m
ドライバはこんな感じ
#!/opt/local/bin/ python # -*- coding: utf-8 -*- import AssociativeMemory test = AssociativeMemory.AssociativeMemory(2)#パターン数を自然数で print test.recall(0.4)#入力画像として原画像にどれだけノイズを混ぜるかを指定(最高1.0)
こんな感じです.できるだけ計算量を削減させようと工夫したけど,結局,かなり遅いです.重みは対称行列なことを利用したりしたんですが,一番時間かかるのは重みの計算です.見通しを立てて,ループ削減が難しそうならC++でやる方がいいよね.
追記があります.次の記事を参照すると幸せになれます.