當前位置:首頁 » 操作系統 » bf演算法D

bf演算法D

發布時間: 2023-04-22 01:12:13

A. kmp演算法什麼意思

KMP演算法之所以叫做KMP演算法是因為這個演算法是由三個人共同提出來的,就取三個人名字的首字母作為該演算法的名字。其實KMP演算法與BF演算法的區別就在於KMP演算法巧妙的消除了指針i的回溯問題,只需確定下次匹配j的位置即可,使得問題的復雜度由O(mn)下降到O(m+n)。
在KMP演算法中,為了確定在匹配不成功時,下次匹配時j的位置,引入了next[]數組,next[j]的值表示P[0...j-1]中最長後綴的長度等於相同字元序列的前綴。
對於next[]數組的定義如下:
1) next[j] = -1 j = 0
2) next[j] = max(k): 0<k<j P[0...k-1]=P[j-k,j-1]
3) next[j] = 0 其他
如:
P a b a b a
j 0 1 2 3 4
next -1 0 0 1 2
即next[j]=k>0時,表示P[0...k-1]=P[j-k,j-1]
因此KMP演算法的思想就是:在匹配過程稱,若發生不匹配的情況,如果next[j]>=0,則目標串的指針i不變,將模式串的指針j移動到next[j]的位置繼續進行匹配;若next[j]=-1,則將i右移1位,並將j置0,繼續進行比較。

B. 【演算法筆記】字元串匹配

BF 演算法中的 BF 是 Brute Force 的縮寫,中文叫作暴力匹配演算法,也叫樸素匹配演算法:

主串和模式串:
在字元串 A 中查找字元串 B,那字元串 A 就是主串,字元串 B 就是模式串。我們把主串的長度記作 n,模式串的長度記作 m

我們在主串中,檢查起始位置分別是 0、1、2…n-m 且長度為 m 的 n-m+1 個子串,看有沒有跟模式串匹配的。

BF 演算法的時間復雜度是 O(n*m)

等價於

比如匹配Google 和Goo 是最好時間復雜度,匹配Google 和ble是匹配失敗的最好時間復雜度。

KMP演算法是一種改進的字元串匹配演算法,由D.E.Knuth與J.H.Morris和V.R.Pratt同時發現,因此人們稱它為克努特—莫里斯—普拉特演算法。KMP演算法主要分為兩個步驟:字元串的自我匹配,目標串和模式串之間的匹配。

看來網上很多的文章,感覺很多的都沒有說清楚,這里直接復制阮一峰的內容,講的很清晰
內容來自 http://www.ruanyifeng.com/blog/

首先,字元串"BBC ABCDAB ABCDABCDABDE"的第一個字元與搜索詞"ABCDABD"的第一個字元,進行比較。因為B與A不匹配,所以搜索詞後移一位。

因為B與A不匹配,搜索詞再往後移。

就這樣,直到字元串有一個字元,與搜索詞的第一個字元相同為止。

接著比較字元串和搜索詞的下一個字元,還是相同。

直到字元串有一個字元,與搜索詞對應的字元不相同為止。

這時,最自然的反應是,將搜索詞整個後移一位,再從頭逐個比較。這樣做雖然可行,但是效率很差,因為你要把"搜索位置"移到已經比較過的位置,重比一遍。

一個基本事實是,當空格與D不匹配時,你其實知道前面六個字元是"ABCDAB"。KMP演算法的想法是,設法利用這個已知信息,不要把"搜索位置"移回已經比較過的位置,繼續把它向後移,這樣就提高了效率。

怎麼做到這一點呢?可以針對搜索詞,算出一張《部分匹配表》(Partial Match Table)。這張表是如何產生的,後面再介紹,這里只要會用就可以了。

已知空格與D不匹配時,前面六個字元"ABCDAB"是匹配的。查表可知,最後一個匹配字元B對應的"部分匹配值"為2,因此按照下面的公式算出向後移動的位數:

因為 6 - 2 等於4,所以將搜索詞向後移動4位。

因為空格與C不匹配,搜索詞還要繼續往後移。這時,已匹配的字元數為2("AB"),對應的"部分匹配值"為0。所以,移動位數 = 2 - 0,結果為 2,於是將搜索詞向後移2位。

因為空格與A不匹配,繼續後移一位。

逐位比較,直到發現C與D不匹配。於是,移動位數 = 6 - 2,繼續將搜索詞向後移動4位。

逐位比較,直到搜索詞的最後一位,發現完全匹配,於是搜索完成。如果還要繼續搜索(即找出全部匹配),移動位數 = 7 - 0,再將搜索詞向後移動7位,這里就不再重復了。

下面介紹《部分匹配表》是如何產生的。

首先,要了解兩個概念:"前綴"和"後綴"。 "前綴"指除了最後一個字元以外,一個字元串的全部頭部組合;"後綴"指除了第一個字元以外,一個字元串的全部尾部組合。

"部分匹配值"就是"前綴"和"後綴"的最長的共有元素的長度。以"ABCDABD"為例,

"部分匹配"的實質是,有時候,字元串頭部和尾部會有重復。比如,"ABCDAB"之中有兩個"AB",那麼它的"部分匹配值"就是2("AB"的長度)。搜索詞移動的時候,第一個"AB"向後移動4位(字元串長度-部分匹配值),就可以來到第二個"AB"的位置。

