自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何用自動(dòng)機(jī)器學(xué)習(xí)實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)進(jìn)化

移動(dòng)開發(fā) 深度學(xué)習(xí)
對(duì)大多數(shù)從事機(jī)器學(xué)習(xí)工作的人來說,設(shè)計(jì)一個(gè)神經(jīng)網(wǎng)絡(luò)無異于制作一項(xiàng)藝術(shù)作品。在本文中,我將介紹一個(gè)使用進(jìn)化算法優(yōu)化CNN超參數(shù)的例子。

對(duì)大多數(shù)從事機(jī)器學(xué)習(xí)工作的人來說,設(shè)計(jì)一個(gè)神經(jīng)網(wǎng)絡(luò)無異于制作一項(xiàng)藝術(shù)作品。神經(jīng)網(wǎng)絡(luò)通常始于一個(gè)常見的架構(gòu),然后我們需要對(duì)參數(shù)不斷地進(jìn)行調(diào)整和優(yōu)化,直到找到一個(gè)好的組合層、激活函數(shù)、正則化器和優(yōu)化參數(shù)。在一些知名的神經(jīng)網(wǎng)絡(luò)架構(gòu),如VGG、Inception、ResNets、DenseNets等的指導(dǎo)下,我們需要對(duì)網(wǎng)絡(luò)的變量進(jìn)行重復(fù)的操作,直到網(wǎng)絡(luò)達(dá)到我們期望的速度與準(zhǔn)確度。隨著網(wǎng)絡(luò)處理能力的不斷提高,將網(wǎng)絡(luò)優(yōu)化處理程序自動(dòng)化變得越來越可行。

在像Random Forests和SVMs這樣的淺模型中,我們已經(jīng)能夠使超參數(shù)優(yōu)化的操作自動(dòng)化進(jìn)行了。一些常用的工具包,比如sk-learn,向我們提供了搜索超參數(shù)空間的方法。在其最簡(jiǎn)單的、最基礎(chǔ)的格式中,“超參數(shù)”是我們?cè)谒锌赡艿膮?shù)中搜索得到的,或者是通過從參數(shù)分布中任意采樣得到的。(詳情請(qǐng)點(diǎn)擊此鏈接查看。)這兩種方法都面臨著兩個(gè)問題:***,在錯(cuò)誤參數(shù)區(qū)域進(jìn)行搜索時(shí)會(huì)造成資源浪費(fèi);第二,處理大量的動(dòng)態(tài)特征參數(shù)集將導(dǎo)致效率過低。因此,改變處理器的架構(gòu)變得相當(dāng)困難。雖然現(xiàn)在有很多看似高效的方法,比如Bayesian優(yōu)化方法。但Bayesian優(yōu)化法雖然能夠解決了***個(gè)問題,卻對(duì)第二個(gè)問題無能為力;另外,在Bayesian優(yōu)化設(shè)置中也很難進(jìn)行探索模型。

自動(dòng)識(shí)別***模型的想法就現(xiàn)在來說已經(jīng)不算新鮮了,再加上最近大幅度提升的處理能力,實(shí)現(xiàn)這一想法比以往任何時(shí)候都要容易。

問題設(shè)定

考慮超參數(shù)優(yōu)化的方式之一,就是將它看做一個(gè)“元學(xué)習(xí)問題”。

我們究竟能否打造出一個(gè)可以用于判斷網(wǎng)絡(luò)性能好壞的算法呢?

注意:接下來我將繼續(xù)使用“元學(xué)習(xí)”這個(gè)術(shù)語,即使將這個(gè)問題描述為“元學(xué)習(xí)”有點(diǎn)混淆視聽,但我們千萬不能把它與“學(xué)習(xí)”相關(guān)的一些方法弄混了。

 

元學(xué)習(xí)

我們的目標(biāo)是定義網(wǎng)絡(luò)隱含層(綠色)的數(shù)量以及每個(gè)隱含層的參數(shù)。

