集成人工生命和遺傳算法自動發現神經網絡最優結構 ~ NeuralFinder

/* 版權聲明:可以任意轉載,轉載時請標明文章原始出處和作者信息 .*/

                          張俊林 黃通文 馬柏樟  薛會萍      

              

一.爲什麼要做神經網絡結構自動發現

16年年中開始,我們開始思考最優的深度神經網絡結構自動發現的問題,並在業餘時間開始逐步做些探索性的實驗。當時的出發點其實很簡單:對於解決某個機器學習任務,目前的常規做法是通過算法研發人員分析問題特性,並不斷設計修改試探深度神經網絡的結構,找到最適合解決手頭問題的網絡結構,然後通過不斷調參來獲得解決問題的最優網絡結構及其對應的參數。很明顯,這裏需要耗費研發人員大量的精力,大家知道,AI在各個行業逐步輔助和替代人是個大的發展趨勢,那麼自然就產生一個問題:在探索解決手頭問題的深度神經網絡結構方面既然耗費了大量的精力,那麼這個工作能不能讓機器自動完成呢?也就是這項工作的初衷是代替深度學習研發工程師的日常工作。我覺得這個思路是可行的,而且將來也一定是這個行業的發展趨勢,而且初步調研了一下當時還沒有發現有人發表相關的工作,有一定的前沿性,並且如果真的可行,在實際工作中也可以用起來節省人力研發成本,於是就開始想些辦法探索這個方向。

我覺得將來深度學習研發的形態不會是目前這個樣子,而應該是如下的一種場景:假設我們手頭有一個技術成熟的神經網絡自動探索最優結構的系統(比如它的名字叫NeuralFinder)的話,那麼整個研發過程不需要深度學習工程師的介入,只需要給定某個問題的訓練數據,然後啓動NeuralFinder,它會自動找到解決這個問題最好的網絡結構及其對應的參數。那麼目前身價不菲的深度學習工程師豈不是沒事可幹?換句話說會面臨失業的風險?這個問題也對也不對,雖然可能沒有參數可調,甚至神經網絡架構也不需要你去設計了,但是你可以投入精力去研發這種神經網絡自動探索系統啊,俗話說的好:上帝給你關上了一扇窗,他還會給你打開一扇門,是吧?當然,上面說的是未來的理想狀況,要真達到這種狀態一方面相關技術纔剛剛冒頭起步,另外也需要計算資源成本得大幅下降才行。

這個方向我覺得是個值得投入精力去摸索的好的探索方向,也是個深度學習工程師自己革自己命的方向,反正你不做遲早有一天別人也會這麼做。這是當時驅動我去開始摸索這個方向的初始動力。

最開始我的思路是想用遺傳算法去做這個問題,因爲遺傳方法看上去解決這個問題匹配度比較高而且也比較直觀:可以把一個具體的網絡結構看做一個生命,而構成神經網絡的基本層比如Conv卷積層,Pooling層或者BN或者非線性函數的選擇都當做構成生命的基本基因(不同的參數也可以看做不同的基因),不同的基因組合形成了不同的網絡結構,然後通過大量羣體之間遺傳變異等操作以及優勝劣汰的基本指導思想,把解決手頭問題性能比較差的網絡結構淘汰掉,性能比較好的網絡結構逐步勝出,然後直到找到最優的網絡結構爲止。

上述思路看着簡單直觀,但是有個現實的問題,因爲遺傳算法要生成大量種羣,尤其是再加上各種遺傳變異操作,所以同一時間需要的計算量是超級大的,但是我們手頭只有一臺GPU服務器,所以跑一輪估計要太久時間,這個時間成本基本無法承受。所以對這個思路進行了一些改造,然後糅合了人工生命和遺傳算法的思路來做,它的好處是運算規模基本可以通過簡單控制參數來進行調整控制,而且不像遺傳算法只有算出一批種羣才能繼續往後進行下一輪,每一步只需要計算5-10個模型就可以繼續往後進行。具體思路後面內容會介紹。