BM(Boyer-Moore)演算法。它是一種非常高效的字元串匹配演算法,有實驗統計,它的性能是著名的KMP 演算法的 3 到 4 倍。

BM 演算法包含兩部分,分別是壞字元規則(bad character rule)和好後綴規則(good suffix shift)

未完待續

參考文章:
字元串匹配的Boyer-Moore演算法

C. VR如何渲染動畫

在vray3.0及之前的時代,使用vray渲染動畫是一件比較繁瑣的工作。又是分層渲染又是隔幀預渲染光子,又或者是逐幀預渲染光子。甚至關掉GI單獨GI設置等等,這都是為了避免動畫渲染的閃爍或者斑點。平衡渲染質量與渲染時間。

當vray3.6及4.0發布之後,使用vray進行動畫渲染變得非常簡單。2020年vray5.0發布,至今天vray已經更新到5.1。渲染動畫在速度上已經有了很快的提升。vray多年GI詬病已經不讓我煩惱。

下面就介紹一下vray官方給出的動畫渲染設置。

傳統上(祖傳閃爍),vray動畫序列的渲染可能會在幀間產生不想要的閃爍,也被稱為「bubbling冒泡」或「boiling沸騰」。這是因為低頻噪波在幀間發生變化。

其實V-RayNext(也就是vray4.0) 時候解已經決這些問題,只有兩個調整的默認設置:Light Cache Subdivs,,和Retrace數值。雖然推薦的設置在大多數情況下都是適用的(比如室內,室外,環境,包拍攝,特效模擬),但我們建議您在提交到最終的序列渲染之前,還是要渲染具有代表性的幀來測試一下有無問題。(譯者:這是免責聲明啊)

如果仍然存在一些視覺偽影(諸如噪點、斑點),繼續以小數值增加這兩個設置,直到它們被解決。接下來就是講到如何設置。

1.1所有的設置都是在V-Ray默認渲染設置下進行的。可以通過更改到另一個渲染引擎,然後再更改回V-Ray,這就重置vray設置了。這是大前提,如果打開舊版本vray的文件就需要先重置渲染器。

1.2設置圖像采樣器為「Bucket.」。點擊渲染設置> V-Ray標簽>圖像采樣器(抗鋸齒)>類型>「Bucket.」。這是最終渲染的首選采樣類型,因為它比漸進式稍微快一些,並且與一些輔助技術一起工作得更全面。譯者:意思就是「Bucket」模式bug更少。

1.3選擇最適合您需要的雜訊閾值。0.005的值將去除可見的噪波,而不用渲染後去噪(譯者:就不用加降噪了)。要比較這兩個值,請查看上面示例中的默認值0.01和0.005之間的差異。

1.4。進入GI選項卡的Light Cache設置,將subdiv設置為3000。增加光緩存子divs確保了光緩存被很好的采樣,並且在幀之間是穩定的。與渲染實際幀相比,更高的subdiv對渲染時間的影響可以忽略不計,所以這是一個良好的常規做法,沒有任何特別的缺點。

請注意,光緩存的計算方法需要是「每幀」(默認),而不是路徑驅動的方法,如「攝像機路徑」。

總結:Vray4.0後,官方推薦的動畫渲染設置已經不分運動物體和靜止物體。動畫的渲染設置,在默認參數前提下,僅僅需要調整兩個位置:

1.圖像采樣器使用Bucket.noisethreshold設置為 0.005就不需要降噪了。默認的話也可以添加降噪器即可。

當然動畫渲染時間普遍都是偏長的,一般公司都是找一些渲染農場來完成項目的渲染工作,但是好用的一般都貴,稍微實惠點的就不好用,又慢又排隊,有興趣的可以去體驗一下這個農場,叫渲染101,目前來說是最好用,效率最高的農場,速度快也不排隊,而且最重要的是價格非常低

D. 神經網路如何外推:從前饋網路到圖網路

How Neural Networks Extrapolate: From Feedforward to Graph Neural Networks

ICLR2021最高分論文            https://arxiv.org/abs/2009.11848

52頁論文,正文佔9頁,主要都是附錄,不過附錄里很多圖片(一頁就一兩張圖),排除這些一頁一圖的,只有40頁

我們研究用梯度下降法訓練的神經網路如何外推,也就是說,它們在訓練分布的支持之外學習什麼。以前的工作報告了使用神經網路進行外推時混合的實證結果:雖然前饋神經網路,即多層感知器(MLP)在某些簡單任務中外推效果不好,但圖形神經網路(GNN)——帶有MLP模塊的結構化網路——在更復雜的任務中取得了一些成功。為了得到理論解釋,我們確定了MLPs和GNNs外推良好的條件。首先,我們量化了ReLU-MLPs從原點沿任意方向快速收斂到線性函數的觀測結果,這意味著ReLU-MLPs不能外推大多數非線性函數。但是,當訓練分布足夠「多樣化」時,他們可以證明學習線性目標函數。其次,在分析GNNs的成功和局限性時,這些結果提出了一個假設,我們提供了理論和經驗證據:GNNs在將演算法任務外推到新數據(例如。,較大的圖或邊權重)依賴於編碼體系結構或特徵中特定於任務的非線性。我們的理論分析建立在過度參數化網路與神經切線核的聯繫上。根據經驗,我們的理論適用於不同的培訓環境

1簡介