具體而言,就是探究模型架構(gòu)和模型的參數(shù)空間,從而在給定的數(shù)據(jù)集上優(yōu)化其性能。這個(gè)問題復(fù)雜難解,而回報(bào)稀薄。之所以說它回報(bào)稀薄,是因?yàn)槲覀冃枰獙?duì)網(wǎng)絡(luò)進(jìn)行足夠的訓(xùn)練,還要對(duì)它進(jìn)行評(píng)估;而在訓(xùn)練、評(píng)估完成后,我們得到回報(bào)的僅僅是一些得分。這些得分反映了整個(gè)系統(tǒng)的性能表現(xiàn),而這種類型的回報(bào)并不是可導(dǎo)函數(shù)!說到這,是不是讓你想起了什么呢?沒錯(cuò),這就是一個(gè)典型的“強(qiáng)化學(xué)習(xí)”情境!

維基百科對(duì)“強(qiáng)化學(xué)習(xí)”的定義:

“強(qiáng)化學(xué)習(xí)”(RL)是一種重要的機(jī)器學(xué)習(xí)方法,它的靈感來自于心理學(xué)的行為主義理論。具體來說,“強(qiáng)化學(xué)習(xí)”是關(guān)于有機(jī)體(agent)如何在環(huán)境(environment)的刺激下,將累計(jì)獎(jiǎng)勵(lì)***化的方法。

“強(qiáng)化學(xué)習(xí)”與標(biāo)準(zhǔn)的監(jiān)督式學(xué)習(xí)之間的區(qū)別在于它不需要出現(xiàn)正確的輸入或輸出對(duì),也不需要精準(zhǔn)校正其次優(yōu)化行為。另外,“在線性能”也是“強(qiáng)化學(xué)習(xí)”關(guān)注的焦點(diǎn),即在未知領(lǐng)域的探索與現(xiàn)有知識(shí)的開發(fā)之間找到平衡。

 

上圖情境中的有機(jī)體(agent)是一個(gè)模型,環(huán)境(environment)就是我們用于訓(xùn)練和評(píng)估的數(shù)據(jù)集。解釋器(interpreter)是對(duì)每一行為進(jìn)行分析以及設(shè)置有機(jī)體狀態(tài)(在我們這個(gè)情境中,解釋器設(shè)置的是網(wǎng)絡(luò)參數(shù))的過程。

通常情況下,“強(qiáng)化學(xué)習(xí)”問題都被定義為一個(gè)Markov決策過程。其目的就是優(yōu)化有機(jī)體的總回報(bào)。每一步,你需要對(duì)優(yōu)化模型輸出作出決策,或者是探索出一個(gè)新的行為。在環(huán)境的刺激下,有機(jī)體將根據(jù)得到的反饋,形成一個(gè)調(diào)整政策,不斷改進(jìn)其行為。

注意:這個(gè)話題超出了本文討論的范圍,R.Sutton和A. Barto的《強(qiáng)化學(xué)習(xí)介紹》可能是關(guān)于這個(gè)主題的***入門指導(dǎo)書。

進(jìn)化算法

進(jìn)化算法

解決“強(qiáng)化學(xué)習(xí)”問題的另一種方法是“進(jìn)化算法”。在生物進(jìn)化的啟發(fā)下,進(jìn)化算法通過創(chuàng)建一個(gè)解決方案的集合,尋找解決方案的空間;然后,它會(huì)對(duì)每一解決方案進(jìn)行評(píng)估,并根據(jù)評(píng)估得分不斷調(diào)整這個(gè)方案集合。生物進(jìn)化論中所講的“進(jìn)化”涉及到一個(gè)種群中***成員的選擇和變異。因此,我們的解決方案集合也會(huì)不斷進(jìn)化發(fā)展,以提高其整體適應(yīng)性,并為問題找到提供可行的解決方案。

 

進(jìn)化算法中的“進(jìn)化”

上圖的左邊介紹了進(jìn)化的過程,設(shè)計(jì)一個(gè)“進(jìn)化算法”涉及到兩個(gè)部分——“選擇”,以及需要遵循的“跨界”或“變異”策略。

“選擇”:對(duì)于“選擇”,我們通常的做法是挑選***的個(gè)體和一些任意的個(gè)體,以達(dá)到多樣性。更先進(jìn)的選擇方法是在種群下設(shè)立不同的“次群”,即“物種”;然后在物種中選擇***的個(gè)體,以保護(hù)其多樣性。另一種比較受歡迎的做法是“競(jìng)賽選擇”,即任意選擇一些個(gè)體參與競(jìng)賽,挑選出勝者(基因優(yōu)勝的個(gè)體)。