上面是原初的想法,後面我們不斷微調算法反覆試驗,到了16年年底的(對於缺乏GPU設備來說,即使初始模型規模控制在比較小,跑一輪時間確實還是比較久,基本是以周爲單位的)時候,系統基本能夠較好的自動運轉,也能在CIFAR10圖像分類數據集合和文本分類數據集合上獲得和目前手工設計的較好網絡結構相當的水準(後面會給出一些實驗數據以及自動找到的好的網絡結構)。本來是打算在初步想法得到驗證後,引入複雜算法進一步實驗看是否能發表,結果16年年底17年年初已經發現陸續開始出現這方面的論文(比如Google的這篇投往ICLR 2017 的用增強學習做的文章:NEURAL ARCHITECTURE SEARCH WITH REINFORCEMENT LEARNING MIT發佈的論文DESIGNING NEURAL NETWORK ARCHITECTURES USING REINFORCEMENT LEARNING;以及今年3月份發出來的Google的同一批人用遺傳算法來做的論文:Large-Scale Evolution of Image Classifiers),考慮到我們採用的方法比較簡單,所以看到增強學習的思路後基本放棄了發表的念頭,但是另外考慮到在這上面還是花了精力,而且方法和目前已經出現的方法有區別,另外我自己工作很快會發生變動,可能會放棄這個方向的進一步探索,所以最終還是考慮以這種方式發出來,供有興趣繼續進行探索的同學參考。這裏我再強調一點,我認爲這是一個值得關注的好的探索方向,代表了未來的趨勢而且剛剛冒頭還有大量問題需要解決,其它原因上面說過了。


二.集成人工生命和遺傳算法思想的最優網絡結構發現


上文簡單說明了基本思路,雖然很直觀,但是如果仔細考慮,你會發現需要探索的網絡結構組合空間的大小還是很恐怖的。

 

2.1 探索空間的巨大性及簡化工作


對比目前人工設計的卷積神經網絡,諸如LeNet網絡,ImageNet,VGG16,VGG19,All-CNNs,NIN,ResNet,GoogleNet,FractalNet,DenseNet等結構,很容易發現這些卷積神經網絡的結構都是由一些不同類型的層構成基礎的結構單元,然後基礎結構單元通過不斷複製組成了深層神經網絡結構,一般而言卷積神經網絡的基本結構由以下部分組成:

  1. 卷積層: 卷積層含有的屬性包括卷積核個數nb_filter,卷積核的大小(長和高的大小),初始化方式,卷積移動stride步數,border_mode模式(same或者valid)。

  2. 激活函數層: 激活函數層的類型可以取值爲tanh,sigmoid,relu任意一種及其各種變體,目前最常用的一般是Relu及其變體;

  3. Pooling層: Pooling層的屬性包括大小即length取值長度,移動的步數stride,padding數目,還有Pooling類型比如MaxPooling,AveragePooling等。

  4. 全連接層: 主要的變化點是隱層單元的個數以及激活函數的類型;

  5. 分類層: 同全連接一樣,只不過隱層單元個數爲類標籤的個數;

  6. Dropout層: 正則化係數,主要指的是丟棄神經元的比例;

  7. BatchNormatization層: 主要是每批訓練的每個樣本減去批內數據的均值,除以批內數據的方差,再乘以alpha加上beta係數,主要變化點爲alpha和beta係數。

  8. Skip     Connection: 主要指的是CNN網絡結構上的層間跳躍,在低層與高層之間建立“捷徑”,從ResNet以及後續許多帶shortcuts結構的模型可以知道,帶有這種結構的網絡結構效果會明顯好於傳統結構。

如果完全利用以上基礎的層結構進行組合形成深層CNN網絡結構,很明顯其參數空間是巨大無比的,是一個NP難問題。 假設一個d層神經網絡,層的類型個數爲s,每層含有k個屬性,每個屬性的取值爲t個,那麼其搜索空間的範圍爲:(skt)d , 這個數字是相當大的,比如針對10層的神經網絡,5種類型層,每層含有3個屬性,每個屬性取值5個,那麼結構的個數爲7510 =1017.8。這個空間的搜索範圍是很恐怖的。