人類在許多任務中推斷得很好。例如,我們可以對任意大的數應用算術。人們可能想知道,神經網路是否也能做到這一點,並將其推廣到任意遠離訓練數據的示例中(Lake et al.,2017)。奇怪的是,以前的工作報告混合外推結果與神經網路。早宏裂期的工作表明,前饋神經網路,又稱多層感知器(MLPs),在學習簡單多項式函數時不能很好地進行外推(Barnard&Wessels,1992;Haley&Soloway,1992年)。然而,最近的研究表明,圖神經網路(GNNs)(Scarselli et al.,2009)是一類具有MLP構建塊的結構化網路,在具有挑戰性的演算法任務中,如預測物理系統的時間演化(Battaglia et al.,2016),可以推廣到比訓練嫌咐圖大得多的圖,學習圖形演算法(Velickovic et al.,2020),求解數學方程(Lample&Charton,2020)。

為了解釋這個難題,我們正式研究了梯度下降(GD)訓練的神經網路是如何外推的,即它們在訓練分布的支持之外學習什麼。我們說,如果一個神經網路在訓練分布之外學習了一個任務,它就能很好地進行外推。乍一看,似乎神經網路可以在訓練分布之外任意行為,因為它們具有高容量(Zhang et al.,2017),並且是通用逼近器(Cybenko,1989;Funahashi,1989年;Hornik等人,1989年;庫爾科娃,1992年)。然而,神經網路受到梯度下降訓練的限制(Hardt等人,2016;Soudry等人,2018年)。在我們的分析中,我們通過類比過參數化神經網路的訓練動態和通過神經切線核(NTK)的核回歸,明確考慮了這種隱式偏差(Jacot等人,2018)。

從前饋網路、最簡單的神經網路和更復雜的體系結構(如GNNs)的構建塊開始,我們建立了由GD訓練的具有ReLU激活的過參數mlp的預測從原點沿任意方向收斂到線性函數。我們證明了兩層網路的收斂速度,並從經驗上觀察到收斂經常發生在訓練數據附近(圖1),這表明ReLU-MLPs不能很好地外推大多數非線性任務。我們強調,我們的結果並不是基於ReLU網路具有有限多個線性區域的事實(Arora et al.,2018;Hanin&Rolnick,2019年;Hein等人,2019年)。雖然有有限多個線性區域意味著ReLU MLPs最終會變為線性,但MLPs是否會學習到接近訓練分布的正確目標函數並沒有說明。相比之下,我們的結果是非漸近的,並且量化了MLPs將學習什麼樣的函數接近於訓練分布。其次,我們確定了mlp外推良好的條件:任務是線性的,訓練分布的幾何結構是充分「多樣化」的。據我們所知蔽者閉,我們的結果是這種前饋神經網路的第一個外推結果。

然後,我們將我們對前饋神經網路的見解與GNNs聯系起來,以解釋GNNs在某些演算法任務中外推得好的原因。先前的工作報告了可以通過動態規劃(DP)解決的任務的成功外推(Bellman,1966),其計算結構與GNNs一致(Xu等人,2020)。DP更新通常可以分解為非線性和線性步驟。因此,我們假設GD訓練的GNN可以在DP任務中很好地外推,如果我們在架構和輸入表示中編碼適當的非線性(圖2)。重要的是,編碼非線性可能不需要GNNs插值,因為MLP模塊可以很容易地學習訓練分布中的許多非線性函數(Cybenko,1989;Hornik等人,1989年;Xu等人,2020),但GNNs正確外推至關重要。我們使用圖NTK(Du等人,2019b)證明了簡化情況下的這一假設。在經驗上,我們驗證了三個DP任務的假設:最大度、最短路徑和n體問題。我們證明了具有適當結構、輸入表示和訓練分布的GNNs可以很好地預測具有未知大小、結構、邊權值和節點特徵的圖。我們的理論解釋了以往工作的經驗成功,並指出了它們的局限性:成功的外推依賴於編碼任務特定的非線性,這需要領域知識或廣泛的模型搜索。從更廣泛的角度來看,我們的見解超越了GNNs,並廣泛應用於其他神經網路。

總之,我們研究神經網路如何外推。首先,由GD訓練的ReLU-mlp以O(1/t)的速率沿原點方向收斂為線性函數。其次,為了解釋為什麼GNNs在一些演算法任務中可以很好地外推,我們證明了ReLU-MLPs在線性任務中可以很好地外推,從而引出一個假設:當適當的非線性被編碼到結構和特徵中時,神經網路可以很好地外推。我們用一個簡化的例子證明了這個假設,並為更一般的情況提供了經驗支持。

1.1相關工作

早期的工作顯示了MLP不能很好地外推的示例任務,例如學習簡單多項式(Barnard&Wessels,1992;Haley&Soloway,1992年)。相反,我們展示了ReLU MLPs如何外推的一般模式,並確定MLPs外推良好的條件。最近的工作研究了在NTK和平均場兩種情況下,梯度下降對MLP產生的隱性偏差(Bietti和Mairal,2019;Chizat&Bach,2018年;Song等人,2018年)。與我們的結果相關,一些工作表明MLP預測收斂於「簡單」分段線性函數,例如,具有很少的線性區域(Hanin&Rolnick,2019;Maennel等人,2018年;Savarese等人,2019年;威廉姆斯等人,2019年)。我們的工作不同之處在於,這些工作都沒有明確研究外推法,有些只關注一維輸入。最近的研究還表明,在NTK區域的高維環境中,MLP在某些標度極限下至多是一個漸近線性預測因子(Ba等人,2020;Ghorbani等人,2019年)。我們研究不同的設置(外推),我們的分析是非漸近性質,不依賴於隨機矩陣理論。