“跨界”:“跨界”也稱“交叉跨界”,指的是兩組或兩組以上親本交叉混合,產(chǎn)生后代。“交叉跨界”高度依賴于問題結(jié)構(gòu)的方式。常見的方法是用一個(gè)項(xiàng)目列表(一般是數(shù)值)對(duì)親本進(jìn)行描述,然后從親本中挑選任意部分來生成新的基因組合。

“變異”:“變異”或“突變”指的是任意改變基因組的過程。這是主要的開發(fā)因素,有助于保持種群的多樣性。

實(shí)施啟用

“進(jìn)化算法”的實(shí)施啟用使用了PyTorch來建立代理,這個(gè)代理將會(huì)探索用于完成簡(jiǎn)單分類任務(wù)的DNNs。這個(gè)實(shí)驗(yàn)使用的是MNIST,因?yàn)樗∏铱?,即使在CPU上也能完成訓(xùn)練。我們將建立一組DNN模型,并將其發(fā)展進(jìn)化為N個(gè)步驟。

我們所講的“進(jìn)化”主題實(shí)際上就是“物競(jìng)天擇”的實(shí)施,完整的高水平“進(jìn)化算法”如下所示:

  1. new_population = [] 
  2.   while size(new_population) < population_size: 
  3.   choose k(tournament) individuals from the population at random 
  4.   choose the best from pool/tournament with probability p1 
  5.   choose the second best individual with probability p2 
  6.   choose the third best individual with probability p3 
  7.   mutate and append selected to the new_population 

附注:當(dāng)涉及到架構(gòu)合并時(shí),跨界問題就變得相當(dāng)復(fù)雜了。究竟該如何將兩個(gè)親本的架構(gòu)合并呢?缺陷圖樣及環(huán)境整合訓(xùn)練將對(duì)此產(chǎn)生什么影響呢?近期的一篇來自Miikkulainen等人的論文提出了一種被稱為CoDeepNEAT的解決方案。基于Evolino進(jìn)化理論,一個(gè)架構(gòu)由部分單元模塊組成,其中的每一單元模塊都是服從于進(jìn)化理論的。這個(gè)架構(gòu)是一個(gè)合并了所有組成成分的理想藍(lán)圖。在這樣的情境下,將親本的組成成分混合是十分合理的,因?yàn)槠涑煞质且粋€(gè)完整的微型網(wǎng)絡(luò)。為了使文章更簡(jiǎn)潔易懂,我在這個(gè)算法實(shí)施過程中避開了跨界交叉的問題,而是簡(jiǎn)單介紹了類似NEAT(或CoDeepNEAT)這樣的解決方案。(我打算在下一篇文章中詳細(xì)介紹這些解決方案。)

基本的構(gòu)件

我們需要定義的***件事情就是每一模型的解決方案空間,每一個(gè)個(gè)體都代表著一個(gè)架構(gòu)。簡(jiǎn)潔起見,我們堆疊了n層,每一層都包含三個(gè)參數(shù):a)隱藏單元的數(shù)量;b)激活類型;c)丟失率。對(duì)于通用參數(shù),我們?cè)诓煌膬?yōu)化器、學(xué)習(xí)率、權(quán)重衰減和層數(shù)量中進(jìn)行選擇。

  1. # definition of a space 
  2. # lower bound - upper bound, type param, mutation rate 
  3. LAYER_SPACE = dict() 
  4. LAYER_SPACE['nb_units'] = (128, 1024, 'int', 0.15) 
  5. LAYER_SPACE['dropout_rate'] = (0.0, 0.7, 'float', 0.2) 
  6. LAYER_SPACE['activation'] =\ 
  7.    (0,  ['linear', 'tanh', 'relu', 'sigmoid', 'elu'], 'list', 0.2) 
  8.  
  9. NET_SPACE = dict() 
  10. NET_SPACE['nb_layers'] = (1, 3, 'int', 0.15) 
  11. NET_SPACE['lr'] = (0.0001, 0.1, 'float', 0.15) 
  12. NET_SPACE['weight_decay'] = (0.00001, 0.0004, 'float', 0.2) 
  13. NET_SPACE['optimizer'] =\ 
  14.    (0, ['sgd', 'adam', 'adadelta', 'rmsprop'], 'list', 0.2) 

完成以上操作以后,我們已經(jīng)定義了模型的空間。接著我們還需要建立三個(gè)基本功能:

隨機(jī)選擇一個(gè)網(wǎng)絡(luò)

  1. def random_value(space): 
  2.    """Sample  random value from the given space.""" 
  3.    val = None 
  4.    if space[2] == 'int': 
  5.        val = random.randint(space[0], space[1]) 
  6.    if space[2] == 'list': 
  7.        val = random.sample(space[1], 1)[0] 
  8.    if space[2] == 'float': 
  9.        val = ((space[1] - space[0]) * random.random()) + space[0] 
  10.    return {'val': val, 'id': random.randint(0, 2**10)} 
  11.  
  12.  
  13. def randomize_network(bounded=True): 
  14.    """Create a random network.""" 
  15.    global NET_SPACE, LAYER_SPACE 
  16.    net = dict() 
  17.    for k in NET_SPACE.keys(): 
  18.        net[k] = random_value(NET_SPACE[k]) 
  19.     
  20.    if bounded:  
  21.        net['nb_layers']['val'] = min(net['nb_layers']['val'], 1) 
  22.     
  23.    layers = [] 
  24.    for i in range(net['nb_layers']['val']): 
  25.        layer = dict() 
  26.        for k in LAYER_SPACE.keys(): 
  27.            layer[k] = random_value(LAYER_SPACE[k]) 
  28.        layers.append(layer) 
  29.    net['layers'] = layers 
  30.    return net 

首先,我們?nèi)我獾貙?duì)層數(shù)量和每一層的參數(shù)進(jìn)行采樣,樣本值會(huì)在預(yù)先定義好的范圍邊緣內(nèi)出現(xiàn)下降。在初始化一個(gè)參數(shù)的同時(shí),我們還會(huì)產(chǎn)生一個(gè)任意的參數(shù)id。現(xiàn)在它還不能使用,但我們可以追蹤所有的層。當(dāng)一個(gè)新的模型發(fā)生突變時(shí),舊的層會(huì)進(jìn)行微調(diào),同時(shí)僅對(duì)發(fā)生突變的層進(jìn)行初始化。這樣的做法應(yīng)該能夠顯著地加快速度,并穩(wěn)定解決方案。

注意:根據(jù)問題性質(zhì)的不同,我們可能需要不同的限制條件,比如參數(shù)的總量或?qū)拥目倲?shù)量。

使網(wǎng)絡(luò)發(fā)生變異

  1. def mutate_net(net): 
  2.    """Mutate a network.""" 
  3.    global NET_SPACE, LAYER_SPACE 
  4.  
  5.    # mutate optimizer 
  6.    for k in ['lr', 'weight_decay', 'optimizer']: 
  7.         
  8.        if random.random() < NET_SPACE[k][-1]: 
  9.            net[k] = random_value(NET_SPACE[k]) 
  10.             
  11.    # mutate layers 
  12.    for layer in net['layers']: 
  13.        for k in LAYER_SPACE.keys(): 
  14.            if random.random() < LAYER_SPACE[k][-1]: 
  15.                layer[k] = random_value(LAYER_SPACE[k]) 
  16.    # mutate number of layers -- RANDOMLY ADD 
  17.    if random.random() < NET_SPACE['nb_layers'][-1]: 
  18.        if net['nb_layers']['val'] < NET_SPACE['nb_layers'][1]: 
  19.            if random.random()< 0.5: 
  20.                layer = dict() 
  21.                for k in LAYER_SPACE.keys(): 
  22.                    layer[k] = random_value(LAYER_SPACE[k]) 
  23.                net['layers'].append(layer) 
  24.                # value & id update 
  25.                net['nb_layers']['val'] = len(net['layers']) 
  26.                net['nb_layers']['id'] +=1 
  27.            else: 
  28.                if net['nb_layers']['val'] > 1: 
  29.                    net['layers'].pop() 
  30.                    net['nb_layers']['val'] = len(net['layers']) 
  31.                    net['nb_layers']['id'] -=1 
  32.    return net 

每一個(gè)網(wǎng)絡(luò)元素都存在變異的可能性,每一次變異都將重新采樣參數(shù)空間,進(jìn)而使參數(shù)發(fā)生變化。