當時爲了驗證思路的可行性,所以考慮一切從簡,先驗證思路可行再考慮引入更多類型的層及參數變化並引入更爲複雜的模型,所以當時儘可能地步減少搜索空間範圍,初步的實驗我們做了如下的簡化處理和一些約定:

   1. 卷積層中由於屬性較多,stride固定設置爲1, border_mode模式設置爲same即經過卷積不改變大小,卷積層的權值初始化方式爲隨機取值。

   2. 激活函數的使用過程中默認和卷積層綁定,不作爲獨立一層,理想的方式應該將激活函數當做單獨的一層處理,這樣可以在其中插入BN操作,同時將BN當做另外的獨立層,這樣產生的網絡結構會更靈活,爲了簡化問題,我們約定激活函數和卷積層綁定,而且激活函數的類型固定住,在卷積層使用relu,分類層使用softmax激活函數。

   3. Dropout用於全連接層,設定固定值0.5。

   4. Pooling層設大小統一置爲2,strides的大小等於pooling的大小,使用的是MaxPooling,不考慮其它類型,這也是目前最常見的類型。

   5. 不考慮Skip-Connnection和BatchNormalization操作,簡少搜索空間。

   6. 全連接層默認固定爲512個隱層神經單元。

   7. 分類層上加一個正則化約束因子L2,防止過擬合。

   8. 訓練時迭代次數設置100次,加入早停機制,即如果10次性能不提高,終止訓練,這是爲了加快單次探索的速度,所以只採用一種粗粒度的訓練和性能評估。

綜上所述,經過上述大量簡化,模型探索過程的主要變化點來自於卷積層的filter個數大小和MaxPooling層的個數和在CNN中的不同位置。爲了進一步簡化問題,這裏我們將CNN卷積層filter個數設置爲取16,32,48,96,128,196,256,512中的某個值。

儘管如此,假設單獨考慮10層模型,並且不考慮其間插入pooling層的情況下,上面8種filter的搜索空間的個數爲:810 ,相對而言訓練的模型的個數還是比較多的。


2.2人工生命和遺傳算法思想

 

2.2.1基礎思想

 

    人工生命結合遺傳算法的基礎思想其實非常簡單我們以下面兩個圖形來說明。

                        1.人工生命的4*4二維生存世界


   我們首先模仿類似人工生命的思路,假設人工生命的生存世界是如圖1所示的4*4大小的二維格子,每個格子裏面居住一個人工生命,在我們的問題裏,每個人工生命就是某個深度神經網絡的網絡結構,每個人工生命網絡結構都不同,而通過訓練數據訓練後使用驗證集可以測試出每個生命的性能,這個性能代表其在生存世界的生存能力,性能越高代表自身存活並繁衍後代的可能性就越大,通過在人工生命的生存世界裏不斷的優勝劣汰並逐步進化的過程,能夠在幾乎無限大小的網絡結構空間裏面逐步向性能好的網絡結構進化,最終性能好的生命會淘汰掉性能差的生命並充斥整個生存世界。

2.遺傳算法進化


   上述是其基本思想,圖2展示了具體的一輪進化過程,一般在人工生命的生存世界中隨機選擇一個格子的生命作爲“主生命”,另外在主生命的鄰居範圍隨機選擇一個“輔生命”,然後以這兩個生命作爲後續進化基礎,通過遺傳算法產生新的網絡結構,進化出更好的生命,淘汰掉局部範圍內性能差的生命,這樣就完成了一輪進化操作。通過進化操作使得性能好的網絡結構增加在生存世界存活的概率,同時逐步淘汰掉性能差的網絡結構。

以上就是結合人工生命和遺傳算法自動最優探索網絡結構的基本思想。因爲我們去年做這個事情的初步的實驗目的是驗證模型的可行性,所以會盡量減少進化過程中基礎遺傳操作的類型,原先的考慮是驗證模型可行再引入更復雜的基礎操作步驟。

 

我們定義了最基本的遺傳操作如下:


2.2.2基礎遺傳操作定義


  1. 基因片段的自我複製.

      這個操作的引入主要是借鑑類似於VGG或者ResNet等結構,這些網絡結構都是由人工定義的基礎Block反覆疊加產生的,爲了能夠產生類似結構,所以引入了網絡子結構的自我複製操作。


  2. 基因片段的交叉組合。

      基因交叉是遺傳算法中的典型操作。以某個神經網絡結構個體序列S1=a1_a2_a3_a4和個體序列S2=b1_b2_b3_b4爲例,它們進行交叉組合的種類是比較多的,這裏採用的策略是:隨機分別在個體序列S1和S2之間選擇交叉點p1,p2.假設p1=a2,p2=b3,那麼它們產生的交叉個體爲:

       a1_a2_b3_b4,

        a1_a2_b1_b2,

       b1_b2_a1_a2,

       b1_b2_a3_a4

       這四個交叉組合個體。


  3. 變異操作。

     基因變異也是遺傳算法典型操作。假設個體的序列爲a1_a2_a3_a4,那麼隨機產生一個變異點,比如說變異點發生在a2位置,這裏有兩種情況:

      如果a2是一個MaxPooling層,那麼變異操作空操作,即原始基因保持不變;

      如果a2是conv卷積層,其屬性卷積核filter個數是f1,那麼在之前的filter可選集合S中去掉f1隨機選擇,即{S-f1}中任意的一個元素作爲變異操作的結果,也就是說將卷積層的卷積核個數作爲變異內容。


2.2.3自動網絡結構尋優的關鍵步驟


採取如下步驟來完成人工生命+遺傳算法的進化過程:


step1. 人工生命初始化步

人工生命生存世界二維格子大小可以自由設定大小比如L×L,最初的生命基因片段只包含單層的卷積層或單層的MaxPooling層,可以按照一定比例配置兩者的個數配比,比如70%是Conv層,30%是MaxPooling層,但是考慮到輸入層如果是MaxPooling性能都比較差,所以在MaxPooling層前可以先套上隨機個數卷積核的卷積層。初始化過程隨機將這些簡單基因片段組成的神經網絡生命分配到L×L大小的二維格子中,填充整個L×L個空間的單元格,針對這L×L個個體分別進行訓練,使用驗證集得到對應網絡結構性能得分。如此就完成了人工生命的初始化步驟。


step2. 人工生命進化步

 1. 隨機選擇一個個體s1作爲“主生命”(這一步是可以優化成給予目前性能較好的生命體更高的被選中概率,這樣會加快進化速度),以s1爲中心點選擇一個半徑爲d的局部區域(一般選擇二維格中相鄰格子中的個體),在除去s1的d*d-1個局部區域中隨機選擇另外一個個體s2,s2被稱爲“輔生命”。之所以有主輔之分,從其命名也可以看出,其中一個是進化的核心,另外一個是輔助進化的生命個體。在這裏,我們假設“主生命”s1的模型層次序列爲a1_a2_a3_a4, “輔生命”s2的序列爲b1_b2_b3_b4;


 2. “主生命”的自身複製

    以“主生命”s1進行自身基因複製操作,產生一個新的個體s3=a1_a2_a3_a4_a1_a2_a3_a4,進行訓練後通過驗證集獲得其性能得分,假設其性能爲p3.


 3. 主輔生命基因交叉組合

     如上面提到的基本操作部分,對主輔生命兩個基因進行隨機的交叉組合產生4個個體,訓練後分別通過驗證集獲得其性能得分,假設爲c1,c2,c3,c4.


 4. 選擇性能表現較好的組合或者自身複製出的新個體,記最好的生命性能得分爲max_c,即max_c=max{p3,c1,c2,c3,c4}。

   這時可能出現如下三種情況:

    a. 如果max_c比“主生命”s1的性能要差,說明目前選中的“主生命”性能比較好,那麼本輪進化不做任何操作,直接跳到step2,進行下一輪進化操作;

    b. 如果max_c比“主生命”s1的性能要好,但比“輔生命”s2的性能要差,這時max_c的網絡結構替換掉s1的網絡結構,意味着性能較差的“主生命”被新生命淘汰掉,然後進行第5步的基因變異操作;

    c. 如果max_c比“主生命”s1的性能要好,也比“輔生命”s2的性能要好,這時max_c的網絡結構替換掉“主生命”s1的結構,同時也替換掉“輔生命”s2的結構,意味着性能較差的“主生命”和“輔生命”同時被新生命淘汰掉,然後進行第5步的基因變異步操作;


 5. 基因變異操作