先前的工作通過在較大的圖上進行測試來探索GNN外推(Battaglia et al.,2018;Santoro等人,2018年;薩克斯頓等人,2019年;Velickovic等人,2020年)。我們是第一個從理論上研究GNN外推法的人,我們完成了外推法的概念,包括看不見的特徵和結構。

2准備工作

3前饋神經網路如何外推

前饋網路是最簡單的神經網路和更復雜的體系結構(如GNNs)的構建塊,因此我們首先研究它們在GD訓練時是如何外推的。在本文中,我們假設ReLU激活。第3.3節包含其他激活的初步結果。

3.1 RELU MLP的線性外推行為

通過架構,ReLU網路學習分段線性函數,但是在訓練數據的支持之外,這些區域究竟是什麼樣的呢?圖1舉例說明了當GD對各種非線性函數進行訓練時,ReLU MLP如何進行外推。這些例子表明,在訓練支持之外,預測很快就會沿著原點的方向線性化。我們通過線性回歸對MLPs的預測進行了系統的驗證:決定系數(R2)總是大於0.99(附錄C.2)。也就是說,ReLU MLPs幾乎立即在訓練數據范圍之外「線性化」。

我們使用GD通過神經切線核(NTK)訓練的神經網路的隱式偏差來形式化這個觀察:GD訓練的過參數化網路的優化軌跡等價於具有特定神經切線核的核回歸的軌跡,在一系列被稱為「NTK制度」的假設下(Jacot等人,2018年)。我們在這里提供了一個非正式的定義;更多詳情,請參閱Jacot等人(2018)和附錄A。

定義2。

(非正式)在NTK區域訓練的神經網路是無限寬的,以一定的比例隨機初始化,並且由GD以無窮小的步長訓練。

先前的工作通過NTK分析過參數化神經網路的優化和分布泛化(Allen-Zhu等人,2019a;b類;Arora等人,2019a;b類;曹顧,2019;杜等人,2019c;一個;李亮,2018;日田和鈴木,2021年)。相反,我們分析外推。

定理1將我們從圖1中觀察到的結果形式化:在訓練數據范圍之外,沿著原點的任何方向tv,兩層ReLU MLP的預測迅速收斂為速率為O(1/t)的線性函數。線性系數β收斂速度中的常數項依賴於訓練數據和方向v。證據見附錄B.1

定理1

ReLU網路具有有限多個線性區域(Arora等人,2018;漢寧和羅爾尼克,2019),因此他們的預測最終成為線性。相反,定理1是一個更細粒度的分析MLP如何外推,並提供了收斂速度。雖然定理1假設兩層網路處於NTK狀態,但實驗證實,線性外推行為發生在具有不同深度、寬度、學習速率和批量大小的網路上(附錄C.1和C.2)。我們的證明技術也可能擴展到更深層次的網路。

圖4a提供了一個更積極的結果:MLP在許多不同的超參數上很好地外推了線性目標函數。雖然學習線性函數一開始似乎非常有限,但在第4節中,這一見解將有助於解釋GNN在非線性實際任務中的外推特性。在此之前,我們首先從理論上分析了MLPs外推的好時機。

3.2當RELU MLPS可證明外推井

圖4a顯示,當目標函數為線性時,MLP可以很好地外推。然而,這並不總是正確的。在本節中,我們展示了成功的外推依賴於訓練數據的幾何結構。直觀地說,訓練分布必須足夠「多樣化」,以便進行正確的推斷

我們提供了兩個條件,將訓練數據的幾何結構與外推聯系起來。引理1指出,過參數化的mlp只需二維例子就可以學習線性目標函數。

實驗:訓練數據的幾何結構影響外推。

定理2中的條件形式化了一種直覺,即訓練分布必須是「多樣的」,才能成功地進行外推,例如,D包括所有方向。從經驗上講,當滿足定理2的條件時(圖4b中的「all」),外推誤差確實很小。相反,當訓練示例僅限於某些方向時,外推誤差要大得多(圖4b和圖3)。

與之前的工作相關,定理2提出了為什麼虛假相關性可能會損害外推,補充了因果關系論點(Arjovsky et al.,2019;Peters等人,2016年;Rojas Carulla等人,2018年)。當訓練數據具有虛假相關性時,某些特徵組合丟失;e、 例如,駱駝可能只出現在沙漠中的圖像收集。因此,定理2的條件不再成立,模型可能外推錯誤。定理2也類似於線性模型的可辨識條件,但更為嚴格。如果訓練數據具有全(特徵)秩,我們可以唯一地識別一個線性函數。mlp更具表現力,因此識別線性目標函數需要附加約束。

綜上所述,我們分析了ReLU-MLPs是如何外推的,並提供了兩個啟示:(1)MLPs由於其線性外推而不能外推大多數非線性任務(定理1);當目標函數是線性函數時,如果訓練分布是「多樣的」(定理2),mlp可以很好地外推。在下一節中,這些結果將幫助我們理解更復雜的網路是如何外推的。

