1x1=1打一成語;0000打一成語正確答案 視頻
作者丨Onedroid@知乎(已授權(quán))
來源丨h(huán)ttps://zhuanlan.zhihu.com/p/632499470
編輯丨極市平臺
前幾天在知乎上看到華為提出的一個VanillaNet,其中的一個設(shè)計點和我一直想實現(xiàn)的功能非常類似,即訓(xùn)練階段的時候模型是比較深的網(wǎng)絡(luò),推理的時候會自動變成比較淺的網(wǎng)絡(luò)。起初我一直想緩漸地暴力地丟掉卷積層,結(jié)果不能如愿,模型性能會在訓(xùn)練階段的最后幾個epoch一直退化,模型變成毫無用處的廢物。整整大半年一直也沒找到穩(wěn)定性能的方案,這也把我后續(xù)所有的構(gòu)想都否定了。本著拿來主義,本文直接采用VanillaNet的方案重新開始構(gòu)建模型ReduceNet(reduce depth,還有就是張量的那個reduce)
ReduceNet和VanillaNet有以下幾個區(qū)別:
1. a) 引入殘差,提升模型性能。部署階段,殘差也可以作為特殊的卷積核融入卷積算子
b) 除了用一個VanillaNet中的"可消解的激活函數(shù)"外,不使用多余的非線性激活函數(shù),從而使得不同模塊繼續(xù)融合。這也是reducenet關(guān)鍵設(shè)計,起源于某個偶然的實驗發(fā)現(xiàn):resnet兩個3x3卷積構(gòu)成的模塊,去掉第二個激活函數(shù),性能會提升,順便提高了速度。所以reducenet模塊也只采用一個激活函數(shù),而且是在訓(xùn)練結(jié)束后會消失的激活函數(shù)
c) 不使用maxpooling,用卷積代替,不同stage可以繼續(xù)融合
2.模型只有在訓(xùn)練階段存在激活函數(shù),部署階段整個網(wǎng)絡(luò)沒有任何激活函數(shù)(最后的softmax還是需要的)
3.根據(jù)2,backbone所有的線性層理論上可以繼續(xù)融合為一個超大尺寸卷積核的卷積層,逼近一個全連接層,印證了那個傳說中的“單層網(wǎng)絡(luò)理論”(印象中是有的,貌似是單層大網(wǎng)絡(luò)學(xué)習(xí)容量足夠卻很難擬合之類的,我不記得出處了,有知道的可以告知一下)。
4. 利用bottleneck結(jié)構(gòu)增加模塊網(wǎng)絡(luò)寬度,為訓(xùn)練階段引入更多參數(shù)量,而不增加推理時候的開銷。理論上我們可以在訓(xùn)練時讓模塊中間無限寬,推理時計算開銷只由模塊首尾的寬度決定。實際上應(yīng)該會存在短板效應(yīng)。我們大概只能在首尾寬度固定情況下不斷壓榨性能直到性能飽和。再繼續(xù)增加中間網(wǎng)絡(luò)寬度估計就變成冗余了。這時只能增加模塊首尾寬度繼續(xù)提升性能。用這種方式有點神經(jīng)架構(gòu)搜索的味道。也許神經(jīng)神經(jīng)架構(gòu)搜索本身是很冗余的領(lǐng)域。漸進(jìn)地調(diào)整寬高,壓榨性能,試探臨界才是較優(yōu)解。
本文貢獻(xiàn)如下:
1.理論說明深度非線性網(wǎng)絡(luò)可以融合成單層網(wǎng)絡(luò),實驗中模型也取得不錯的性能。本文提供了基本模塊的思路,目前的SOTA模型只要對應(yīng)魔改,在不改架構(gòu)的情況下,盡情利用本文模塊的特性榨取模型性能就可以,理論上100%漲點,不增加額外推理開銷。其實,本文的東西是提供了“填充”的功能,任何架構(gòu)都可以通過本文模塊中“無限”和“縮并”的特性,理論上壓榨出該架構(gòu)下最高性能。所以在數(shù)據(jù)充足的情況下,結(jié)合本文的模塊,最終的模型瓶頸還將會是架構(gòu)設(shè)計。不過目前為止,我們還遠(yuǎn)遠(yuǎn)還沒摸到瓶頸。暫時只要用sota架構(gòu)繼續(xù)壓榨就可以了。本人資源有限,沒卡,只要負(fù)責(zé)驗證方法的有效性就可以了。
上面說的是如何利用現(xiàn)有架構(gòu)提升性能。另外我這里提供個模型設(shè)計方案去探索新的適合應(yīng)用場景的sota架構(gòu)設(shè)計方案。我們先定下模型的開銷約束,比如計算量,參數(shù)量,內(nèi)存占用。在符合開銷約束情況下,掃描網(wǎng)絡(luò)深度和每層的寬度(這里是指部署的寬深,訓(xùn)練階段,一層網(wǎng)絡(luò)是可以根據(jù)我們的辦法無限擴(kuò)張寬深的,只要最后縮并回來),這樣就有不同的架構(gòu),讓它們一一被壓榨性能就可以了,因為寬深固定,性能極限就固定了。和SOTA比較,勝者為王。和神經(jīng)架構(gòu)搜索相比,我們可以做到專心壓榨性能,相當(dāng)于搜索得更快了。因為神經(jīng)架構(gòu)搜索方法是沒法保證一定寬度深度各種組合下性能如何的,再加上搜索空間這么大,很容易三心二意顧此失彼。
總之,有一個證明,兩個pipeline方案
2.嘗試解釋了為什么單層網(wǎng)絡(luò)規(guī)模足夠大卻很難獲得學(xué)習(xí)能力,從優(yōu)化的角度為多層非線性網(wǎng)絡(luò)和單層網(wǎng)絡(luò)建立了聯(lián)系,并指出多層非線性網(wǎng)絡(luò)本質(zhì)上可以為"探索單層網(wǎng)絡(luò)的權(quán)重最優(yōu)值”提供更大的探索自由度, 緩解優(yōu)化算法和單層網(wǎng)絡(luò)的“不和”,從而具備更高的學(xué)習(xí)效率。
3.訓(xùn)練階段,ReduceNet可以和現(xiàn)有的其他模型設(shè)計兼容,享有深度非線性網(wǎng)絡(luò)的性能收益。推理階段則最終可以變成單層網(wǎng)絡(luò),保持高性能的同時,獲得激進(jìn)的模型效率。當(dāng)然,還有一個好處是,部署網(wǎng)絡(luò)的形態(tài)是具備靈活性的,你愛融合幾層就幾層,依照硬件的內(nèi)存占用,延時條件調(diào)整融合的層數(shù)。比如,兩層3x3可以變成5x5卷積,在某個硬件上可能就能提速了。如果任務(wù)很容易,很小的模型就能滿足,那直接壓成單層,在硬件合適的情況下,推理速度會非常快,提供了用深度網(wǎng)絡(luò)高效學(xué)習(xí),用單層網(wǎng)絡(luò)快速推理的完美方案。
4.ReduceNet理論上可以在訓(xùn)練階段無限深和無限寬(bottleneck中間表示無限寬),推理階段變成一個小網(wǎng)絡(luò),有需要的話甚至直接變成單層網(wǎng)絡(luò)。
不排除我犯了很傻的代碼錯誤,一切只是我的妄想(真的碰到好幾次了),如果錯了就刪帖跑路
代碼鏈接
[https://github.com/ohmydroid/reducenet
模型壓縮的核心思想是先利用大網(wǎng)絡(luò)的學(xué)習(xí)能力,最后通過各種手段(知識蒸餾,剪枝,神經(jīng)架構(gòu)搜索,動態(tài)推理網(wǎng)絡(luò)等)將該能力轉(zhuǎn)移到較小的模型上,以減少資源開銷。(目前的分類習(xí)慣并不把神經(jīng)架構(gòu)搜索,動態(tài)推理網(wǎng)絡(luò)歸于模型壓縮,這僅僅是我個人習(xí)慣和理解)
ReduceNet的靈感來源有以下幾個:
1.RepVGG是比較特別的模型,訓(xùn)練時有多個分支,推理時可以合并成單個分支,可以看作是網(wǎng)絡(luò)寬度這個角度的縮并。所以很容易聯(lián)想到把這種設(shè)計擴(kuò)展到網(wǎng)絡(luò)深度方向,相關(guān)的工作有DepthShrinker,RMNet。嚴(yán)格來說,讀研期間設(shè)計的靜態(tài)condconv比這個更早,模塊化動態(tài)卷積又被condconv先發(fā)。橫向重參化的idea應(yīng)該來源于condconv.
2.SkipNet, 一種動態(tài)推理網(wǎng)絡(luò),在推理階段通過路由網(wǎng)絡(luò)為不同數(shù)據(jù)選擇性地跳過主網(wǎng)絡(luò)的一些網(wǎng)絡(luò)層,以減少計算.
3.Stochastic Depth,訓(xùn)練階段以概率的方式激活或者不激活殘差塊中的卷積分支,可以提升性能,但是推理階段沒有減少網(wǎng)絡(luò)深度,按照概率融合卷積塊和殘差。
4.DepthShrinker, 比較接近我設(shè)想中的模型,但是條件很麻煩,需要學(xué)習(xí)mask參數(shù),還要蒸餾,微調(diào)和融合。RMNet需要剪枝,微調(diào),和融合。這些方式其實和華為的VanillaNet比較接近了。后者更加簡潔有效。我自己想的方案暫時又粗暴且無用,打不過就加入。
5.VanillaNet中Deep Training Strategy,里面的公式以及衰減策略和我設(shè)計的幾乎差不多,只是VanillaNet選擇了對激活函數(shù)下手,再后期融合兩個串聯(lián)的卷積算子。而我天真地以為idea結(jié)合了skipnet,Stochastic Depth,神經(jīng)架構(gòu)搜索等思想必定萬無一失(不排除以后會有正確穩(wěn)定的方案),從而貪心地選擇最后丟棄整個卷積層。實驗結(jié)果一度讓我懷疑人生,模型性能會在最后階段徹徹底地崩潰。換成VanillaNet的Deep Training Strategy后模型結(jié)果非常理想。
6. 是我N年前構(gòu)想的DetachNet,算是ReduceNet的雛形,希望有一個無限大的網(wǎng)絡(luò)可以為一個小網(wǎng)絡(luò)的每一層提供scale factor(scale的方式乘,加,卷積都可以)。這個和動態(tài)卷積非常類似了,只不過我希望大網(wǎng)絡(luò)在訓(xùn)練的可以無限大,推理的時候可以摘除,將能力轉(zhuǎn)移給小網(wǎng)絡(luò),完美的妄想的無限壓縮算法。最終敗于BP算法。也不是不可能。我一度相信,這種模型會讓AGI時代到來,完全沒想到AGI風(fēng)暴是ChatGPT引起的。ReduceNet現(xiàn)在好像也可以在訓(xùn)練階段無限大,推理階段非常小,所以DetachNet也算后繼有net。
總的來說,這種設(shè)計使得模型在訓(xùn)練過程中借助多層卷積和非線性獲得更強(qiáng)的學(xué)習(xí)能力;推理階段,非線性消失則為減少網(wǎng)絡(luò)深度提供了可能。
順便一提,VanillaNet網(wǎng)絡(luò)雖然淺但是非常寬,計算量,參數(shù)量,內(nèi)存占用都很大,唯一的優(yōu)勢可能就是用更快的速度取得接近sota的準(zhǔn)確率。然而,這速度也是有限制的。歸根結(jié)底這限制來自于寬網(wǎng)絡(luò)引發(fā)的一系列連鎖反應(yīng)。龐大的通道數(shù),會帶來更多的內(nèi)存占用,進(jìn)一步增加訪存。batch size等于1的時候vanillanet還有速度優(yōu)勢,其遠(yuǎn)超深網(wǎng)絡(luò)的計算開銷還能忽略。如果batch size變大呢,想必速度優(yōu)勢不會有這么明顯,甚至?xí)饾u慢于普通的sota模型,那其優(yōu)勢將蕩然無存。
VanillaNet的deep training strategy足以對深度網(wǎng)絡(luò)模型設(shè)計產(chǎn)生深遠(yuǎn)的影響,可能在網(wǎng)絡(luò)架構(gòu)上設(shè)計元素太多太雜,反而不能發(fā)揮整體優(yōu)勢。
和VanillaNet不同,本文設(shè)計的基本模型由3x3 conv, 1x1 conv ,殘差連接構(gòu)成。下采樣的話,也只要把3x3 conv的stride設(shè)置為2,并且去除收尾的殘差(激活函數(shù)的殘差保留)。值得注意的是整個模塊只有一個激活函數(shù),訓(xùn)練結(jié)束,激活函數(shù)也會消失。之所以只用一個激活函數(shù)是因為之前發(fā)現(xiàn)resnet的殘差塊中去掉一個激活函數(shù)效果會更好,速度還更快(查重發(fā)現(xiàn)被人發(fā)過了)。
數(shù)值,我是隨著iteration從1到0按照cosine的方式衰減,公式和VanillaNet的是反過來的。
訓(xùn)練階段,模塊如左圖,推理階段,這個模塊會整合成一個純線性的3x3 conv。能夠融合的原因有以下幾點:
1.conv,bn可以融合成1個conv
2.一個3x3 conv和一個1x1 conv會整合成一個3x3 conv
3.殘差連接是可以看作一種特殊的卷積核,所以也可以參與線性融合
比起VanillaNet,ReduceNet的其中一個優(yōu)勢在于能夠和現(xiàn)有的架構(gòu)設(shè)計方式兼容。
此外,當(dāng)訓(xùn)練結(jié)束后,所有算子完成上述的融合后,ReduceNet的網(wǎng)絡(luò)backbone部分,只有連續(xù)的3x3 conv,這意味著這些純線性的3x3 conv可以進(jìn)一步連續(xù)融合直至變成一個更大尺寸卷積核的單層卷積。最終,整個網(wǎng)絡(luò)會變成一個卷積層,pool, FC, 總共3層。pool是avgpool的話網(wǎng)絡(luò)應(yīng)該可以直接變成1層。
按照resnet56 cifar的架構(gòu),reducenet56(訓(xùn)練階段是56層) cifar10的準(zhǔn)確率可以達(dá)到93%。resnet的模塊是兩個3x3 conv, 我的模塊是一個3x3 conv+一個1x1 Conv(可以融合成一個3x3 Conv)。
如果只融合模塊里的卷積不繼續(xù)融合的話,網(wǎng)絡(luò)深度應(yīng)該是29. 為此構(gòu)造了一個29層的ResNet進(jìn)行比較(和原版resnet不同,每個模塊是一個非線性3x3卷積加一個殘差,因為要和我的模型推理階段的架構(gòu)公平對比)準(zhǔn)確率是91+%(手賤,不小心把tmux退出了)。具體架構(gòu)和訓(xùn)練代碼可以參考repo的代碼。雖然只是在cifar10上的實驗,但是效果已經(jīng)足夠驚艷。代碼里還沒有加入任何融合操作,我就是確認(rèn)純線性條件是不是成立,能跑不錯的結(jié)果就行,結(jié)果超出預(yù)期。
如果設(shè)計邏輯正確無誤,代碼也能確保線性條件成立的話,可以印證:
1.單層網(wǎng)絡(luò)的表達(dá)能力是足夠的,只是我們目前的優(yōu)化算法并不能讓單層網(wǎng)絡(luò)找到合適解。不是模型容量的問題,是目前深度學(xué)習(xí)的優(yōu)化算法碰上單層線性網(wǎng)絡(luò)的天然局限。
2.深度非線性網(wǎng)絡(luò)最終是可以轉(zhuǎn)換成單層網(wǎng)絡(luò)的,多層非線性網(wǎng)絡(luò)本質(zhì)上可以看作是為單層網(wǎng)絡(luò)高效搜索權(quán)重的方法,彌補(bǔ)了當(dāng)前單層網(wǎng)絡(luò)優(yōu)化算法的缺陷。
這么多的非線性層也許只是為單個線性層找到更好的參數(shù)。最開始,參數(shù)只是隨機(jī)的,非線性的存在和BP算法機(jī)制,讓整體網(wǎng)絡(luò)的每個參數(shù)個體能夠像布朗運(yùn)動一樣“更自由”地改變參數(shù)。更確切地說,是隨機(jī)初始化讓前向傳播有了一定隨機(jī)性,比如ReLU后的數(shù)值,隨機(jī)地為0。因果循環(huán),這種隨機(jī)的失活,又讓反向傳播只能隨機(jī)地尋找路徑讓梯度流動(后面會提到,這是天然的子網(wǎng)采樣,每個子網(wǎng)都有機(jī)會接受數(shù)據(jù)洗禮)。
訓(xùn)練階段,堆疊純非線性等價于一層線性層,即便堆疊再多,所有參數(shù)的更新軌跡都被“限定”了,訓(xùn)練前的初始值給整個模型留下了深刻的烙印并且貫穿整個訓(xùn)練過程。因為無論怎么更新,初始值已經(jīng)決定了反向傳播梯度分配的比例,W這個整體權(quán)重完全散失了“隨機(jī)探索超流形的自由性”。
深度非線性網(wǎng)絡(luò)和巨大的參數(shù)量,或許只是為優(yōu)化過程買更多的。參數(shù)越多,拓?fù)渎窂浇M合的子網(wǎng)絡(luò)越多,W就能更加細(xì)致地,發(fā)揮群體力量更加高效地探索空間,最終只是為最后的單層網(wǎng)絡(luò)權(quán)重服務(wù)(這個過程當(dāng)然也很有可能造成冗余。這種“冗余”某種程度上是有意義的,可以用計算開銷換取更快的學(xué)習(xí)速度,有粒子群優(yōu)化的味道)改日再繼續(xù)想這個優(yōu)化問題,因為是個很大的數(shù)學(xué)問題,而我只是憑借文字描述抓住一點鱗片,暫時無法更確切地描述。單單在多層非線性網(wǎng)絡(luò)和單層網(wǎng)絡(luò)之間建立辨證的數(shù)學(xué)聯(lián)系,這本身就是意義深遠(yuǎn)的事情。假如深度非線性網(wǎng)絡(luò)的存在本身就是在自由隨機(jī)地為單個線性層(沒有考慮softmax)尋找"無數(shù)"可能性,網(wǎng)絡(luò)最終可以縮并成一層,那這實在是太具有暴力美學(xué)的數(shù)學(xué)哲思。應(yīng)該可以顛覆現(xiàn)在優(yōu)化領(lǐng)域的一些常識,也可能可以開個新的方向。
這并不是說模型可以無限壓縮,只有在深度非線性網(wǎng)絡(luò)學(xué)足以學(xué)到東西的時候,我們才會繼續(xù)轉(zhuǎn)換成單層網(wǎng)絡(luò)。單層網(wǎng)絡(luò)開銷有多大還是得由當(dāng)前的深度非線性網(wǎng)絡(luò)所決定。所以,如何設(shè)計高效的深度網(wǎng)絡(luò)仍然是一個重要的課題,剪枝、蒸餾、神經(jīng)架構(gòu)搜索,動態(tài)推理網(wǎng)絡(luò),這些方向或許本質(zhì)上被某個共同的"規(guī)則"所左右,未來可能統(tǒng)一,神經(jīng)架構(gòu)搜索(NAS)可能會被廢棄(因為實在是太浪費(fèi)了,NAS本質(zhì)上是一種高度浪費(fèi)的壓縮算法)。如果說這些算法實在壓縮,那么還有必然還一種對立的,是生長型的算法。小模型性能飽和之后,可以繼續(xù)成長成更大的網(wǎng)路從而繼續(xù)壓榨更高的性能。明明是對等的產(chǎn)物,不知道為什么少有人問津。
NAS設(shè)置的超網(wǎng)搜索空間實在是太大了,打個比方,就像把食物淺嘗幾口就丟掉。獲得超網(wǎng)也并不需要這么多并行的層。最簡單的VGG本身就是一個超網(wǎng)。我的意思是說,當(dāng)訓(xùn)練階段仔細(xì)探索子網(wǎng),整個模型本身相對來說就是一個超網(wǎng)。與其嘗一口,嚼幾下就丟掉,還不如仔細(xì)咀嚼每一口。換言之:
1.需要充分地讓子網(wǎng)接受數(shù)據(jù)訓(xùn)練的洗禮
2.用有限的計算資源在最簡單的網(wǎng)絡(luò)中創(chuàng)造更多數(shù)量的子網(wǎng)。當(dāng)充分訓(xùn)練,子網(wǎng)便會“自動集成”成高性能的模型。
當(dāng)有了足夠的子網(wǎng),便意味著有了足夠的學(xué)習(xí)容量。但這還不夠,每一個子網(wǎng)(它們之間也會共享部分,難分彼此)需要“相對獨(dú)立”地進(jìn)行學(xué)習(xí)。每個子網(wǎng)地能力足夠強(qiáng),整體網(wǎng)絡(luò)性能才會更高。我們并不需要額外的操作,像ReLU這種網(wǎng)絡(luò)就是天然的子網(wǎng)采樣器。訓(xùn)練完畢,網(wǎng)絡(luò)本身就是所有子網(wǎng)的集成。
上面說過,當(dāng)所有子網(wǎng)模型都可以獨(dú)當(dāng)一面的時候,這就意味著整體網(wǎng)絡(luò)足夠健壯。那些剪枝算法只是回過頭來再選取合適的子網(wǎng),使其成為更小的獨(dú)立模型。
所以有時候,我們大概不能片面地評估一個剪枝算法一定比另一個算法更好。因為當(dāng)訓(xùn)練不充分,某些剪枝算法也會因為運(yùn)氣好(不好)(也是隨機(jī))采樣到一些優(yōu)秀(糟糕)的子網(wǎng),這樣的比較并沒有太大的意義。除非它們自己能夠證明自己是“精準(zhǔn)定位”到優(yōu)秀子網(wǎng)的。舉個例子作類比,能不能打到好的獵物取決于山林資源條件如何,獵人身手如何。在貧瘠的山林里,再強(qiáng)的獵人也不見得收獲會比菜鳥獵人更豐。明顯只有資源足夠豐富的情況下,獵人的身手才能成為關(guān)鍵。當(dāng)然也會存在一種極端情況,山林資源過于豐富,再怎么菜雞的獵人閉著眼睛亂射都能收獲滿滿。這也對應(yīng)下文所說的,隨機(jī)剪枝完全足夠,不遜色任何算法。
原則上應(yīng)該讓隨機(jī)剪枝大量采樣子網(wǎng),證明網(wǎng)絡(luò)的健壯性。再讓其剪枝算法進(jìn)行比較(比較采樣的良率,搜索時間,性能,效率等)。神經(jīng)架構(gòu)搜索(NAS)本身就可以看作是剪枝算法,但是大多數(shù)情況下NAS的超網(wǎng)太大了,不能也根本沒必要充分訓(xùn)練。再回過頭來看,如果我們已經(jīng)讓一個模型具備良好的健壯性了,花里胡哨的剪枝算法也就沒有什么太大的意義了(如果是那種剪枝,微調(diào)最后還不和相同規(guī)模的模型繼續(xù)比較那無異于掩耳盜鈴了。而且剪枝的網(wǎng)絡(luò)比大網(wǎng)絡(luò)更強(qiáng)也并不奇怪,畢竟隨機(jī)初始化,學(xué)習(xí)率主場都可能是關(guān)鍵。沒有統(tǒng)計意義的勝負(fù)也沒什么參考價值。)這個時候,隨機(jī)剪枝就足夠了,考慮到模型效率,必須是按照規(guī)則形狀的隨機(jī)剪枝。
VGG這種超網(wǎng)也可以變得強(qiáng)大。比如引進(jìn)殘差,vgg的子網(wǎng)數(shù)量就變得更多了。比如隨機(jī)深度算法,讓一些更小的子網(wǎng)能夠獨(dú)立且充分地接受數(shù)據(jù)洗禮。個人認(rèn)為上述兩條設(shè)計原則應(yīng)該可以為輕量化模型設(shè)計提供一定程度的方向性指導(dǎo)。超網(wǎng)和子網(wǎng)的辨證關(guān)系想必對深度集成理論會有所幫助。
此外,如果模型能被壓縮(剪枝,蒸餾等),性能還不下降,說明大模型本身性能不飽和。也可以說是大模型存在結(jié)構(gòu)冗余。現(xiàn)實中,我們可以利用大模型快速收斂得到不錯的性能,再想方設(shè)法利用各種奇技淫巧壓縮模型,小心翼翼地防止精度損失。其實這和本文提出地bottleneck縮并技術(shù)很類似,都要經(jīng)歷膨脹再收縮的過程。但是我覺得bottleneck(層積,模塊級,網(wǎng)絡(luò)級都可以)縮并技術(shù)更加簡潔,兩端網(wǎng)絡(luò)寬度固定,以滿足資源約束,中間盡可能大以獲得強(qiáng)大的學(xué)習(xí)能力,大到性能飽和為止,最后縮并成很窄的網(wǎng)絡(luò)即可,不需要花里胡哨的過程。這個貌似直接解決了幾年前所謂的信息瓶頸理論。(我不記得它說了什么,聽名字和bottleneck 縮并應(yīng)該還是很相關(guān)的。應(yīng)該不需要分析,直接做出來即可)。
做個實驗就很明白了。目前repo實驗代碼用的是layer級別的bottleneck設(shè)計,當(dāng)然完全可以選擇block級,甚至整個網(wǎng)絡(luò)是一個bottleneck. 理論上net級容量是最大的,可以更快壓榨性能。
ReduceNet20, 調(diào)整expansion可以控制bottleneck中間的寬度,3個模型最終部署成本都是一樣的,簡直是免費(fèi)的性能榨汁機(jī)。我還沒有探索expansion能有多大,有時間補(bǔ)上數(shù)據(jù)。20層只是訓(xùn)練層數(shù),之前說過了,部署的網(wǎng)絡(luò)形態(tài)是可以靈活改變的。比如,至少1x1卷積就可以消掉,網(wǎng)絡(luò)變成11層(10個3x3 conv, avgpool,FC),剩下3x3如果融合就要考慮計算量的增加自行trade-off了。硬件條件合適的話,計算量就能換更高速的模型推理。
完整訓(xùn)練代碼:https://github.com/ohmydroid/reducenet
如果是我搞錯了,別打我。發(fā)這種半成品實在是因為已經(jīng)浪費(fèi)了好幾個月在研究貌似沒有什么用的東西。
模塊代碼如下:
可以看到,模塊中只有一個激活函數(shù),即
self.scaler 就是一個不可訓(xùn)練,人為控制數(shù)值的參數(shù) \lambda\lambda 。在訓(xùn)練過程中,隨著iteration(每個mini batch)按照cosine方式從1衰減至0。訓(xùn)練結(jié)束后,這個激活函數(shù)就會退化成identity mapping(輸入等于輸出)。那么conv1,bn1,conv2,bn2四層可以融合成單層的3x3 conv。之后,把模塊首尾的殘差變成3x3卷積核的形狀,"對角線"元素填充為1(這比1x1 卷積核形狀的殘差稍微復(fù)雜一點點,不是正規(guī)的對角線,是3x3的中心點,每個通道沿著對角線,可以參考DiracNet),和3x3卷積繼續(xù)橫向融合。因為推理階段不存在任何非線性函數(shù),所以所有的線性算子橫向和縱向都可以融合,這里不再贅述。
模塊中self.scaler可以由ReduceNet的Module的參數(shù)傳入。main.py文件控制self.scaler的數(shù)值,cosine衰減。代碼如下:
以后繼續(xù)優(yōu)化:
1.和RepVGG等重參結(jié)合
2.3x3卷積可能不需要這么多,3x3卷積的數(shù)量關(guān)乎模型性能和效率,怎么尋找合適的數(shù)量值得研究
3.最大的愿望當(dāng)然是能夠想出一步到位的方案,而不是用VanillaNet這種策略
4.還沒有寫融合算子和整個網(wǎng)絡(luò)的代碼
5. 嘗試在conv旁邊多加一條殘差
6.參考BagNet, MLP-mixer, weighted sum of patches is all you need
7.我比較好奇的是究竟能不能根據(jù)訓(xùn)練結(jié)果的實時反映生成一個控制 \lambda\lambda 的信號,再讓這個新的數(shù)值再控制網(wǎng)絡(luò)形成控制閉環(huán)。
8.擁抱LORA。初聞LORA的時候我就意識到了,這東西和我從前想的多核卷積太像了,與我設(shè)想的無限可縮并的bottleneck不謀而合。總的來說,這種類似“多重宇宙”,“影分身般”的特性無處不在。比如,谷歌某個集成方法,訓(xùn)練多個模型,最后用加法融合每個模型的參數(shù),最后微調(diào)整。不過這個方法也可以看作上文所說的net級別的bottleneck縮并技術(shù)的一個稀疏子集。
9.最難的恐怕是我該如何用一套數(shù)學(xué)語言去嚴(yán)謹(jǐn)?shù)亟忉尪鄬臃蔷€性網(wǎng)絡(luò)是在尋找單層網(wǎng)絡(luò)的權(quán)重這一動態(tài)過程。
10.融合后可以繼續(xù)在現(xiàn)有網(wǎng)絡(luò)(訓(xùn)練過的ReduceNet)基礎(chǔ)上生出新的活性網(wǎng)絡(luò),可以是橫向的擴(kuò)展寬度,縱向地插入新層,甚至每個模塊能成為bottleneck中間的小網(wǎng)絡(luò),成為被縮并的對象,成就新的下一代模塊。總而言之,繼承舊網(wǎng)絡(luò),在此基礎(chǔ)上附上新網(wǎng)絡(luò)繼續(xù)擴(kuò)展學(xué)習(xí)容量,壓縮融合,嫁接生長,循環(huán)反復(fù)。
寫得有些隨意,有空再整理。
代碼模塊其實和resnet沒什么兩樣,可以自行驗證相同架構(gòu)網(wǎng)絡(luò)的效果。把conv1換成conv3,就可以和現(xiàn)有的resnet架構(gòu)完全兼容。
最后解釋一下免得讓人誤解。ReduceNet在訓(xùn)練中理論上可以無限深無限寬,但這并不意味著就模型最后一定具有無限的學(xué)習(xí)能力。部署時模型模型(都統(tǒng)一為單層網(wǎng)絡(luò)比較好了)的寬度等物理因素決定了它的能力上限,訓(xùn)練階段無限的資源投入都只是讓最終的模型無限逼近固有的能力上限。這個規(guī)律同樣適用于現(xiàn)在的大模型。沒有免費(fèi)的涌現(xiàn)。計算夠不夠久,數(shù)據(jù)夠不夠多,都是瓶頸,能量換信息所有過程都是為了逼近這個上限。突然對涌現(xiàn)這個詞語這么瘋魔,只是低估了這個上限了而已。