【深度学习】遗传算法优化GAN
作者 | Victor Sim?
編譯 | VK?
來源?| Towards Data Science
GANs是計算量最大的模型之一,因為它相當(dāng)于同時訓(xùn)練兩個神經(jīng)網(wǎng)絡(luò)。對于我那臺糟糕的便攜式計算機(jī)來說,訓(xùn)練一個GAN直到收斂是非常困難的。我寫了一個通用的遺傳算法,可以適應(yīng)許多不同的問題。我采用這種遺傳算法來訓(xùn)練GANs,生成手寫數(shù)字。
什么是遺傳算法
遺傳算法是一種學(xué)習(xí)算法,它利用兩個好的神經(jīng)網(wǎng)絡(luò)的權(quán)值交叉的思想,可以得到一個更好的神經(jīng)網(wǎng)絡(luò)。
遺傳算法之所以如此有效,是因為沒有直接的優(yōu)化算法,允許有可能產(chǎn)生極其不同的結(jié)果。此外,他們通常會提出非常有趣的解決方案,這些解決方案往往能為問題提供有價值的結(jié)論。
它們是如何工作的
生成一組隨機(jī)權(quán)重。這是第一個智能體的神經(jīng)網(wǎng)絡(luò)。對智能體執(zhí)行一組測試。智能體收到基于測試的分?jǐn)?shù)。重復(fù)此操作幾次以創(chuàng)建種群。選擇種群的前10%可以進(jìn)行繁衍。從前10%中隨機(jī)選擇兩個父母,他們的權(quán)重是交叉的。每次交叉發(fā)生時,都有一個很小的突變機(jī)會:這是一個隨機(jī)值,不在父對象的權(quán)重中。
隨著智能體慢慢適應(yīng)環(huán)境,此過程會慢慢優(yōu)化智能體的性能。
優(yōu)缺點:
優(yōu)點:
計算不密集
不需要進(jìn)行線性代數(shù)計算。唯一需要的機(jī)器學(xué)習(xí)計算是通過神經(jīng)網(wǎng)絡(luò)前向傳播。因此,與深層神經(jīng)網(wǎng)絡(luò)相比,需求非常廣泛。
適應(yīng)性強(qiáng)
人們可以調(diào)整和插入許多不同的測試和方法來操縱遺傳算法的靈活性。人們可以在遺傳算法中創(chuàng)建一個GAN,方法是讓智能體作為生成器網(wǎng)絡(luò),通過鑒別器進(jìn)行測試。這是一個關(guān)鍵的好處,它使我相信遺傳算法在未來的應(yīng)用將更加廣泛。
可以理解
對于普通神經(jīng)網(wǎng)絡(luò),該算法的學(xué)習(xí)模式是神秘的。對于遺傳算法來說,我們很容易理解為什么會發(fā)生一些事情:例如,當(dāng)一個遺傳算法被賦予Tic-Tac-Toe環(huán)境時,某些可識別的策略會慢慢發(fā)展。這是一個很大的好處,因為使用機(jī)器學(xué)習(xí)是為了使用技術(shù)來幫助我們深入了解重要問題。
缺點:
需要很長時間
不好的交叉和突變會對程序的準(zhǔn)確性產(chǎn)生負(fù)面影響,從而使程序收斂速度減慢或達(dá)到某個損失閾值。
代碼
既然你對遺傳算法及其優(yōu)點和缺點有了相當(dāng)全面的了解,我現(xiàn)在就可以向你展示該程序:
import?random import?numpy?as?np from?IPython.display?import?clear_output from?keras.layers?import?Reshape from?keras.layers?import?Flatten from?keras.layers?import?Conv2D from?keras.layers?import?Conv2DTranspose from?keras.layers?import?LeakyReLU from?keras.layers?import?Dropout,Dense from?keras.optimizers?import?Adam from?keras.models?import?Sequential from?keras.datasets.mnist?import?load_data(trainX,?trainy),?(testX,?testy)?=?load_data()鑒別器需要Keras,但是遺傳算法中的神經(jīng)網(wǎng)絡(luò)是由下面的代碼創(chuàng)建的,在代碼中,它是以numpy為基礎(chǔ)構(gòu)建的。
class?genetic_algorithm:def?execute(pop_size,generations,threshold,network):class?Agent:def?__init__(self,network):這是“genetic_algorithm”類的創(chuàng)建,它包含了所有與遺傳算法有關(guān)的函數(shù)以及它應(yīng)該如何工作。主要函數(shù)是execute函數(shù),它以pop_size,generations,threshold,network為參數(shù)。pop_size是生成的種群的大小,generations是表示epoch的術(shù)語,threshold是你滿意的損失值。X和y表示標(biāo)記數(shù)據(jù)。network是神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)。
class?neural_network:def?__init__(self,network):self.weights?=?[]self.activations?=?[]for?layer?in?network:if?layer[0]?!=?None:input_size?=?layer[0]else:input_size?=?network[network.index(layer)-1][1]output_size?=?layer[1]activation?=?layer[2]self.weights.append(np.random.randn(input_size,output_size))self.activations.append(activation)def?propagate(self,data):input_data?=?datafor?i?in?range(len(self.weights)):z?=?np.dot(input_data,self.weights[i])a?=?self.activations[i](z)input_data?=?ayhat?=?areturn?yhatself.neural_network?=?neural_network(network)self.fitness?=?0此腳本描述每個智能體的神經(jīng)網(wǎng)絡(luò)的權(quán)重初始化和網(wǎng)絡(luò)傳播。
def?generate_agents(population,?network):return?[Agent(network)?for?_?in?range(population)]此函數(shù)創(chuàng)建將要測試的第一組智能體。
def?fitness(agents):for?agent?in?agents:dataset_len?=?100fake?=?[]real?=?[]y?=?[]for?i?in?range(dataset_len//2):fake.append(agent.neural_network.propagate(np.random.randn(latent_size)).reshape(28,28))y.append(0)real.append(random.choice(trainX))y.append(1)X?=?fake+realX?=?np.array(X).astype('uint8').reshape(len(X),28,28,1)y?=?np.array(y).astype('uint8')model.fit(X,y,verbose?=?0)fake?=?[]real?=?[]y?=?[]for?i?in?range(dataset_len//2):fake.append(agent.neural_network.propagate(np.random.randn(latent_size)).reshape(28,28))y.append(0)real.append(random.choice(trainX))y.append(1)X?=?fake+realX?=?np.array(X).astype('uint8').reshape(len(X),28,28,1)y?=?np.array(y).astype('uint8')agent.fitness?=?model.evaluate(X,y,verbose?=?0)[1]*100return?agents適應(yīng)度函數(shù)是該遺傳算法的獨特部分:
稍后將定義鑒別器型神經(jīng)網(wǎng)絡(luò)。此模型將基于先前加載的MNIST數(shù)據(jù)集進(jìn)行訓(xùn)練。該模型以卷積網(wǎng)絡(luò)的形式返回結(jié)果。
def?selection(agents):agents?=?sorted(agents,?key=lambda?agent:?agent.fitness,?reverse=False)print('\n'.join(map(str,?agents)))agents?=?agents[:int(0.2?*?len(agents))]return?agents這個函數(shù)模仿了進(jìn)化中的選擇理論:最好的種群生存,而其他則任由他們死去。
def?unflatten(flattened,shapes):newarray?=?[]index?=?0for?shape?in?shapes:size?=?np.product(shape)newarray.append(flattened[index?:?index?+?size].reshape(shape))index?+=?sizereturn?newarray要執(zhí)行交叉和變異函數(shù),需要將權(quán)重展平,并將其展開為原始形狀。
def?crossover(agents,network,pop_size):offspring?=?[]for?_?in?range((pop_size?-?len(agents))?//?2):parent1?=?random.choice(agents)parent2?=?random.choice(agents)child1?=?Agent(network)child2?=?Agent(network)shapes?=?[a.shape?for?a?in?parent1.neural_network.weights]genes1?=?np.concatenate([a.flatten()?for?a?in?parent1.neural_network.weights])genes2?=?np.concatenate([a.flatten()?for?a?in?parent2.neural_network.weights])split?=?random.ragendint(0,len(genes1)-1)child1_genes?=?np.asrray(genes1[0:split].tolist()?+?genes2[split:].tolist())child2_genes?=?np.array(genes1[0:split].tolist()?+?genes2[split:].tolist())child1.neural_network.weights?=?unflatten(child1_genes,shapes)child2.neural_network.weights?=?unflatten(child2_genes,shapes)offspring.append(child1)offspring.append(child2)agents.extend(offspring)return?agents交叉函數(shù)是程序中最復(fù)雜的函數(shù)之一。它生成兩個新的“子代”智能體,其權(quán)重被替換為兩個父代的交叉。這是創(chuàng)建權(quán)重的過程:
Flatten化父代的權(quán)重
生成兩個分割點
使用分割點作為索引來設(shè)置兩個子智能體的權(quán)重
這是特征交叉的全過程。
def?mutation(agents):for?agent?in?agents:if?random.uniform(0.0,?1.0)?<=?0.1:weights?=?agent.neural_network.weightsshapes?=?[a.shape?for?a?in?weights]flattened?=?np.concatenate([a.flatten()?for?a?in?weights])randint?=?random.randint(0,len(flattened)-1)flattened[randint]?=?np.random.randn()newarray?=?[a?]indeweights?=?0for?shape?in?shapes:size?=?np.product(shape)newarray.append(flattened[indeweights?:?indeweights?+?size].reshape(shape))indeweights?+=?sizeagent.neural_network.weights?=?newarrayreturn?agents這就是突變函數(shù)。展平與交叉函數(shù)相同。不是拆分點,而是選擇一個隨機(jī)點,用一個隨機(jī)值替換。
for?i?in?range(generations):print('Generation',str(i),':')agents?=?generate_agents(pop_size,network)agents?=?fitness(agents)agents?=?selection(agents)agents?=?crossover(agents,network,pop_size)agents?=?mutation(agents)agents?=?fitness(agents)if?any(agent.fitness?<?threshold?for?agent?in?agents):print('Threshold?met?at?generation?'+str(i)+'?!')if?i?%?100:clear_output()return?agents[0]這是execute函數(shù)的最后一部分,它執(zhí)行已定義的所有函數(shù)。
image_size?=?28 latent_size?=?100model?=?Sequential() model.add(Conv2D(64,?(3,3),?strides=(2,?2),?padding='same',?input_shape=(image_size,image_size,1))) model.add(LeakyReLU(alpha=0.2)) model.add(Dropout(0.4)) model.add(Conv2D(64,?(3,3),?strides=(2,?2),?padding='same')) model.add(LeakyReLU(alpha=0.2)) model.add(Dropout(0.4)) model.add(Flatten()) model.add(Dense(1,?activation='sigmoid')) opt?=?Adam(lr=0.0002,?beta_1=0.5) model.compile(loss='binary_crossentropy',?optimizer=opt,?metrics=['accuracy'])network?=?[[latent_size,100,sigmoid],[None,image_size**2,sigmoid]] ga?=?genetic_algorithm agent?=?ga.execute(1000,1000,90,network) (trainX,?trainy),?(testX,?testy)?=?load_data() weights?=?agent.neural_network.weights對于網(wǎng)絡(luò)變量,每個嵌套列表包含輸入神經(jīng)元數(shù)、輸出神經(jīng)元數(shù)和激活函數(shù)。execute函數(shù)返回最佳智能體。
結(jié)論
顯然,遺傳算法不會像基于梯度的算法那樣快速收斂,但是計算工作會在較長的時間內(nèi)進(jìn)行,這使得它在計算機(jī)上的密集度降低了!
感謝你閱讀我的文章!
往期精彩回顧適合初學(xué)者入門人工智能的路線及資料下載機(jī)器學(xué)習(xí)及深度學(xué)習(xí)筆記等資料打印機(jī)器學(xué)習(xí)在線手冊深度學(xué)習(xí)筆記專輯《統(tǒng)計學(xué)習(xí)方法》的代碼復(fù)現(xiàn)專輯 AI基礎(chǔ)下載機(jī)器學(xué)習(xí)的數(shù)學(xué)基礎(chǔ)專輯 本站知識星球“黃博的機(jī)器學(xué)習(xí)圈子”(92416895) 本站qq群704220115。 加入微信群請掃碼:總結(jié)
以上是生活随笔為你收集整理的【深度学习】遗传算法优化GAN的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Edge浏览器怎么打开开发者模式
- 下一篇: 【论文解读】经典CNN对2D3D掌纹及掌