3.3具有其他激活功能的MLPS

在繼續討論GNNs之前,我們通過對其他激活函數tanh的實驗來完成MLPs的描述σ(x) =tanh(x),餘弦σ(x) =cos(x)(Lapedes&Farber,1987年;McCaughan,1997年;Sopena和Alquezar,1994),和σ(x) =x2(杜和李,2018;Livni等人,2014年)。詳情見附錄C.4。當激活函數和目標函數相似時,MLPs外推效果較好;e、 例如,當學習tanh時,tanh激活可以很好地推斷,但不能推斷其他功能(圖5)。而且,每個激活函數都有不同的局限性。要用tanh激活外推tanh函數,訓練數據范圍必須足夠寬。當學習具有二次激活的二次函數時,只有兩層網路可以很好地進行外推,而更多的層可以得到更高階的多項式。對於高維數據,餘弦激活很難優化,因此我們只考慮一維/二維餘弦目標函數。

4圖形神經網路如何外推

上面,我們看到非線性任務中的外推對於MLP來說是困難的。盡管存在這一局限性,GNNs在一些非線性演算法任務中表現出了很好的外推能力,如直觀物理(Battaglia et al.,2016;Janner等人,2019),圖演算法(Battaglia等人,2018;Velickovic等人,2020)和符號數學(Lample&Charton,2020)。為了解決這個差異,我們建立在MLP結果的基礎上,研究GD訓練的GNNs是如何外推的。

4.1假設:線性演算法對齊有助於外推

我們從一個例子開始:訓練GNNs來解決最短路徑問題。對於這項任務,先前的工作觀察到,具有最小聚集的改進GNN架構可以推廣到比訓練集中的圖更大的圖(Battaglia et al.,2018;Velickovic等人,2020):

我們首先提供一個直觀的解釋(圖2a)。最短路徑可通過Bellman-Ford(BF)演算法(Bellman,1958)求解,並進行以下更新

其中w(v,u)是邊(v,u)的權重,d[k][u]是k步內到節點u的最短距離。這兩個方程可以很容易地對齊:如果GNNs的MLP模塊學習一個線性函數d[k],那麼它將模擬BF演算法−1] [v]+w(v,u)。由於mlp可以外推線性任務,這種「對齊」可以解釋為什麼GNNs可以在這個任務中很好地外推。

為了進行比較,我們可以解釋為什麼我們不希望GNN使用更常用的和聚合(Eqn。1) 在這項任務中推斷得很好。對於和聚合,MLP模塊需要學習一個非線性函數來模擬BF演算法,但定理1表明,它們不會在訓練支持之外外推大多數非線性函數。

我們可以將上述直覺推廣到其他演算法任務。許多GNNs外推良好的任務可以通過動態規劃(DP)來解決(Bellman,1966),這是一種具有類似GNNs(Eqn)的遞歸結構的演算法範式。1) (Xu等人,2020年)。

定義3。動態規劃(DP)是一個帶有更新的遞歸過程

其中答案[k][s]是迭代k和狀態s索引的子問題的解決方案,DP Update是一個任務特定的更新函數,它基於上一次迭代解決子問題。從更廣泛的角度出發,我們假設:如果我們將適當的非線性編碼到模型結構和輸入表示中,使MLP模塊只需要學習接近線性的步驟,那麼所得到的神經網路就可以很好地外推。

假設1。

我們的假設建立在(Xu等人,2020)的演算法對齊框架之上,該框架指出,如果模塊「對齊」以便於學習(可能是非線性)函數,則神經網路插值良好。成功的外推更難:模塊需要與線性函數對齊。

線性演算法對準的應用。

一般來說,線性演算法對准不局限於GNN,廣泛應用於神經網路。為了滿足這種情況,我們可以在結構或輸入表示中編碼適當的非線性操作(圖2)。使用GNNs學習DP演算法是在體系結構中編碼非線性的一個例子(Battaglia等人,2018;Corso等人,2020年)。另一個例子是對體系結構中的日誌和exp變換進行編碼,以幫助外推算術任務中的乘法(Trask等人,2018;Madsen&Johansen,2020年)。神經符號程序進一步發展,並對符號操作庫進行編碼,以幫助推斷(Johnson等人,2017年;Mao等人,2019年;易等,2018年)。

對於某些任務,更改輸入表示可能更容易(圖2b)。有時,我們可以將目標函數f分解為f=g◦ 將h嵌入特徵嵌入h和一個簡單的目標函數g中,我們的模型可以很好地推斷。我們可以通過使用領域知識通過專門的特徵或特徵轉換獲得h(Lample&Charton,2020;Webb等人,2020年),或通過X\D中未標記的未標記的未標記的分發數據的表示學習(例如,BERT)(Chen等人,2020年);Devlin等人,2019年;胡等,2020;Mikolov等人,2013b;Peters等人,2018年)。這為表示如何幫助在不同應用領域進行外推提供了新的視角。例如,在自然語言處理中,預處理表示(Mikolov等人,2013a;Wu&Dredze,2019)和使用領域知識進行特徵轉換(袁等,2020年;Zhang等人,2019)幫助模型在語言之間進行概括,這是一種特殊的外推。在定量金融中,確定正確的「因素」或特徵對於深入學習模型至關重要,因為金融市場可能經常處於外推制度中(Banz,1981;法蘭西,1993年;羅斯,1976)。