建立網(wǎng)絡(luò)

  1. class CustomModel(): 
  2.  
  3.    def __init__(self, build_info, CUDA=True): 
  4.  
  5.        previous_units = 28 * 28 
  6.        self.model = nn.Sequential() 
  7.        self.model.add_module('flatten', Flatten()) 
  8.        for i, layer_info in enumerate(build_info['layers']): 
  9.            i = str(i) 
  10.            self.model.add_module( 
  11.                'fc_' + i, 
  12.                nn.Linear(previous_units, layer_info['nb_units']['val']) 
  13.                ) 
  14.            self.model.add_module( 
  15.                'dropout_' + i, 
  16.                nn.Dropout(p=layer_info['dropout_rate']['val']) 
  17.                ) 
  18.            if layer_info['activation']['val'] == 'tanh': 
  19.                self.model.add_module( 
  20.                    'tanh_'+i, 
  21.                    nn.Tanh() 
  22.                ) 
  23.            if layer_info['activation']['val'] == 'relu': 
  24.                self.model.add_module( 
  25.                    'relu_'+i, 
  26.                    nn.ReLU() 
  27.                ) 
  28.            if layer_info['activation']['val'] == 'sigmoid': 
  29.                self.model.add_module( 
  30.                    'sigm_'+i, 
  31.                    nn.Sigmoid() 
  32.                ) 
  33.            if layer_info['activation']['val'] == 'elu': 
  34.                self.model.add_module( 
  35.                    'elu_'+i, 
  36.                    nn.ELU() 
  37.                ) 
  38.            previous_units = layer_info['nb_units']['val'] 
  39.  
  40.        self.model.add_module( 
  41.            'classification_layer', 
  42.            nn.Linear(previous_units, 10) 
  43.            ) 
  44.        self.model.add_module('sofmax', nn.LogSoftmax()) 
  45.        self.model.cpu() 
  46.         
  47.        if build_info['optimizer']['val'] == 'adam': 
  48.            optimizer = optim.Adam(self.model.parameters(), 
  49.                                lr=build_info['weight_decay']['val'], 
  50.                                weight_decay=build_info['weight_decay']['val']) 
  51.  
  52.        elif build_info['optimizer']['val'] == 'adadelta': 
  53.            optimizer = optim.Adadelta(self.model.parameters(), 
  54.                                    lr=build_info['weight_decay']['val'], 
  55.                                    weight_decay=build_info['weight_decay']['val']) 
  56.  
  57.        elif build_info['optimizer']['val'] == 'rmsprop': 
  58.            optimizer = optim.RMSprop(self.model.parameters(), 
  59.                                    lr=build_info['weight_decay']['val'], 
  60.                                    weight_decay=build_info['weight_decay']['val']) 
  61.        else: 
  62.            optimizer = optim.SGD(self.model.parameters(), 
  63.                                lr=build_info['weight_decay']['val'], 
  64.                                weight_decay=build_info['weight_decay']['val'], 
  65.                                momentum=0.9) 
  66.        self.optimizer = optimizer 
  67.        self.cuda = False 
  68.        if CUDA: 
  69.            self.model.cuda() 
  70.            self.cuda = True 

上面的類別將會(huì)實(shí)例化模型的“基因組”。

現(xiàn)在,我們已經(jīng)具備了建立一個(gè)任意網(wǎng)絡(luò)、變更其架構(gòu)并對(duì)其進(jìn)行訓(xùn)練的基本構(gòu)件,那么接下來的步驟就是建立“遺傳算法”,“遺傳算法”將會(huì)對(duì)***個(gè)體進(jìn)行選擇和變異。每個(gè)模型的訓(xùn)練都是獨(dú)立進(jìn)行的,不需要其他有機(jī)體的任何信息。這就使得優(yōu)化過程可以隨著可用的處理節(jié)點(diǎn)進(jìn)行線性擴(kuò)展。