在s1附近的局部種羣中,除去“主生命”和“輔生命”s1,s2外,隨機選擇出局部區域中兩個性能最差的個體L1,L2,使用max_c的網絡結構替換掉L1和L2的網絡結構後進行變異操作,就是把卷積層的卷積核個數隨機變化掉。這步的意思是加快優秀基因個體在種羣中的傳播,通過增加優秀基因個數並淘汰局部範圍內較差基因的方式來達成這個目的。同時,爲了能夠探索更多的網絡結構空間,將目前找到的優秀基因進行變異。

 

以上就是人工生命結合遺傳算法進行進化操作的步驟,從上面的流程描述可以看出,這種結合人工生命和遺傳算法的方法好處是一次進化步驟只需要產生10個以內的新結構,然後可以進入下一次進化過程,當然,理論上完全可以把上述過程並行化來加快進化過程,比如多GPU的情況下,可以同時隨機選擇K個“主生命”同時計算加快速度。但是上文說過,之所以選擇這種方式正是因爲我們只有一個GPU服務器,所以爲了保證算法能夠跑起來被迫採取這種方式,就是把遺傳算法的種羣這種大量並行計算給消解掉了使得其能夠串行運行。


   另外需要說明的是:上述過程中存在優秀生命個體淘汰落後生命個體的過程,淘汰標準是對這個網絡結構在驗證集上的性能比較來進行的,性能好的生命個體就是優秀生命個體。這裏存在一個性能比較標準問題,比如一個網絡性能是0.8253,另外一個是0.8252,其實兩者性能差異並大,可以認爲相當,不足以說明哪個性能更好,所以使用模型性能的相對比率進行度量和比較,即兩個模型的得分爲s1,s2,如果s1>s2 並且abs(s1-s2)/s2>r, 則認爲s1的性能比s2好。


三.實驗結果及分析


3.1實驗配置


·  數據集

CIFAR10數據集,50000訓練和10000測試,10個類別。


·  單次訓練的參數統一設置

  - 訓練算法的選擇:

    帶動量的隨機梯度下降算法,使用nesterov進行初始化,初始學習率設置爲0.01,動量因子0.9,衰減因子設置爲1e-6。

  - 誤差函數

    誤差函數選擇交叉熵,度量指標爲準確率。      

  - 結構參數:

    訓練次數設置100次,設置早停,10次性能不提高終止訓練。

    固定模型的全連接層的隱層單元爲512個,dropout=0.5,分類層標籤數爲10。


·  進化過程參數設置

  - 基礎算子的選擇:

    卷積層的filter選擇了16,32,64,96,128,196,224,256,512.

    pooling層,默認設爲2,stride設置也爲2

  - 進化次數設置150次

  - 性能比較比率設置爲0.02

- 二維格子大小設定爲7*7或9*9大小


·  數據處理說明

  - 數據增強:

    進行旋轉操作,水平和豎直方向進行平移操作;

  - 數據處理:

    零均值規範化處理;

 

3.2自動找出的TOP性能網絡結構


    因爲條件所限以及目的主要是探索思路可行性,所以我們設定的二維格都比較小一般採取7*7或者9*9大小,最終跑出來大約1000多個各種基因組成的CNN結構,很明顯這個數據量相對可能組合出的CNN結構來比可說是滄海一粟,但是經過優勝劣汰,性能得分前列的模型表現還是不錯的,基本可以進入目前人工設計出的最好的神經網絡結構之列,其中效果最好的模型在CIFAR10數據集上性能達到了92.70%的準確率,自動找出的性能TOP 20的網絡結構準確率都超過了91%(本文附件列出了性能TOP 15的神經網絡模型結構)。其中,性能最好的模型長這個樣子:

   ('init-1', '0.927000', [('conv', [('nb_filter', 32)]), ('conv',[('nb_filter', 192)]), ('conv', [('nb_filter', 192)]), ('maxp', [('pool_size', 2)]),('conv', [('nb_filter', 128)]), ('conv', [('nb_filter', 192)]), ('maxp',[('pool_size', 2)]), ('conv', [('nb_filter', 128)]), ('conv', [('nb_filter',192)]), ('conv', [('nb_filter', 192)]), ('maxp', [('pool_size', 2)]), ('conv',[('nb_filter', 128)]), ('conv', [('nb_filter', 192)]), ('maxp', [('pool_size',2)])])