線性演算法對齊解釋了文獻中成功的外推,並指出外推一般更難:編碼適當的非線性通常需要領域專家或模型搜索。其次,我們為我們的假設提供理論和實證支持。

4.2理論和經驗支持

我們驗證了我們對三個DP任務的假設:最大度、最短路徑和n-體問題,並證明了最大度假設。我們強調了圖結構在外推中的作用。

理論分析。

我們從一個簡單而基本的任務開始:學習一個圖的最大度,一個DP的特例。作為定理1的推論,常用的基於和的GNN(Eqn。1) 無法很好地推斷(證據見附錄B.4)。

推論1。

具有和聚集和和和讀出的GNNs在最大程度上不能很好地外推。為了實現線性演算法對齊,我們可以對讀出器中唯一的非線性max函數進行編碼。定理3證實了具有最大讀數的GNN在這個任務中可以很好地外推。

定理3並不是緊跟定理2,因為GNNs中的MLP模塊只接受間接的監視。我們分析圖NTK(Du等人,2019b)來證明附錄B.5中的定理3。雖然定理3假設相同的節點特徵,但我們在經驗上觀察到相同和不相同特徵的相似結果(附錄中的圖16)。

條件的解釋。

定理3中的條件類似於定理2中的條件。這兩個定理都需要不同的訓練數據,用定理3中的圖結構或定理2中的方向來度量。在定理3中,如果所有訓練圖都具有相同的最大或最小節點度,例如,當訓練數據來自以下族之一時,違反了該條件:路徑、C-正則圖(具有C度的正則圖)、圈和階梯。

實驗:有助於推斷的架構。

我們用兩個DP任務來驗證我們的理論分析:最大度和最短路徑(詳見附錄C.5和C.6)。而以前的工作只測試不同大小的圖(Battaglia et al.,2018;Velickovic等人,2020),我們還測試了具有不可見結構、邊權重和節點特徵的圖。結果支持了我們的理論。對於最大度,具有最大讀數的GNNs優於具有和讀數的GNNs(圖6a),證實了推論1和定理3。對於最短路徑,具有最小讀數和最小聚集的GNN優於具有和讀數的GNN(圖6a)。

實驗證實了訓練圖結構的重要性(圖7)。有趣的是,這兩個任務支持不同的圖結構。對於最大度,如定理3所預測的,當訓練在樹、完全圖、擴張圖和一般圖上時,GNNs外推效果很好,當訓練在4-正則圖、圈圖或梯形圖上時,外推誤差更大。對於最短路徑,當我們改變訓練圖的稀疏性時,外推誤差遵循U形曲線(附錄中的圖7b和圖18)。直覺上,在稀疏或稠密圖上訓練的模型可能學習退化解。

實驗:有助於推斷的表徵。

最後,我們展示了一個很好的輸入表示幫助外推。我們研究了n體問題(Battaglia等人,2016;Watters等人,2017年)(附錄C.7),即預測重力系統中n個物體的時間演化。根據之前的工作,輸入是一個完整的圖形,其中節點是對象(Battaglia等人,2016)。

5與其他分布外設置的連接

我們討論幾個相關的設置。直觀地說,從我們上述結果的觀點來看,相關設置中的方法可以通過1)學習超出訓練數據范圍的有用非線性和2)將相關測試數據映射到訓練數據范圍來改進外推。

領域適應研究對特定目標領域的泛化(Ben-David等人,2010;Blitzer等人,2008年;Mansour等人,2009年)。典型的策略會調整訓練過程:例如,使用來自目標域的未標記樣本來對齊目標和源分布(Ganin等人,2016;趙等,2018)。在訓練期間使用目標域數據可能會導致有用的非線性,並可能通過匹配目標和源分布來減輕外推,盡管學習映射的正確性取決於標簽分布(Zhao等人,2019)。

對大量未標記數據的自監督學習可以學習超出標記訓練數據范圍的有用非線性(Chen et al.,2020;Devlin等人,2019年;He等人,2020年;Peters等人,2018年)。因此,我們的結果提出了一個解釋,為什麼像BERT這樣的預訓練表示可以提高分布外魯棒性(Hendrycks et al.,2020)。此外,自監督學習可以將語義相似的數據映射到相似的表示,因此映射後的一些域外實例可能會落入訓練分布中。

不變模型旨在學習在多個訓練分布中尊重特定不變性的特徵(Arjovsky et al.,2019;Rojas Carulla等人,2018年;周等人,2021)。如果模型真的學習到了這些不變性,這可能發生在線性情況下,當存在混雜或反因果變數時(Ahuja等人,2021;Rosenfeld等人,2021),這可能從本質上增加了訓練數據范圍,因為模型可以忽略不變特徵的變化。

分布魯棒性考慮了數據分布的小干擾,並確保模型在這些干擾下表現良好(Goh&Sim,2010;Sagawa等人,2020年;Sinha等人,2018年;Staib&Jegelka,2019年)。相反,我們看的是更多的全局擾動。盡管如此,人們還是希望,有助於外推的修改通常也能提高對局部擾動的魯棒性。

6結論

