反馈式神经网络之HNN
反饋式神經(jīng)網(wǎng)絡(luò)之HNN
神經(jīng)網(wǎng)絡(luò)
神經(jīng)網(wǎng)絡(luò)的簡介
人工神經(jīng)網(wǎng)絡(luò)(Artificial Neural Network,即ANN ),它從信息處理角度對人腦神經(jīng)元網(wǎng)絡(luò)進(jìn)行抽象, 建立某種簡單模型,按不同的連接方式組成不同的網(wǎng)絡(luò)。同時也直接簡稱為神經(jīng)網(wǎng)絡(luò)或類神經(jīng)網(wǎng)絡(luò)。神經(jīng)網(wǎng)絡(luò)是一種運(yùn)算模型,由大量的節(jié)點(diǎn)(或稱神經(jīng)元)之間相互聯(lián)接構(gòu)成。每個節(jié)點(diǎn)代表一種特定的輸出函數(shù),稱為激勵函數(shù)(activation function)。每兩個節(jié)點(diǎn)間的連接都代表一個對于通過該連接信號的加權(quán)值,稱之為權(quán)重,這相當(dāng)于人工神經(jīng)網(wǎng)絡(luò)的記憶。網(wǎng)絡(luò)的輸出則依網(wǎng)絡(luò)的連接方式,權(quán)重值和激勵函數(shù)的不同而不同。而網(wǎng)絡(luò)自身通常都是對自然界某種算法或者函數(shù)的逼近,也可能是對一種邏輯策略的表達(dá)。
神經(jīng)網(wǎng)絡(luò)的類型
人工神經(jīng)網(wǎng)絡(luò)模型主要考慮網(wǎng)絡(luò)連接的拓?fù)浣Y(jié)構(gòu)、神經(jīng)元的特征、學(xué)習(xí)規(guī)則等。所以我們根據(jù)連接的拓?fù)浣Y(jié)構(gòu),神經(jīng)網(wǎng)絡(luò)模型可以分為:
-
前向網(wǎng)絡(luò)
網(wǎng)絡(luò)中的各個神經(jīng)元(節(jié)點(diǎn))接收前一級的輸入,加權(quán)疊加后并輸入到下一級,網(wǎng)絡(luò)中沒有反饋,網(wǎng)絡(luò)的拓?fù)浣Y(jié)構(gòu)可以用一個有向無環(huán)圖表示。這種網(wǎng)絡(luò)實(shí)現(xiàn)信號從輸入空間到輸出空間的變換,它的信息處理能力來自于簡單非線性函數(shù)的多次復(fù)合。網(wǎng)絡(luò)結(jié)構(gòu)簡單,易于實(shí)現(xiàn)。反傳網(wǎng)絡(luò)(BP)是一種典型的前向網(wǎng)絡(luò)。如圖1所示:
-
反饋網(wǎng)絡(luò)
網(wǎng)絡(luò)內(nèi)神經(jīng)元間有反饋,可以用一個無向的完備圖表示。這種神經(jīng)網(wǎng)絡(luò)的信息處理是狀態(tài)的變換,可以用動力學(xué)系統(tǒng)理論處理。系統(tǒng)的穩(wěn)定性與聯(lián)想記憶功能有密切關(guān)系。Hopfield網(wǎng)絡(luò)(HNN)、波耳茲曼機(jī)均屬于這種類型。如圖2(HNN的拓?fù)浣Y(jié)構(gòu)圖)所示:
反饋式神經(jīng)網(wǎng)絡(luò)
反饋神經(jīng)網(wǎng)絡(luò)是一種反饋動力學(xué)系統(tǒng)。在這種網(wǎng)絡(luò)中,每個神經(jīng)元同時將自身的輸出信號作為輸入信號反饋給其他神經(jīng)元,它需要工作一段時間才能達(dá)到穩(wěn)定。
Hopfield神經(jīng)網(wǎng)絡(luò)(HNN)
美國加州理工學(xué)院物理學(xué)家J.J.Hopfield教授于1982年提出一種單層反饋神經(jīng)網(wǎng)絡(luò),后來人們將這種反饋網(wǎng)絡(luò)稱作Hopfield 網(wǎng)。Hopfield神經(jīng)網(wǎng)絡(luò)是(HNN)反饋網(wǎng)絡(luò)中最簡單且應(yīng)用廣泛的模型,它具有聯(lián)想記憶和解決快速尋優(yōu)問題的功能。
HNN的狀態(tài)
對于HNN中的每一個節(jié)點(diǎn)只有兩種狀態(tài):0 或者 1,代表閉或開,節(jié)點(diǎn)之間彼此互相連接,所有神經(jīng)元狀態(tài)的集合就構(gòu)成反饋網(wǎng)絡(luò)的狀態(tài),但是這種網(wǎng)絡(luò)是很難分析的,其可能的狀態(tài)有:
-
穩(wěn)定
-
震蕩
-
混沌
HNN的能量函數(shù)與吸引子
研究發(fā)現(xiàn)如果模型是對稱的,那么整個網(wǎng)絡(luò)就會存在一個全局能量函數(shù),系統(tǒng)能夠收斂到一個最低能量處。因此,我們研究的 Hopfield 網(wǎng)絡(luò)是一個對稱網(wǎng)絡(luò)。這里所謂的對稱即每個節(jié)點(diǎn)的輸出狀態(tài)都反饋回來作為除自身外每一個節(jié)點(diǎn)的輸入。
-
對于每一個神經(jīng)元,我們知道其輸入與輸出的關(guān)系為:
-
離散型(DHNN)與連續(xù)型(DHNN)
根據(jù)激勵函數(shù)的選取我們可以把神經(jīng)網(wǎng)絡(luò)定義成離散型與連續(xù)型:
DHNN: 作用函數(shù)為符號函數(shù),主要用于聯(lián)想記憶。
符號函數(shù)sgn(x):
CHNN:作用函數(shù)為S形函數(shù)(sigmoid),主要用于優(yōu)化計算。
sigmoid函數(shù)sigmoid(x):
-
DHNN
對于每個神經(jīng)元,其輸出狀態(tài)為:
穩(wěn)定點(diǎn)為:
-
DHNN的狀態(tài)變化
- 每一個神經(jīng)元有兩種狀態(tài)(0或1),所有對于N個節(jié)點(diǎn)的HNN有2的N次方個可能的狀態(tài),即整個網(wǎng)絡(luò)的狀態(tài)可以用一個包含0和1的向量表示。
- 節(jié)點(diǎn)的狀態(tài)更新包括三種情況:0—>1; 1—>0; 保持不變
- 按照單元異步更新方式,某一時刻網(wǎng)絡(luò)只有一個節(jié)點(diǎn)被選擇進(jìn)行狀態(tài)更新,當(dāng)該節(jié)點(diǎn)狀態(tài)變化時,網(wǎng)絡(luò)狀態(tài)就以一定概率轉(zhuǎn)移到另一狀態(tài);當(dāng)該節(jié)點(diǎn)保持時,網(wǎng)絡(luò)狀態(tài)的更新結(jié)果保持前一時刻的狀態(tài)。
因?yàn)槲覀冇脵?quán)值和閾值訓(xùn)練整個網(wǎng)絡(luò),所以,一旦給出確定的HNN權(quán)值和神經(jīng)元的閾值,網(wǎng)絡(luò)的狀態(tài)轉(zhuǎn)移序列就確定了,也就是網(wǎng)絡(luò)的狀態(tài)就確定了。
HNN的能量函數(shù)
按照能量變化為負(fù)的思路,可將定義節(jié)點(diǎn)i的能量為:
所以對于整個網(wǎng)絡(luò),其總能量為:
顯然E是對所有的Ei按照某種方式求和得到。因?yàn)殡x散HNN中,wij = wji (單層對稱網(wǎng)絡(luò)),如果直接計算E,將會對Ei中的每一項計算兩次。所以在前面有個1/2的因子。
對于能量函數(shù),我們可以改寫為:
定義兩個差值變量:
則可得出能量變化為:
我們假設(shè)t時刻,只有1個神經(jīng)元調(diào)整狀態(tài)(串行方式工作),假設(shè)神經(jīng)元為j,則此時:
帶入上式,得到:
因?yàn)樯窠?jīng)元不存在自反饋,所以wii為0,則最終能量變化為:
我們考慮:
因此能量E是不斷減少的。
吸引子
網(wǎng)絡(luò)達(dá)到穩(wěn)定時的狀態(tài)X,稱為網(wǎng)絡(luò)的吸引子。在上述推導(dǎo)中我們證明了網(wǎng)絡(luò)中的能量是逐漸減少的,通過能量變化公式可知,當(dāng)能量穩(wěn)定時(極小點(diǎn)),整個網(wǎng)絡(luò)的狀態(tài)也穩(wěn)定了。我們稱此時的狀態(tài)為網(wǎng)絡(luò)的吸引子,也就是說此時網(wǎng)絡(luò)具有了記憶的功能。如果將記憶的樣本信息存儲于不同的能量極小點(diǎn),當(dāng)輸入某一模式時,網(wǎng)絡(luò)就能實(shí)現(xiàn)“聯(lián)想記憶”與其相關(guān)的存儲樣本,實(shí)現(xiàn)聯(lián)想記憶。
權(quán)值的設(shè)計
通過上面的推導(dǎo),我們知道HNN主要是通過訓(xùn)練(或者確定)連接權(quán)和閾值就可以達(dá)到存儲序列的目的,在實(shí)際的過程中我們可令閾值為0,這樣一來我們只需要訓(xùn)練連接權(quán)就可達(dá)到記憶相應(yīng)的序列的目的。所以,我們下面的問題就是怎么去設(shè)計這個權(quán)值。
通常訓(xùn)練權(quán)值的方法有外積法、偽逆法、正交設(shè)計法等。下面講解了最常用的外積法(Hebb學(xué)習(xí)法則)。
Hebb學(xué)習(xí)法則
Hebb學(xué)習(xí)法則是一種比較簡單,在一定條件下行之有效的設(shè)計勸著的方法。當(dāng)神經(jīng)元輸入與輸出節(jié)點(diǎn)的狀態(tài)相同(即同時興奮或抑制)時,從第 j 個到第 i 個神經(jīng)元之間的連接強(qiáng)度則增強(qiáng),否則則減弱。海布(Hebb)法則是一種無指導(dǎo)的死記式學(xué)習(xí)算法。學(xué)習(xí)的目的:對具有 q 個不同的輸入樣本組X^k = [x1,x2,…,x^k],希望通過調(diào)節(jié)計算有限的權(quán)值矩陣 W,使得當(dāng)每一組輸入樣本 X^k,作為系統(tǒng)的初始值,經(jīng)過網(wǎng)絡(luò)循環(huán),系統(tǒng)能夠收斂到各自輸入樣本矢量本身。
-
求權(quán)矩陣
給定輸入, k = [1,2,3,…,m], I 為nxn的單位矩陣,則:
-
每一個神經(jīng)元的狀態(tài)
同時我們須知:x_ii = 0
根據(jù)上式,我們可以根據(jù)目的存儲序列設(shè)計出相應(yīng)的連接權(quán)。
HNN的實(shí)現(xiàn)
不管采取什么工作方式,基本運(yùn)行步驟是類似的,下面以串行工作方式為例。
HNN的實(shí)現(xiàn)流程
- 第一步:對網(wǎng)絡(luò)進(jìn)行初始化
- 第二步:使用Hebbo法則確定權(quán)值
- 第三步:進(jìn)行預(yù)測
訓(xùn)練集
zero = [0, 1, 1, 1, 0,1, 0, 0, 0, 1,1, 0, 0, 0, 1,1, 0, 0, 0, 1,1, 0, 0, 0, 1,0, 1, 1, 1, 0]one = [0, 1, 1, 0, 0,0, 0, 1, 0, 0,0, 0, 1, 0, 0,0, 0, 1, 0, 0,0, 0, 1, 0, 0,0, 0, 1, 0, 0]two = [1, 1, 1, 0, 0,0, 0, 0, 1, 0,0, 0, 0, 1, 0,0, 1, 1, 0, 0,1, 0, 0, 0, 0,1, 1, 1, 1, 1]
訓(xùn)練板塊
# Hopfield Class
class HOP(object):def __init__(self, N):# Bit Dimensionself.N = N# Weight Matrixself.W = np.zeros((N, N), dtype = floatType)# Calculate Kronecker Square Product of [factor] itself OR use np.kron()def kroneckerSquareProduct(self, factor):ksProduct = np.zeros((self.N, self.N), dtype=floatType)# Calculatefor i in range(0, self.N):ksProduct[i] = factor[i] * factorreturn ksProduct# Training a single stableState once a time, mainly to train [W]def trainOnce(self, inputArray):# Learn with normalizationmean = float(inputArray.sum()) / inputArray.shape[0]self.W = self.W + self.kroneckerSquareProduct(inputArray - mean) / (self.N * self.N) / mean / (1 - mean)# Erase diagonal self-weightindex = range(0, self.N)self.W[index, index] = 0.# Overall training functiondef hopTrain(self, stableStateList):# Preprocess List to Array typestableState = np.asarray(stableStateList, dtype=uintType)# Exceptionif np.amin(stableState) < 0 or np.amax(stableState) > 1:print('Vector Range ERROR!')return# Trainif len(stableState.shape) == 1 and stableState.shape[0] == self.N:print('stableState count: 1')self.trainOnce(stableState)elif len(stableState.shape) == 2 and stableState.shape[1] == self.N:print('stableState count: ' + str(stableState.shape[0]))for i in range(0, stableState.shape[0]):self.trainOnce(stableState[i])else:print('SS Dimension ERROR! Training Aborted.')returnprint('Hopfield Training Complete.')# Run HOP to outputdef hopRun(self, inputList):# Preprocess List to Array typeinputArray = np.asarray(inputList, dtype=floatType)# Exceptionif len(inputArray.shape) != 1 or inputArray.shape[0] != self.N:print('Input Dimension ERROR! Runing Aborted.')return# Runmatrix = np.tile(inputArray, (self.N, 1))matrix = self.W * matrix# print("matrix:",matrix.shape)outputArray = matrix.sum(1)# print("outputArray:",outputArray.shape)# Normalizem = float(np.amin(outputArray))M = float(np.amax(outputArray))outputArray = (outputArray - m) / (M - m)# Binary''' \SWITCH/ : 1/-1 OR 1/0outputArray[outputArray < 0.5] = -1.''' # \Division/outputArray[outputArray < 0.5] = 0.# ''' # \END/outputArray[outputArray > 0] = 1.return np.asarray(outputArray, dtype=uintType)# Reset HOP to initialized statedef hopReset(self):# Weight Matrix RESETself.W = np.zeros((self.N, self.N), dtype = floatType)
輸出格式定義
# Utility routine for printing the input vector: [NperGroup] numbers each piece
def printFormat(vector, NperGroup):string = ''for index in range(len(vector)):if index % NperGroup == 0:'''\SWITCH/ : Single-Row OR Multi-Rowstring += ' ''''# \Division/string += '\n'if str(vector[index]) == '0':string += ' 'elif str(vector[index]) == '1':string += '*'else:string += str(vector[index])string += '\n'print(string)
進(jìn)行測試
# DEMO of Hopfield Net
def HOP_demo():zero = [0, 1, 1, 1, 0,1, 0, 0, 0, 1,1, 0, 0, 0, 1,1, 0, 0, 0, 1,1, 0, 0, 0, 1,0, 1, 1, 1, 0]one = [0, 1, 1, 0, 0,0, 0, 1, 0, 0,0, 0, 1, 0, 0,0, 0, 1, 0, 0,0, 0, 1, 0, 0,0, 0, 1, 0, 0]two = [1, 1, 1, 0, 0,0, 0, 0, 1, 0,0, 0, 0, 1, 0,0, 1, 1, 0, 0,1, 0, 0, 0, 0,1, 1, 1, 1, 1]hop = HOP(5 * 6)hop.hopTrain([zero, one, two])half_zero = [0, 1, 1, 1, 0,1, 0, 0, 0, 1,1, 0, 0, 0, 1,0, 0, 0, 0, 0,0, 0, 0, 0, 0,0, 0, 0, 0, 0]print('Half-Zero:')printFormat(half_zero, 5)result = hop.hopRun(half_zero)print('Recovered:')printFormat(result, 5)half_two = [0, 0, 0, 0, 0,0, 0, 0, 0, 0,0, 0, 0, 0, 0,0, 1, 1, 0, 0,1, 0, 0, 0, 0,1, 1, 1, 1, 1]print('Half-Two:')printFormat(half_two, 5)result = hop.hopRun(half_two)print('Recovered:')printFormat(result, 5)half_two = [1, 1, 1, 0, 0,0, 0, 0, 1, 0,0, 0, 0, 1, 0,0, 0, 0, 0, 0,0, 0, 0, 0, 0,0, 0, 0, 0, 0]print('Another Half-Two:')printFormat(half_two, 5)result = hop.hopRun(half_two)print('Recovered:')printFormat(result, 5)
入口程序
if __name__ == '__main__':start = time.clock()HOP_demo()end = time.clock()print("time: ", end-start)
輸出結(jié)果
stableState count: 3
Hopfield Training Complete.
Half-Zero:***
* *
* *Recovered:***
* *
* *
* *
* **** Half-Two:**
*
*****Recovered:*** * * **
*
*****Another Half-Two:*** * * Recovered:*** * * **
*
*****time: 0.02231466803018272
附錄
參考文檔
Hopfield 網(wǎng)絡(luò)
Hopfield 網(wǎng)絡(luò)(上)
Hopfield 網(wǎng)絡(luò)(下)
Hopfield神經(jīng)網(wǎng)絡(luò)詳解
【Python】改進(jìn)Hopfield網(wǎng)絡(luò)代碼實(shí)現(xiàn)
一種設(shè)計離散型Hopfield神經(jīng)網(wǎng)絡(luò)權(quán)值的新方法
總結(jié)
以上是生活随笔為你收集整理的反馈式神经网络之HNN的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 坚定修谱的4大原则!专家:缺少一个都可能
- 下一篇: TimeUnit类详解及其常见用法(详解