這是模型的主體,最後再拼接上512個隱層神經單元的全連接層和10分類的分類層即可。 其中('conv', [('nb_filter', 32)])代表第一層是卷積層,卷積核個數爲32,而('maxp', [('pool_size', 2)])代表MaxPooling層,大小爲2。

   

3.3相關實驗性能比較


    目前人工設計的比較常見的神經網絡有包括VGG,NIN,ALL-CNN,ResNet,DenseNet等等,其性能情況參考如下兩個表格:

       表1:目前CIFAR10上最常見的深度神經網絡性能及Google使用增強學習自動探索網絡結構性能(From paper: NEURAL ARCHITECTURE SEARCH WITH REINFORCEMENT LEARNING)

 

2:目前CIFAR10上最常見的深度神經網絡性能及MITMetaQNN自動探索網絡結構性能(From paper: DESIGNING NEURAL NETWORK ARCHITECTURES USING REINFORCEMENT LEARNING)


從數據上看,人工生命結合遺傳算法的實驗中找出的性能最好的網絡結構對應的誤差率爲7.30(考慮到我們資源有限,只跑了1000多組不同網絡結構,如果在更充分的計算資源支持條件下應該能夠找到性能更好的網絡結構)。

首先,和人工設計的神經網絡對比,一個特點是其結果要比highway,NIN,maxout,FitNet等人工設計的結構要好,與VGG和All-CNNs相比性能相當,但是比ResNet,Wide ResNet及DenseNet這些帶有Skip Connection的網絡結構相比仍然有差距。

     另外,如果和MIT的MetaQNN和Google的RL方法比的話,會發現比MetaQNN找出的最優結構性能(誤差率6.92)稍差,但是MetaQNN找出的性能最優的TOP 10結構中,除了最好的結構外,其它結構性能都比較差,參考如下結果:

表3:MIT的MetaQNN性能TOP 5的網絡結構性能


所以人工生命+神經網絡方法TOP性能結構整體性能是要優於MetaQNN的,就是說能夠找到更多平均性能更好的網絡結構。

而Google的RL方法找出的最優網絡結構性能明顯要好(不同方法找出的最優結構性能誤差率在3.84到6.01之間),與其另一篇採用遺傳算法論文找出的最優結構性能(最優結構誤差率5.4)比也有較大差距。Google的這兩個方法在構建網絡結構的時候都引入了Skip Connection 結構,而我們的方法及MIT的MetaQNN的方法都沒有引入Skip Connection,有理由相信如果在網絡結構自動生成過程中引入Skip Connection會明顯增加網絡性能。

 另外,如果看一下自動找出的神經網絡結構和人工設計的網絡結構的差異來說,也有很明顯的區別。從附錄的TOP 15網絡結構和常見的人工設計的網絡結構對比,可以看出有以下幾個特點:

首先,自動生成的性能較好的網絡結構和人工設計的結構差異比較大,存在conv_conv_conv_maxp,conv_conv_maxp,conv_conv_conv_conv_maxp等不規則BLOCK結構交叉組合出現的情況,而且其具體的卷積核filter個數參數不規則,人工設計網絡結構往往會重複相同配置的BLOCK結構,很難去設計這種不規則的結構。但是從另外一個角度也說明了,也許這種不規則的組合能更容易找到更好的結構,這一點人工設計很難做到。

其次,從生成網絡結構的深度也就是層數看,VGG結構最少是16層,ResNet常規的會有50多到100層,其它人工設計的網絡結構一般卷積層都比較深,而自動發現的性能較好的網絡結構一般都不太深,大部分介於5到10個卷積層,層數要明顯少。

結合上面兩個區別可以看出:自動生成網絡結構更容易找出那些網絡結構不規則但是層數較淺的性能較好的網絡結構,而人工設計的網絡結構因爲結構的規則性,所以可能必須層數更深才能達到類似的性能。這是兩者最主要的區別。


附錄:利用上述方法找到的CIFAR10圖像分類問題的TOP-15網絡結構


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章