本文是一個初步的步驟,正式了解如何神經網路訓練梯度下降外推。我們確定了MLPs和GNNs按期望外推的條件。我們還提出了一種解釋,說明GNNs在復雜的演算法任務中是如何能夠很好地進行外推的:在架構和特性中編碼適當的非線性可以幫助外推。我們的結果和假設與本文和文獻中的實證結果一致

E. 頁面置換演算法的實驗

#include <stdio.h>
#define PROCESS_NAME_LEN 32 /*進程名稱的最大長度*/
#define MIN_SLICE 10 /*最小碎片的大小*/
#define DEFAULT_MEM_SIZE 1024 /*默認內存的大小*/
#define DEFAULT_MEM_START 0 /*默認內存的起始位置*/

/* 內存分配演算法 */
#define MA_FF 1
#define MA_BF 2
#define MA_WF 3

int mem_size=DEFAULT_MEM_SIZE; /*內存大小*/
int ma_algorithm = MA_FF; /*當前分配演算法*/
static int pid = 0; /*初始pid*/
int flag = 0; /*設置內存大小標志*/

struct free_block_type
{
int size;
int start_addr;
struct free_block_type *next;
};
struct free_block_type *free_block;

struct allocated_block
{
int pid;
int size;
int start_addr;
char process_name[PROCESS_NAME_LEN];
struct allocated_block *next;
};
struct allocated_block *allocated_block_head;

/*初始化空閑塊,默認為一塊,可以指定大小及起始地址*/
struct free_block_type* init_free_block(int mem_size)
{

struct free_block_type *fb;

fb=(struct free_block_type *)malloc(sizeof(struct free_block_type));
if(fb==NULL)
{
printf("No mem\n");
return NULL;
}
fb->size = mem_size;
fb->start_addr = DEFAULT_MEM_START;
fb->next = NULL;
return fb;
}

void display_menu()
{
printf("\n");
printf("1 - Set memory size (default=%d)\n", DEFAULT_MEM_SIZE);
printf("2 - Select memory allocation algorithm\n");
printf("3 - New process \n");
printf("4 - Terminate a process \n");
printf("5 - Display memory usage \n");
printf("0 - Exit\n");
}

/*設置內存的大小*/
int set_mem_size()
{
int size;
if(flag!=0)
{ /*防止重復設置*/
printf("Cannot set memory size again\n");
return 0;
}
printf("Total memory size =");
scanf("%d", &size);
if(size>0)
{
mem_size = size;
free_block->size = mem_size;
}
flag=1;
return 1;
}
/*Best-fit使用最小的能夠放下將要存放數據的塊,First-first使用第一個能夠放下將要存放數據的塊,Worst-fit使用最大的能夠放下將要存放數據的塊。*/
/* 設置當前的分配演算法 */
/*分區分配演算法(Partitioning Placement Algorithm)
*/
void set_algorithm()
{
int algorithm;
printf("\t1 - First Fit\n");/*首次適應演算法(FF):。 */
printf("\t2 - Best Fit\n");/*最佳適應演算法(BF): */

printf("\t3 - Worst Fit\n");
scanf("%d", &algorithm);
if(algorithm>=1 && algorithm <=3) ma_algorithm=algorithm;
/*按指定演算法重新排列空閑區鏈表*/
rearrange(ma_algorithm);
}

void swap(int* data_1,int* data_2)
{
int temp;
temp=*data_1;
*data_1=*data_2;
*data_2=temp;
}

void rearrange_FF()
{
struct free_block_type *tmp, *work;
printf("Rearrange free blocks for FF \n");
tmp = free_block;
while(tmp!=NULL)
{
work = tmp->next;
while(work!=NULL)
{
if( work->start_addr < tmp->start_addr)
{ /*地址遞增*/
swap(&work->start_addr, &tmp->start_addr);
swap(&work->size, &tmp->size);
}
else
{
work=work->next;
}
}
tmp=tmp->next;
}
}
/*按BF演算法重新整理內存空閑塊鏈表(未完成)
void rearrange_BF()
{
struct free_block_type *tmp,*work;
printf("Rearrange free blocks for BF\n");
tmp=free_block;
while(tmp!=NULL)
{
work=tmp->next;
while(work!=NULL)
{

}
}

}

*/
/*按WF演算法重新整理內存空閑塊鏈表(未完成)
void rearrange_WF()
{
struct free_block_type *tmp,*work;
printf("Rearrange free blocks for WF \n");
tmp=free_block;
while(tmp!=NULL)
{
work=tmp->next;
while(work!=NULL)
{

}
}
}
*/

/*按指定的演算法整理內存空閑塊鏈表*/
int rearrange(int algorithm)
{
switch(algorithm)
{
case MA_FF: rearrange_FF(); break;
/*case MA_BF: rearrange_BF(); break; */
/*case MA_WF: rearrange_WF(); break; */
}
}

/*創建新的進程,主要是獲取內存的申請數量*/
int new_process()
{
struct allocated_block *ab;
int size;
int ret;
ab=(struct allocated_block *)malloc(sizeof(struct allocated_block));
if(!ab)
exit(-5);
ab->next = NULL;
pid++;
sprintf(ab->process_name, "PROCESS-%02d", pid);
ab->pid = pid;

printf("Memory for %s:", ab->process_name);
scanf("%d", &size);
if(size>0) ab->size=size;
ret = allocate_mem(ab); /* 從空閑區分配內存,ret==1表示分配ok*/
/*如果此時allocated_block_head尚未賦值,則賦值*/
if((ret==1) &&(allocated_block_head == NULL))
{
allocated_block_head=ab;
return 1;
}
/*分配成功,將該已分配塊的描述插入已分配鏈表*/
else if (ret==1)
{
ab->next=allocated_block_head;
allocated_block_head=ab;
return 2;
}
else if(ret==-1)
{ /*分配不成功*/
printf("Allocation fail\n");
free(ab);
return -1;
}
return 3;
}