GP優(yōu)化器的編碼

  1. """Genetic programming algorithms.""" 
  2. from __future__ import absolute_import 
  3.  
  4. import random 
  5. import numpy as np 
  6. from operator import itemgetter 
  7. import torch.multiprocessing as mp 
  8. from net_builder import randomize_network 
  9. import copy 
  10. from worker import CustomWorker, Scheduler 
  11.         
  12.  
  13. class TournamentOptimizer: 
  14.    """Define a tournament play selection process.""" 
  15.  
  16.    def __init__(self, population_sz, init_fn, mutate_fn, nb_workers=2, use_cuda=True): 
  17.        """ 
  18.        Initialize optimizer. 
  19.  
  20.            params:: 
  21.                 
  22.                init_fn: initialize a model 
  23.                mutate_fn: mutate function - mutates a model 
  24.                nb_workers: number of workers 
  25.        """ 
  26.         
  27.        self.init_fn = init_fn 
  28.        self.mutate_fn = mutate_fn 
  29.        self.nb_workers = nb_workers 
  30.        self.use_cuda = use_cuda 
  31.         
  32.        # population 
  33.        self.population_sz = population_sz 
  34.        self.population = [init_fn() for i in range(population_sz)]         
  35.        self.evaluations = np.zeros(population_sz) 
  36.         
  37.        # book keeping 
  38.        self.elite = [] 
  39.        self.stats = [] 
  40.        self.history = [] 
  41.  
  42.    def step(self): 
  43.        """Tournament evolution step.""" 
  44.        print('\nPopulation sample:') 
  45.        for i in range(0,self.population_sz,2): 
  46.            print(self.population[i]['nb_layers'], 
  47.                  self.population[i]['layers'][0]['nb_units']) 
  48.        self.evaluate() 
  49.        children = [] 
  50.        print('\nPopulation mean:{} max:{}'.format( 
  51.            np.mean(self.evaluations), np.max(self.evaluations))) 
  52.        n_elite = 2 
  53.        sorted_pop = np.argsort(self.evaluations)[::-1] 
  54.        elite = sorted_pop[:n_elite] 
  55.         
  56.        # print top@n_elite scores 
  57.        # elites always included in the next population 
  58.        self.elite = [] 
  59.        print('\nTop performers:') 
  60.        for i,e in enumerate(elite): 
  61.            self.elite.append((self.evaluations[e], self.population[e]))     
  62.            print("{}-score:{}".format( str(i), self.evaluations[e]))    
  63.            children.append(self.population[e]) 
  64.        # tournament probabilities: 
  65.        # first p 
  66.        # second p*(1-p) 
  67.        # third p*((1-p)^2) 
  68.        # etc... 
  69.        p = 0.85 # winner probability  
  70.        tournament_size = 3 
  71.        probs = [p*((1-p)**i) for i in range(tournament_size-1)] 
  72.        # a little trick to certify that probs is adding up to 1.0 
  73.        probs.append(1-np.sum(probs)) 
  74.         
  75.        while len(children) < self.population_sz: 
  76.            pop = range(len(self.population)) 
  77.            sel_k = random.sample(pop, k=tournament_size) 
  78.            fitness_k = list(np.array(self.evaluations)[sel_k]) 
  79.            selected = zip(sel_k, fitness_k) 
  80.            rank = sorted(selected, key=itemgetter(1), reverse=True) 
  81.            pick = np.random.choice(tournament_size, size=1, p=probs)[0] 
  82.            best = rank[pick][0] 
  83.            model = self.mutate_fn(self.population[best]) 
  84.            children.append(model) 
  85.  
  86.        self.population = children 
  87.         
  88.        # if we want to do a completely completely random search per epoch 
  89.        # self.population = [randomize_network(bounded=False) for i in range(self.population_sz) ] 
  90.  
  91.    def evaluate(self): 
  92.        """evaluate the models.""" 
  93.         
  94.        workerids = range(self.nb_workers) 
  95.        workerpool = Scheduler(workerids, self.use_cuda ) 
  96.        self.population, returns = workerpool.start(self.population) 
  97.  
  98.        self.evaluations = returns 
  99.        self.stats.append(copy.deepcopy(returns)) 
  100.        self.history.append(copy.deepcopy(self.population))  

“進(jìn)化算法”看起來非常簡(jiǎn)單,對(duì)嗎?沒錯(cuò)!這個(gè)算法可以非常成功,尤其是當(dāng)你為個(gè)體定義了好的變異或跨界功能時(shí)。

存儲(chǔ)庫中還包含了一些額外的使用類別,比如工作器類和調(diào)度器類,使GP優(yōu)化器能夠獨(dú)立平行地完成模型訓(xùn)練和評(píng)估。

運(yùn)行代碼

