使用演算法原理
㈠ LRU綆楁硶鐨勫師鐞嗕笌瀹炵幇
LRU鏄疞east Recently Used鐨勭緝鍐欙紝鍗蟲渶榪戞渶灝戜嬌鐢ㄧ畻娉曪紝搴旂敤闈㈤潪甯哥殑騫挎硾錛屾瘮濡俽edis褰撲腑鐨勫唴瀛樻窐奼扮瓥鐣ャ傚洜涓鴻$畻鏈虹殑鍐呭瓨閮芥槸鏈夐檺鐨勶紝褰撶敤鎴瘋塊棶鐨勬暟鎹濡傛灉瀛樺湪鍐呭瓨褰撲腑鐩存帴榪斿洖鐨勭粰鐢ㄦ埛鐨勮瘽錛屾晥鐜囦細闈炲父蹇錛屼絾鏄濡傛灉鍐呭瓨涓嶅瓨鍦錛屽湪鍘葷佺洏閲岄潰鏌ユ壘鐨勶紝鏁堢巼浼氬ぇ鎵撴姌鎵c傛墍浠ユ垜浠甯屾湜鍦ㄦ湁闄愮殑鍐呭瓨絀洪棿褰撲腑錛屽氬瓨鏀劇偣鐑鐐規暟鎹錛岀敤鎴蜂笉緇忓父璁塊棶鐨勬暟鎹錛屽敖閲忔窐奼版帀錛岄伩鍏嶅崰鐢ㄥ唴瀛樼┖闂淬
浣跨敤鍙屽悜閾捐〃鏉ュ疄鐜癓RU 榪欑瘒鏂囩珷宸茬粡鐢ㄥ弻鍚戦摼琛ㄦ潵瀹炵幇榪嘗RU綆楁硶浜嗭紝浣嗘槸鍩轟簬鍙屽悜閾捐〃鐨勭壒鎬э紝浣垮緱璇ョ畻娉曠殑鏃墮棿澶嶆潅搴︿負O(n)錛屾樉鐒朵笉鏄鏈浼樼殑綆楁硶錛岄偅涔堟湁娌℃湁綆楁硶錛屽彲浠ヨ揪鍒癘(1)錛屽綋鐒舵槸鏈夌殑錛屾棭鏃╃殑璁$畻鏈虹戝﹀跺凡緇忔兂鍒幫紝騫朵笖宸茬粡瀹炵幇浜嗐
鍦ㄧ瑪鑰呬粙緇嶆帴涓嬫潵鐨勫唴瀹規椂錛岃繕鏄甯屾湜鍏堜簡瑙d竴涓嬩袱綃囧崥鏂囷細
涓銆 鍥捐ВHashMap鍘熺悊
浜屻 鍥捐ВLinkedHashMap
涔嬪墠浣跨敤鍙屽悜閾捐〃鍘誨疄鐜癓RU綆楁硶鏃訛紝鏃墮棿澶嶆潅搴︽病鏈夎揪鍒癘(1)錛屼富瑕佸師鍥犲湪浜庨亶鍘嗙粨鐐規椂錛屽甫鏉ョ殑鏃墮棿寮閿錛岄偅涔堟崲鍙ヨ瘽璇達紝瑕佸疄鐜伴亶鍘嗙粨鐐規椂錛屾椂闂村嶆潅搴︿負O(1)錛岀涓鏃墮棿鎯沖埌鐨勫簲璇ユ槸hash鏁扮粍錛屼絾鏄痟ash綆楁硶鍙鑳戒細瀛樺湪涓嶅悓鐨刱ey鍊礆紝浜х敓鐩稿悓鐨刪ash鍊礆紝閭d箞鍙浠ュ皢涓嶅悓key錛屼絾鏄鐩稿悓hash鍊肩殑緇撶偣錛屼互鍗曢摼琛ㄧ殑褰㈠紡瀛樻斁銆傝繖鏍蜂粎浠呮槸瀹炵幇浜嗗瓨鍙栨椂闂村嶆潅搴︿負O(1)錛屽備綍瀹炵幇鏁版嵁鑳藉熸寜璁塊棶欏哄簭瀛樻斁鍛錛熷苟涓斿炲垹鐨勬椂闂村嶆潅搴︿負O(1)錛岃繖涓鍙浠ヤ嬌鐢ㄥ弻鍚戦摼琛ㄦ潵瀹炵幇錛屾墍浠ョ患鍚堟潵璁詫紝灝辨槸瀹炵幇鏁e垪鏁扮粍+鍙屽悜閾捐〃鏉ヤ嬌鐢↙RU錛屽彲浠ヨ揪鍒版椂闂村嶆潅搴︿負O(1)銆
閫昏緫瑙嗗浘濡備笅:
鍜嬩竴鐪嬭繖涓鍥句貢鐨勫緢錛岀◢寰瑙i噴涓涓嬶紝濡傛灉鎰熻夌悊瑙d笂鏈夌偣鍥伴毦錛屽彲浠ュ厛鍘諱簡瑙d竴涓嬩箣鍓嶆帹鑽愮殑涓ょ瘒鍗氭枃錛岄偅閲屼細浠嬬粛鐨勬洿鍔犺︾粏涓鐐廣
1.鏈宸︿晶鍏跺疄灝辨槸涓涓鏅閫氱殑鏁扮粍錛屾暟緇勭殑澶у皬蹇呴』鏄2鐨勫嶆暟錛岃繖涓鍘熷洜鏄浠涔堝憿錛熷洜涓鴻繖涓鏁扮粍鐨勫瓨鏀炬柟寮忔槸鏁e垪鐨勶紝鎰忔濆氨鏄闇瑕乲ey.hashcode & (length -1)鎵嶈兘寰楀嚭瀛樻斁浣嶇疆鐨勬柟寮忥紝hash鐨勫ソ澶勬槸鍙浠ユ牴鎹甼ey鍊礆紝鍦ㄦ椂闂村嶆潅搴︿負O(1)鐨勫墠鎻愭壘鍒板瑰簲鐨勫瓨鏀句綅緗錛岃繖涔熸槸鎴戜滑鐨勫垵琛鳳紝璇村埌榪欓噷鍏跺疄榪樻病鏈夎В閲婁負浠涔堜竴瀹氳佹槸2鐨勫嶆暟錛屽洜涓2鐨勫嶆暟-1錛岃繖涓鏁扮殑浜岃繘鍒訛紝涓瀹氬叏鏄1錛屾瘮濡16-1=15錛屼簩榪涘埗琛ㄧず灝辨槸1111錛&榪愮畻絎﹀叾瀹炲氨鏄灝嗗煎叏閮ㄥ寲鎴愪簩榪涘埗閫愪綅涓庯紝姣斿10111011 & 1111 = 1011 = 11錛屼絾鏄濡傛灉涓嶆槸2鐨勫嶆暟錛屾瘮濡7-1=6錛屽寲鎴愪簩榪涘埗灝辨槸0110錛岀敱浜庢湯浣嶆槸0錛屼笉綆′粈涔堜簩榪涘埗鍊間笌0110鍋&榪愮畻錛屼竴瀹氭槸鍋舵暟錛岃繖鏍蜂細瀵艱嚧鏁e垪鍒嗗竷涓嶅潎鍖銆
2.涓嶅悓key鍊礆紝鐩稿悓hash鍊礆紝濡備綍瀛樻斁鍛錛熺浉鍚岀殑hash鍊煎仛涓庤繍綆椾竴瀹氳兘澶熷緱鍒扮浉鍚岀殑鏁扮粍鑴氭爣錛岃繖浜涚粨鐐癸紝浠ュ崟閾捐〃鐨勫艦寮忓瓨鍦錛屽氨鏄鍥句腑鏁扮粍鍙充晶鐨勫崟閾捐〃銆
3.濡備綍瀹炵幇鎸夎塊棶欏哄簭錛熶笂鍥鵑櫎鍘繪暟緇勫拰鎸傚湪鏁扮粍鍙充晶鐨勫崟閾捐〃錛岃繕鏈夌豢鑹插拰榛勮壊鐨勫崟鍚戠澶達紝鍦ㄥ彸涓婅掕繕鏈変竴涓鍙屽悜閾捐〃鐨勫ご鎸囬拡銆傚叾瀹炶繖浜涚澶村氨鏄緇存姢涓嶅悓緇撶偣鐨勮塊棶欏哄簭錛屽嵆鍙屽悜閾捐〃銆
鎬諱笂鎵榪幫紝榪欑嶆暟鎹緇撴瀯瀹氫箟鐨勭粨鏋勪綋濡備笅錛
class Node{
Object key; //瀛樻斁key鍊礆紝鐢ㄤ簬璁$畻瀛樻斁鏁扮粍鑴氭爣浣嶇疆
Object value;//瀛樻斁鍏冪礌鍊
int hash;//瀛樻斁key.hashcode
Node next;//緇存姢鍗曢摼琛ㄩ『搴
Node before;//緇存姢鍙屽悜閾捐〃欏哄簭
Node after;
}
絎旇呯敤java瀹炵幇濡備笅錛屾劅鍏磋叮鍙浠ョ敤鑷宸卞枩嬈㈢殑璇璦鍘誨疄鐜頒竴閬嶏紝鍔犳繁鐞嗚В錛
鍏跺疄浠ヤ笂瀹炵幇搴曞眰鍘熺悊灝辨槸LinkedHashMap鐨勫疄鐜板師鐞嗭紝鍙涓嶈繃絎旇呭仛浜嗕竴浜涚畝鍖栵紝鍘繪帀浜嗙箒鐞愮殑緇ф壙錛屾墿瀹圭瓑錛岀獊鍑轟簡綆楁硶鏍稿績錛屽傛灉璇昏呮劅鍏磋叮涔熷彲浠ュ幓鐮旂┒涓涓婰inkedHashMap鐨勬簮鐮併
浣跨敤LinkedHashMap鏉ュ疄鐜癓RU綆楁硶錛
鐪嬭搗鏉ユ槸涓嶆槸綆鍗曚簡寰堝氾紝鍥犱負LinkedHashMap搴曞眰宸茬粡灝佽呭ソ浜嗭紝鎴戜滑鐩存帴璋冪敤灝卞ソ錛屼絾鏄浣滀負涓涓鎯寵佸彉浼樼鐨勭爜鍐滐紝涓瀹氳佺煡鍏剁劧鐭ュ叾鎵浠ョ劧銆
浣跨敤鏁e垪+鍙屽悜閾捐〃鐨勬柟寮忔槸濡備綍瀹炵幇O(1)澶嶆潅搴︾殑錛熷湪瀹炵幇LRU綆楁硶榪囩▼涓錛屾棤闈炰袱縐嶆搷浣滐紝鏌ユ壘鍜屼慨鏀癸紝浣跨敤鏁e垪鏁扮粍瀹炵幇鏌ユ壘鏃墮棿澶嶆潅搴︿負O(1)錛屼嬌鐢ㄥ弻鍚戦摼琛ㄥ疄鐜頒慨鏀瑰嶆潅搴︿負O(1)錛屽苟涓斿弻鍚戦摼琛ㄨ繕鍙浠ョ淮鎶よ塊棶欏哄簭錛屾墍浠ヤ嬌鐢ㄨ繖縐嶆柟寮忥紝鍙浠ヨ揪鍒癘(1)銆
㈡ 古典密碼學常用的技術和主要的密碼演算法原理
古典密碼技術根據其基本原理大體可以分為兩類:替換密碼技術和換位密碼技術。
古典密碼是密碼學中的其中一個類型,其大部分加密方式都是利用替換式密碼或移項式密碼,有時則是兩者的混合。其於歷史中經常使用,但在現代由於計算機的出現,使得古典密碼解密已經不再困難,已經很少使用,大部分的已經不再使用了。
利用一個密鑰字來構造替換作為密鑰,先將密鑰字作為首段密文,然後將之後未在字母表中出現過的字母依次寫在此密鑰字之後,構造出一個字母替換表。當密文為英文單詞時,最多可以有26!個不同的替換表(包括恆等變換)。
仿射密碼技術:
即結合乘法密碼技術和移位密碼技術。
它的加密函數是 e(x)=ax+b,其中a和 m互質,m是字母的數目。
解碼函數是 d(x)=i*(x-b)mod m,其中 i 是 a 的乘法逆元。
當a=0時,仿射密碼技術退化為移位替換密碼技術。
當b=0時,仿射密碼技術退化為乘法密碼技術。
㈢ 一文徹底搞懂BP演算法:原理推導+數據演示+項目實戰(上篇)
反向傳播演算法(Backpropagation Algorithm,簡稱BP演算法)是深度學習的重要思想基礎,對於初學者來說也是必須要掌握的基礎知識!本文希望以一個清晰的脈絡和詳細的說明,來讓讀者徹底明白BP演算法的原理和計算過程。
全文分為上下兩篇,上篇主要介紹BP演算法的原理(即公式的推導),介紹完原理之後,我們會將一些具體的數據帶入一個簡單的三層神經網路中,去完整的體驗一遍BP演算法的計算過程;下篇是一個項目實戰,我們將帶著讀者一起親手實現一個BP神經網路(不使用任何第三方的深度學習框架)來解決一個具體的問題。
圖 1 所示是一個簡單的三層(兩個隱藏層,一個輸出層)神經網路結構,假設我們使用這個神經網路來解決二分類問題,我們給這個網路一個輸入樣本 ,通過前向運算得到輸出 。輸出值 的值域為 ,例如 的值越接近0,代表該樣本是"0"類的可能性越大,反之是"1"類的可能性大。
為了便於理解後續的內容,我們需要先搞清楚前向傳播的計算過程,以圖1所示的內容為例:
輸入的樣本為:
第一層網路的參數為:
第二層網路的參數為:
第三層網路的參數為:
第一層隱藏層有三個神經元: 、 和 。該層的輸入為:
以 神經元為例,則其輸入為:
同理有:
假設我們選擇函數 作為該層的激活函數(圖1中的激活函數都標了一個下標,一般情況下,同一層的激活函數都是一樣的,不同層可以選擇不同的激活函數),那麼該層的輸出為: 、 和 。
第二層隱藏層有兩個神經元: 和 。該層的輸入為:
即第二層的輸入是第一層的輸出乘以第二層的權重,再加上第二層的偏置。因此得到和的輸入分別為:
該層的輸出分別為: 和 。
輸出層只有一個神經元 :。該層的輸入為:
即:
因為該網路要解決的是一個二分類問題,所以輸出層的激活函數也可以使用一個Sigmoid型函數,神經網路最後的輸出為: 。
在1.1節里,我們已經了解了數據沿著神經網路前向傳播的過程,這一節我們來介紹更重要的反向傳播的計算過程。假設我們使用隨機梯度下降的方式來學習神經網路的參數,損失函數定義為 ,其中 是該樣本的真實類標。使用梯度下降進行參數的學習,我們必須計算出損失函數關於神經網路中各層參數(權重 和偏置 )的偏導數。
假設我們要對第 層隱藏層的參數 和 求偏導數,即求 和 。假設 代表第 層神經元的輸入,即 ,其中 為前一層神經元的輸出,則根據鏈式法則有:
因此,我們只需要計算偏導數 、 和 。
前面說過,第k層神經元的輸入為: ,因此可以得到:
上式中, 代表第 層神經元的權重矩陣 的第 行, 代表第 層神經元的權重矩陣 的第 行中的第 列。
我們以1.1節中的簡單神經網路為例,假設我們要計算第一層隱藏層的神經元關於權重矩陣的導數,則有:
因為偏置b是一個常數項,因此偏導數的計算也很簡單:
依然以第一層隱藏層的神經元為例,則有:
偏導數 又稱為 誤差項(error term,也稱為「靈敏度」) ,一般用 表示,例如 是第一層神經元的誤差項,其值的大小代表了第一層神經元對於最終總誤差的影響大小。
根據第一節的前向計算,我們知道第 層的輸入與第 層的輸出之間的關系為:
又因為 ,根據鏈式法則,我們可以得到 為:
由上式我們可以看到,第 層神經元的誤差項 是由第 層的誤差項乘以第 層的權重,再乘以第 層激活函數的導數(梯度)得到的。這就是誤差的反向傳播。
現在我們已經計算出了偏導數 、 和 ,則 和 可分別表示為:
下面是基於隨機梯度下降更新參數的反向傳播演算法:
單純的公式推導看起來有些枯燥,下面我們將實際的數據帶入圖1所示的神經網路中,完整的計算一遍。
我們依然使用如圖5所示的簡單的神經網路,其中所有參數的初始值如下:
輸入的樣本為(假設其真實類標為"1"):
第一層網路的參數為:
第二層網路的參數為:
第三層網路的參數為:
假設所有的激活函數均為Logistic函數: 。使用均方誤差函數作為損失函數:
為了方便求導,我們將損失函數簡化為:
我們首先初始化神經網路的參數,計算第一層神經元:
上圖中我們計算出了第一層隱藏層的第一個神經元的輸入 和輸出 ,同理可以計算第二個和第三個神經元的輸入和輸出:
接下來是第二層隱藏層的計算,首先我們計算第二層的第一個神經元的輸入z₄和輸出f₄(z₄):
同樣方法可以計算該層的第二個神經元的輸入 和輸出 :
最後計算輸出層的輸入 和輸出 :
首先計算輸出層的誤差項 ,我們的誤差函數為 ,由於該樣本的類標為「1」,而預測值為 ,因此誤差為 ,輸出層的誤差項為:
接著計算第二層隱藏層的誤差項,根據誤差項的計算公式有:
最後是計算第一層隱藏層的誤差項:
㈣ 深入淺出BP神經網路演算法的原理
深入淺出BP神經網路演算法的原理
相信每位剛接觸神經網路的時候都會先碰到BP演算法的問題,如何形象快速地理解BP神經網路就是我們學習的高級樂趣了(畫外音:樂趣?你在跟我談樂趣?)
本篇博文就是要簡單粗暴地幫助各位童鞋快速入門採取BP演算法的神經網路。
BP神經網路是怎樣的一種定義?看這句話:一種按「誤差逆傳播演算法訓練」的多層前饋網路。
BP的思想就是:利用輸出後的誤差來估計輸出層前一層的誤差,再用這層誤差來估計更前一層誤差,如此獲取所有各層誤差估計。這里的誤差估計可以理解為某種偏導數,我們就是根據這種偏導數來調整各層的連接權值,再用調整後的連接權值重新計算輸出誤差。直到輸出的誤差達到符合的要求或者迭代次數溢出設定值。
說來說去,「誤差」這個詞說的很多嘛,說明這個演算法是不是跟誤差有很大的關系?
沒錯,BP的傳播對象就是「誤差」,傳播目的就是得到所有層的估計誤差。
它的學習規則是:使用最速下降法,通過反向傳播(就是一層一層往前傳)不斷調整網路的權值和閾值,最後使全局誤差系數最小。
它的學習本質就是:對各連接權值的動態調整。
拓撲結構如上圖:輸入層(input),隱藏層(hide layer),輸出層(output)
BP網路的優勢就是能學習和儲存大量的輸入輸出的關系,而不用事先指出這種數學關系。那麼它是如何學習的?
BP利用處處可導的激活函數來描述該層輸入與該層輸出的關系,常用S型函數δ來當作激活函數。
我們現在開始有監督的BP神經網路學習演算法:
1、正向傳播得到輸出層誤差e
=>輸入層輸入樣本=>各隱藏層=>輸出層
2、判斷是否反向傳播
=>若輸出層誤差與期望不符=>反向傳播
3、誤差反向傳播
=>誤差在各層顯示=>修正各層單元的權值,直到誤差減少到可接受程度。
演算法闡述起來比較簡單,接下來通過數學公式來認識BP的真實面目。
假設我們的網路結構是一個含有N個神經元的輸入層,含有P個神經元的隱層,含有Q個神經元的輸出層。
這些變數分別如下:
認識好以上變數後,開始計算:
一、用(-1,1)內的隨機數初始化誤差函數,並設定精度ε,最多迭代次數M
二、隨機選取第k個輸入樣本及對應的期望輸出
重復以下步驟至誤差達到要求:
三、計算隱含層各神經元的輸入和輸出
四、計算誤差函數e對輸出層各神經元的偏導數,根據輸出層期望輸出和實際輸出以及輸出層輸入等參數計算。
五、計算誤差函數對隱藏層各神經元的偏導數,根據後一層(這里即輸出層)的靈敏度(稍後介紹靈敏度)δo(k),後一層連接權值w,以及該層的輸入值等參數計算
六、利用第四步中的偏導數來修正輸出層連接權值
七、利用第五步中的偏導數來修正隱藏層連接權值
八、計算全局誤差(m個樣本,q個類別)
比較具體的計算方法介紹好了,接下來用比較簡潔的數學公式來大致地概括這個過程,相信看完上述的詳細步驟都會有些了解和領悟。
假設我們的神經網路是這樣的,此時有兩個隱藏層。
我們先來理解靈敏度是什麼?
看下面一個公式:
這個公式是誤差對b的一個偏導數,這個b是怎麼?它是一個基,靈敏度δ就是誤差對基的變化率,也就是導數。
因為?u/?b=1,所以?E/?b=?E/?u=δ,也就是說bias基的靈敏度?E/?b=δ等於誤差E對一個節點全部輸入u的導數?E/?u。
也可以認為這里的靈敏度等於誤差E對該層輸入的導數,注意了,這里的輸入是上圖U級別的輸入,即已經完成層與層權值計算後的輸入。
每一個隱藏層第l層的靈敏度為:
這里的「?」表示每個元素相乘,不懂的可與上面詳細公式對比理解
而輸出層的靈敏度計算方法不同,為:
而最後的修正權值為靈敏度乘以該層的輸入值,注意了,這里的輸入可是未曾乘以權值的輸入,即上圖的Xi級別。
對於每一個權值(W)ij都有一個特定的學習率ηIj,由演算法學習完成。