熱的東西顯然會變涼。房間會會人沮喪地變得淩亂。幾乎同樣,訊息會失真。逆轉這些情況的短期策略分別是重新加熱、 做衛生和使用 Hopfield 網路。本文向您介紹了三者中的最後一個,它是一個只需要特定的參數就可以消除雜訊的演算法。net.py 是一個特別簡單的 Python 實現,將向您展示它的基本部分如何結合到一起,以及為何 Hopfield 網路有時可以自失真的圖案中 重新得到原圖案。儘管這個實現有局限性,不過仍然可以讓您獲得關於 Hopfield 網路的很多有益且有啟發作用的經驗。
您尋求的是什嗎?
我假定您是因為遇到了一些計算上的問題而來閱讀本文。有人向您建議,一些神經網路演算法可能會提供解決方案。具體說, 建議是說您可以使用一個 Hopfield 網路。我進一步假設您需要有一個大致的想法,以使得您可以決定那個建議是否切實 可行而且確保深入的研究。下面這個 Hopfield 網路的非常縮減的應用可能會引導您著手解決問題。
首先,您的問題有一組基本的用 -1 和 +1 編碼的圖案。如果需要,它們可以用 0 和 +1 編碼。這些圖案可以是郵票的規格化的 二進位圖案(參閱 參考資料)。下一個要素是偏離這一基礎的一組圖案。您尋求的是建立代碼,以 使得可以輸入不正常的圖案而輸出應得的一個基本圖案。因而您尋求的將是一個演算法,可以輸入一個對特定郵票的編碼描述,然後 輸出應得的一個基本郵票圖案。您搜尋不確定會成功。有可以接受的對您的計劃產生負面影響的失敗率。對您來說,會有一個不 會顯著地影響您的項目的郵票誤識別的比率。
如果這使您想起了您的問題,下面可能會是您的解決方案設計的開始。在結束之前,您最好應該能回答出基本的問題。 這個 Hopfield 是什嗎?它如何工作?它的局限性是什嗎?它可以為我做什嗎?我希望用更多的時間來研究它嗎?
圖案及其失真
讓我們首先來看將會失真而隨後被重新獲得的五個任意圖案。它們可以可視化地表示為 10 乘 10 的黑白方塊矩陣。圖 1 展示了第一個圖案,p1。
圖 1. p1 的可視化表示
點擊 net.py 中 p2到 p5 的任意一個,可以顯示其他的圖案。為了編碼,這五個圖案被初始描述為 Python 列表。 這樣,舉例來說,第一個圖案的描述見清單 1。
清單 1. 圖案 p1
p1 = [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [-1, -1, -1, -1, -1, -1, -1, -1, 1, 1], [-1, -1, -1, -1, -1, -1, -1, -1, 1, 1], [-1, -1, -1, -1, -1, -1, -1, -1, 1, 1], [-1, -1, -1, -1, -1, -1, -1, -1, 1, 1], [-1, -1, -1, -1, -1, -1, -1, -1, 1, 1], [-1, -1, -1, -1, -1, -1, -1, -1, 1, 1], [-1, -1, -1, -1, -1, -1, -1, -1, 1, 1], [-1, -1, -1, -1, -1, -1, -1, -1, 1, 1], [-1, -1, -1, -1, -1, -1, -1, -1, 1, 1] ]
黑色和白色的方塊分別對應於 -1 和 +1。這個列表隨後被轉化為一個數組。(請參閱 參考資料 ,獲得 我使用的 Python 庫的參考。)對應於這類圖案中的每一個元素,-1 或者 +1,在節點數組中都有一個節點對象。
一個節點對象有三個主要屬性:
- 一個節點對象有一個值,它是圖案中的一個元素。
- 一個節點還有一個地址,也就是在數組中它的地址。
- 每個節點還有一個顏色,以使得它可以顯示出來。
如前所述,Hopfield 的一個功能是消除雜訊。為實現這一功能,需要有一種方法來給圖案引入雜訊。點擊 Add Noise 恰好 可以完成此任務。向 p1 添加雜訊產生了圖 2。
圖 2. 失真的 p1
為了給一個圖案引入雜訊,Hopfield 要訪問節點數組中的每一個地址。然後它會在 [0,1) 中取一個隨機數,也就是 0 到 1 之間 包括 0 但不包括 1。如果數字小於某個固定的標準,網路就會改變節點的值和顏色,否則就會保持不變。預設情況下,這個標準設定 為 0.20,這樣任意給定的節點就有百分之二十的可能會改變其值和顏色。您可以用調節滑塊來改變這個機率。調為 0% 時,不會有雜訊, 調為 100% 時,節點數組會簡單地反轉。取這區間的值,會出現所有其他通常的可能。每個值都會給一個圖案引入特定程度的雜訊。由於 Hopfield 網路是一個消除雜訊的演算法,它可以輸入一個如圖 2 所示的失真的圖案,然後輸出圖 1 中的原始圖案。
儘管有時會因不合適的解釋而變得晦澀,相關的演算法實現起來還是相當簡單的。接下來,我將向您完整地介紹演算法的一個實現, 然後我將簡短解釋為什麼這些演算法可以消除雜訊。
權重
如 David Mertz 和我在以前的一篇 developerWorks 文章 An introduction to neural nets 中所述, 人類的大腦由大約 1 千億個神經元構成,平均每個神經元要串連到幾千個其他神經元。神經元既接收也發送不同的能量。 神經元的一個重要特性是,它們接收到能量後不會馬上反應。而是,它們積累所接收到的能量,只有當積累的能量達到一定臨界 極限時,它們才會向其他神經元發送自己的能量。
當大腦在學習時,可以認為它是在調整這些串連的數目和強度。毫無疑問,這是一個極其簡化的生物學事實。 在這個例子中,對於實現控制神經網路而言,簡化可以是實用的,尤其是當它們被作為模型來使用時。從生物學到演算法的轉換是通過 將串連轉化為權重來實現的。(感知器以一種不同的而且可能更為直觀的方式來使用權重。閱讀這裡之前,您可能會希望再讀一遍 An introduction to neural nets。)
權重對象主要封裝一個表示一個節點與另一個節點之間的權重的數值。權重對象還有一個地址和一個顏色。地址是它在權重數組中的位置。 顏色用於顯示。圖 3 是權重數組的一種可能的表示。Net.py(請參閱 參考資料 中的連結)保持了對最低和最高 權重的追蹤,它將權重顯示中顯示顏色數值的一個鍵。
圖 3. 權重數組的一種可視化表示
在權重數組的每一行上,是一個給定節點與所有其他節點間權重的一個列表。Hopfield 網路有兩種形式。一種形式的節點有一個到 自身的權重,另一種形式則沒有。通過 net.py 獲得的經驗表明,當節點不是自權重(self-weighted)時,節點數組不會總是重構到自身。 選擇 No Self Weight 選項,然後嘗試重構 p3 或 p5。有一百個節點,所以有一萬個通常冗餘的權重。預設情況下,當節點是 自權重時,就會有 5050 個非冗餘權重,否則就只有 4950 個。
圖 4. 權重的起源
清單 2. 權重產生演算法
PAT = { x: x is a RxC pattern }
WA = { x: x is a (R*C)x(R*C) weight array }
For all (i,j) and (a,b) in the range of R and C:
SUM = 0
for p in PAT:
SUM += p(i,j) * p(a,b)
WA( (R*i)+j, (C*a)+b ) = SUM
受生物學啟發的概念是 1949 年 Donald Hebb 研究所得的 Hopfield 網路的基礎。他假定如果一對節點同時向對方發送它們的能量, 那麼它們之間的權重就要大於只有一個發送自己的能量的情況。他寫道:“當細胞 A 的一個軸突距離 B 足夠近以至於能刺激它,而且 能反覆持久地參與對它的激發時,一個或者全部兩個細胞中就會發生一些成長過程或新陳代謝的變化,這樣,作為激發 B 的一個細胞, A 的功效就會增長”(參閱 參考資料 以獲得詳細資料)。就 Hopfield 網路來說,當一對節點有相同的 值時,換句話說是 -1 或 +1,它們之間的權重就更大。所有可能的節點對的值的乘積的和決定的權重數組的內容。當兩個值相同時,它們 的乘積就是正的,和就會增加。在不同的值的情況下,這個和就會減小。
更詳細地講,權重是哪裡來的?首先,Hopfield 網路必須可以訪問一個庫或者一組基本圖案。在這裡即 p1 到 p5。權重的產生首先由 Hopfield 網路在基本圖案矩陣的界限內選擇一對座標。然後它訪問每個圖案中的對應節點。在每一步,它將節點值的乘積添加到一個 正在使用的和。(見圖 4)。當網路訪問過每一個圖案後,它將一個權重對象的值設定為這個和。給出一對位於(i,j)和(a,b)的 節點,它會設定在權重數組中位於(i*10+j,a*10+b)的權重對象的值。
這就是權重如何構造的過程,不過,它如何作用於更大的 Hopfield 演算法?它如何作用於圖案的重構?
重構
如果在手邊有一個權重數組和一個失真的或有雜訊的圖案,Hopfield 網路有時可以輸出原始圖案。沒有保證,但是 網路正確次數的百分比高得驚人。它既可以同步完成,也可以非同步完成。
如果是非同步完成,網路會遍曆失真的圖案,在每一個節點 N,它會詢問 N 的值應該設定為 -1 還是 +1。
要確定這一設定,網路會去遍曆權重數組中包含 N 與其他節點間所有權重的的行。不要忘記,節點可能是也可能不是自權重的。
在第二次遍曆的每一步,它會計算出(1)N 與另一個節點之間的權重與(2)另一個節點的值的乘積。正如您所預料的,網路會 保持這些乘積的一個使用中的計數器。
現在,網路就可以做出判定。至少在當前的實現中,如果這個和小於 0,網路就將節點設定為 -1,如果它大於或等於 0,則網路將 節點的值設定為 +1。
圖 5. 重構:不遺留任何節點
清單 3. 重構
For every node, N, in pattern P.
SUM = 0
For every node, A, in P:
W = weight between N and A
V = value of A
SUM += W * V
if SUM < 0:
set N's value to -1
else:
set N's value to +1
預設的更新是非同步,因為網路只是在確定的這個值應該是什麼之後才去設定一個節點的值。如果網路在做出了所有判定 後再去設定節點的值,那麼它就可以是同步的。在這種情況下,它將儲存它的判定,然後在最後一個判定做出後更新數組的節點。 在 net.py(參見 參考資料)中,重構預設情況下非同步進行的,不過要注意 同步重構 的選項。
當您體驗 net.py,當重構成功時,Hopfield 網路的行為令人震驚。這種行為之一是,甚至當權重數組嚴重退化時,它仍可以 重構圖案。我的簡單實現的退化權重(Degrade Weights)會遍曆權重數組並隨機地將權重設定為 0。對權重數級的顯示給出了 破壞程度的一個視圖。在這裡,正確的重構說明 Hopfield 網路的容錯性遠超過大腦。它是如何工作的?數學的描述不會短。取而 代之的,這裡給出了一個結構簡介。
發生了什麼
Hopfield 網路的演算法細節說明了為什麼它有時可以消除雜訊。和通常演算法分析一樣,最麻煩的部分是數學細節。在當前的例子中,這些 是難以描繪和想像的。幸運的是,有一些密切相關的現象,可以使 Hopfield 網路的工作原理清楚明白地顯示出來。
當一個彈球掉入一個簡單曲面構成的碗中時,它會滾到最低點。碗的曲率就像是一個規則,輸入彈球的進入點,然後返回最低點, 即碗底。更為複雜的曲率將類似於一個函數,它輸入一個進入點並返回幾個局部最低點中的其中之一。
能量是這些簡單現象的一個基本部分。不管是在簡單的還是在複雜的例子中,進入的彈球都具有一定度量的能量。隨時間的過去, 這個能量會減少。它最終會達到一個穩定點,不能再變小。在複雜的例子中,可能會有一個更低的能量層級,但是彈球無法達到。
類似地,不管有沒有失真,一個圖案都可以被認為具有特定度量的能量。所以,圖案 p1 到 p5 有能量層級。
圖案能量層級
圖案的能量層級的計算並不複雜。Hopfield 網路計算每一個可能的節點對的值與它們之間權重的乘積。圖案的 能量層級是用負 2 去除這些乘積的和所得的結果。 Net.py 顯示了任意給定圖案或節點 數組的能量層級。當您重構圖案時,我認為並希望您將能夠看到圖案能量層級的下降。
在重構中,網路基於其他節點的值及它們之間的權重的乘積的和做出翻轉一個節點的判定。當和小於 0 時,節點設定為 -1,否則設定為 +1。當值與權重的乘積是正的時,它有助於促使和大於 0。不過這樣會將網路推向將節點值設定為 +1 的趨勢。當乘積是負的時,和被推進到或者小於 0。於是,網路被推向到將節點的設定為 -1 的趨勢。權重的變化 會引起度量的變化以及網路進行判定過程中被推向的趨勢的變化。圖案可能會失真很嚴重,導致網路不會被推向到做出 正確判定的趨勢。如果表述沒有問題,網路在絕大部分時候會被推向正確的趨勢。
如果您重構那五個圖案中的任意一個,您將發現每個圖案會重構到自身。它應該是這樣,因為每個圖案已經佔據了一個 局部最低能量的點。沒有重構過程可以再降低圖案的能量層級。如果您成功地重構了一個失真的圖案,Hopfield 就已經將 圖案的能量層級降到了某個圖案的層級。當失敗時,它是已經將失真圖案的能量層級降到了一個假的局部低點。在兩種情況下, 能量層級都不能再有任何降低。換句話說,它已經達到了一種穩定點。以能量的方式來描述 Hopfield 網路有著有趣而且 重要的意義。在此基礎之上,它可以以數學的方式建立起來,以使得重複應用重構演算法可以最終得到一個穩定的圖案。(參閱 參考資料以獲得詳細資料。)
結束語
您應該意識到 Hopfield 網路的局限性。一個經常被提及的明顯局限是,它的圖案必須可以被編碼為一個數組,這個數組或者由 -1 和 +1 構成,或者由 0 和 +1 構成。您已經知道,Hopfield 可能會穩定於一個假的局部低點。這個更為明顯的局限在於,當圖案 的數目超過節點數組中的節點數目的大約 14% 時,網路穩定於某個假的局部低點的機率會增加。也就是說,每增加一個基本圖案, 就必須多大約 7 個節點。儘管有這樣的局限性,但是,這裡所討論的圖案重構還是有可能成為解決您特定計算問題的直觀嚮導。 現在您已經大概瞭解了最初提及的 Hopfield 演算法。如果它能滿足您的需要,現在您已經明白了構建您自己的實現的上部構造。 這包括計算權重數組的演算法、重構失真圖案的方式以及計算圖案的能量層級的演算法。