按照上述步驟操作運(yùn)行。

  1. """Tournament play experiment.""" 
  2. from __future__ import absolute_import 
  3. import net_builder 
  4. import gp 
  5. import cPickle 
  6. # Use cuda ? 
  7. CUDA_ = True 
  8.  
  9. if __name__=='__main__': 
  10.    # setup a tournament! 
  11.    nb_evolution_steps = 10 
  12.    tournament = \ 
  13.        gp.TournamentOptimizer( 
  14.            population_sz=50, 
  15.            init_fn=net_builder.randomize_network, 
  16.            mutate_fn=net_builder.mutate_net, 
  17.            nb_workers=3, 
  18.            use_cuda=True) 
  19.  
  20.    for i in range(nb_evolution_steps): 
  21.        print('\nEvolution step:{}'.format(i)) 
  22.        print('================') 
  23.        tournament.step() 
  24.        # keep track of the experiment results & corresponding architectures 
  25.        name = "tourney_{}".format(i) 
  26.        cPickle.dump(tournament.stats, open(name + '.stats','wb')) 
  27.        cPickle.dump(tournament.history, open(name +'.pop','wb')) 

接下來,讓我們一起來看看運(yùn)行的結(jié)果!

這是50個(gè)解決方案的得分結(jié)果,比賽規(guī)模為3。這些模型僅接受了10000個(gè)樣本的訓(xùn)練,然后就被評(píng)估了。乍一看,進(jìn)化算法似乎并沒有起到太大的作用,因?yàn)榻鉀Q方案在***次進(jìn)化中就已經(jīng)接近***狀態(tài)了;而在第七階段,解決方案達(dá)到了它的***表現(xiàn)。在下圖中,我們用了一個(gè)盒式圖來依次描述這些解決方案的四分之一。我們發(fā)現(xiàn),大多數(shù)方案都表現(xiàn)的很好,但在方案進(jìn)化的同時(shí),這個(gè)盒式圖也隨之緊縮了。

方案的分布

 

每一階段方案的盒式圖

圖中的這個(gè)盒子展示了方案的四分之一,而其盒須則延伸展示了剩余四分之三的方案分布。其中的黑點(diǎn)代表著方案的平均值,從圖中我們會(huì)發(fā)現(xiàn)平均值的上升趨勢(shì)。

 

不同的進(jìn)化運(yùn)行方式

不同的進(jìn)化運(yùn)行方式

為了進(jìn)一步理解這一方法的性能和表現(xiàn),我們***將其與一個(gè)完全隨機(jī)的種群搜做相比較。每個(gè)階段之間都不需要進(jìn)化,每個(gè)解決方案都要被重新設(shè)置為一個(gè)隨機(jī)的狀態(tài)。

方案的分布

每一步隨機(jī)生成的的方案盒式圖

在一個(gè)相對(duì)較小的(93.66% vs 93.22%)里進(jìn)化算法的性能較好。而隨機(jī)種群搜索似乎生成了一些好的解決方案,但模型的方差卻大大增加了。這就意味著在搜索次優(yōu)架構(gòu)的時(shí)候出現(xiàn)了資源浪費(fèi)。將這個(gè)與進(jìn)化圖相比較,我們會(huì)發(fā)現(xiàn)進(jìn)化確實(shí)生成了更多有用的解決方案,它成功地使那些結(jié)構(gòu)進(jìn)化了,進(jìn)而使之達(dá)到了更好的性能表現(xiàn)。

  • MNIST是一個(gè)相當(dāng)簡(jiǎn)單的數(shù)據(jù)集,即使是單層網(wǎng)絡(luò)也能達(dá)到很高的準(zhǔn)確度。

  • 像ADAM這樣的優(yōu)化器對(duì)學(xué)習(xí)率的敏感度比較低,只有在它們的網(wǎng)絡(luò)具備足夠的參數(shù)時(shí),它們才能找到比較好的解決方案。

  • 在訓(xùn)練過程中,模型只會(huì)查看10000個(gè)(訓(xùn)練總數(shù)據(jù)的1/5)樣本示例。如果我們訓(xùn)練得時(shí)間再長(zhǎng)一些,好的架構(gòu)可能會(huì)達(dá)到更高的準(zhǔn)確度。

  • 限制樣本數(shù)量對(duì)于我們學(xué)習(xí)的層的數(shù)量同樣非常重要,越深層的模型需要越多樣本。為了解決這個(gè)問題,我們還增加了一個(gè)移除突變層,使種群調(diào)節(jié)層的數(shù)量。