/*分配內存模塊*/
int allocate_mem(struct allocated_block *ab)
{
struct free_block_type *fbt,*pre,*r;
int request_size=ab->size;
fbt=pre=free_block;
while(fbt!=NULL)
{
if(fbt->size>=request_size)
{
if(fbt->size-request_size>=MIN_SLICE)
{
fbt->size=fbt->size-request_size;
}
/*分配後空閑空間足夠大,則分割*/

else
{
r=fbt;
pre->next=fbt->next;
free(r);
/*分割後空閑區成為小碎片,一起分配*/

return 1;
}
}
pre = fbt;
fbt = fbt->next;
}

return -1;
}

/*將ab所表示的已分配區歸還,並進行可能的合並*/
int free_mem(struct allocated_block *ab)
{
int algorithm = ma_algorithm;
struct free_block_type *fbt, *pre, *work;

fbt=(struct free_block_type*) malloc(sizeof(struct free_block_type));
if(!fbt)
return -1;
fbt->size = ab->size;
fbt->start_addr = ab->start_addr;
/*插入到空閑區鏈表的頭部並將空閑區按地址遞增的次序排列*/
fbt->next = free_block;
free_block=fbt;
rearrange(MA_FF);
fbt=free_block;
while(fbt!=NULL)
{
work = fbt->next;
if(work!=NULL)
{
/*如果當前空閑區與後面的空閑區相連,則合並*/
if(fbt->start_addr+fbt->size == work->start_addr)
{
fbt->size += work->size;
fbt->next = work->next;
free(work);
continue;
}
}
fbt = fbt->next;
}
rearrange(algorithm); /*重新按當前的演算法排列空閑區*/
return 1;
}

/*?釋放ab數據結構節點*/
int dispose(struct allocated_block *free_ab)
{
struct allocated_block *pre, *ab;

if(free_ab == allocated_block_head)
{ /*如果要釋放第一個節點*/
allocated_block_head = allocated_block_head->next;
free(free_ab);
return 1;
}
pre = allocated_block_head;
ab = allocated_block_head->next;

while(ab!=free_ab)
{
pre = ab;
ab = ab->next;
}
pre->next = ab->next;
free(ab);
return 2;
}
/*查找要刪除的進程*/
struct allocated_block* find_process(int pid)
{
struct allocated_block *temp;
temp=allocated_block_head;
while(temp!=NULL)
{
if(temp->pid==pid)
{
return temp;
}
temp=temp->next;
}
}

/*刪除進程,歸還分配的存儲空間,並刪除描述該進程內存分配的節點*/
void kill_process()
{
struct allocated_block *ab;
int pid;
printf("Kill Process, pid=");
scanf("%d", &pid);
ab=find_process(pid);
if(ab!=NULL)
{
free_mem(ab); /*釋放ab所表示的分配區*/
dispose(ab); /*釋放ab數據結構節點*/

}
}

/* 顯示當前內存的使用情況,包括空閑區的情況和已經分配的情況 */

int display_mem_usage()
{
struct free_block_type *fbt=free_block;
struct allocated_block *ab=allocated_block_head;
if(fbt==NULL) return(-1);
printf("----------------------------------------------------------\n");

/* 顯示空閑區 */
printf("Free Memory:\n");
printf("%20s %20s\n", " start_addr", " size");
while(fbt!=NULL)
{
printf("%20d %20d\n", fbt->start_addr, fbt->size);
fbt=fbt->next;
}
/* 顯示已分配區 */
printf("\nUsed Memory:\n");
printf("%10s %20s %10s %10s\n", "PID", "ProcessName", "start_addr", " size");
while(ab!=NULL)
{
printf("%10d %20s %10d %10d\n", ab->pid, ab->process_name, ab->start_addr, ab->size);
ab=ab->next;
}
printf("----------------------------------------------------------\n");
return 0;
}

**********************************************************************
樓主啊,小女子給你的是殘缺版滴,要是你給我分,我就把剩下滴給你,上次在北京大學貼吧都被人騙了,世道炎涼啊O(∩_∩)O~

熱點內容
xpftp外網 發布:2025-05-17 23:58:11 瀏覽:384
如何評價一個伺服器的性能 發布:2025-05-17 23:40:53 瀏覽:270
淘寶客適合什麼伺服器 發布:2025-05-17 23:39:26 瀏覽:613
python循環文件 發布:2025-05-17 23:39:22 瀏覽:828
androidstudio更新 發布:2025-05-17 23:38:22 瀏覽:643
java項目面試 發布:2025-05-17 23:30:53 瀏覽:780
若主存儲器按位元組編址 發布:2025-05-17 23:30:46 瀏覽:24
kotlinandroid 發布:2025-05-17 23:19:09 瀏覽:974
雲編程英語 發布:2025-05-17 23:18:34 瀏覽:623
androidstudio導入類 發布:2025-05-17 23:15:36 瀏覽:237