這個(gè)實(shí)驗(yàn)的規(guī)模還不足以突出這種方法的優(yōu)勢(shì),這些文章中使用的實(shí)驗(yàn)規(guī)模更大,數(shù)據(jù)集也更復(fù)雜。

我們剛剛完成了一個(gè)簡(jiǎn)單的進(jìn)化算法,這個(gè)算法很好地詮釋了“物競(jìng)天擇”的主題。我們的算法只會(huì)選擇最終勝利的解決方案,然后將其變異來產(chǎn)生更多的后代。接下來,我們需要做的就是使用更先進(jìn)的方法,生成和發(fā)展方案群。以下是一些改進(jìn)的建議:

  • 為通用層重新使用親本的權(quán)重

  • 將來自兩個(gè)潛在親本的層合并

  • 架構(gòu)不一定要連續(xù)的,你可以探索層與層之間更多不一樣的聯(lián)系(分散或合并等)

  • 在頂部增加額外的層,然后進(jìn)行微調(diào)整。

以上內(nèi)容都是人工智能研究領(lǐng)域的一個(gè)課題。其中一個(gè)比較受歡迎的方法就是NEAT及其擴(kuò)展。EAT變量使用進(jìn)化算法在開發(fā)網(wǎng)絡(luò)的同時(shí),還對(duì)網(wǎng)絡(luò)的權(quán)重進(jìn)行了設(shè)置。在一個(gè)典型的強(qiáng)化學(xué)習(xí)場(chǎng)景下,代理權(quán)重的進(jìn)化是非常有可能實(shí)現(xiàn)的。但是,當(dāng)(x,y)輸入對(duì)可用時(shí),梯度下降的方法則表現(xiàn)得更好。

相關(guān)文章

Evolino: Hybrid Neuroevolution / Optimal Linear Search for Sequence Learning 

Evolving Deep Neural Networks — This is a very interesting approach of co-evolving whole networks and blocks within the network, it’s very similar to the Evolino method but for CNNs.

Large-Scale Evolution of Image Classifiers 

Convolution by Evolution

本文轉(zhuǎn)自雷鋒網(wǎng),如需轉(zhuǎn)載請(qǐng)至雷鋒網(wǎng)官網(wǎng)申請(qǐng)授權(quán)。

責(zé)任編輯:張子龍 來源: 雷鋒網(wǎng)
相關(guān)推薦

2023-10-23 07:13:04

2023-02-20 07:46:45

機(jī)器學(xué)習(xí)AI 技術(shù)

2017-04-26 08:31:10

神經(jīng)網(wǎng)絡(luò)自然語言PyTorch

2017-06-11 23:38:43

進(jìn)化圖像神經(jīng)網(wǎng)絡(luò)

2018-10-18 10:27:15

機(jī)器學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)python

2022-02-15 23:38:22

Python機(jī)器學(xué)習(xí)算法

2020-08-06 10:11:13

神經(jīng)網(wǎng)絡(luò)機(jī)器學(xué)習(xí)算法

2023-04-19 10:17:35

機(jī)器學(xué)習(xí)深度學(xué)習(xí)

2020-12-18 07:42:30

機(jī)器學(xué)習(xí)數(shù)據(jù)科學(xué)

2025-02-24 08:00:00

機(jī)器學(xué)習(xí)ML架構(gòu)

2018-02-05 08:58:36

Python神經(jīng)網(wǎng)絡(luò)識(shí)別圖像

2020-12-25 10:08:53

Python機(jī)器學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)算法

2017-06-19 15:12:30

Uber神經(jīng)網(wǎng)絡(luò)事件預(yù)測(cè)

2017-03-10 12:16:46

機(jī)器學(xué)習(xí)

2018-08-31 09:55:38

Ansible網(wǎng)絡(luò)自動(dòng)化

2023-02-22 07:04:05

自動(dòng)機(jī)原理優(yōu)化實(shí)踐

2017-08-04 14:23:04

機(jī)器學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)TensorFlow

2021-04-16 09:57:17

AI 數(shù)據(jù)人工智能

2023-11-15 16:12:41

人工智能機(jī)器學(xué)習(xí)深度學(xué)習(xí)

2025-02-25 14:13:31

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)