【深度学习】遗传算法优化GAN
作者 | Victor Sim?
編譯 | VK?
來源?| Towards Data Science
GANs是計算量最大的模型之一,因為它相當于同時訓練兩個神經網絡。對于我那臺糟糕的便攜式計算機來說,訓練一個GAN直到收斂是非常困難的。我寫了一個通用的遺傳算法,可以適應許多不同的問題。我采用這種遺傳算法來訓練GANs,生成手寫數字。
什么是遺傳算法
遺傳算法是一種學習算法,它利用兩個好的神經網絡的權值交叉的思想,可以得到一個更好的神經網絡。
遺傳算法之所以如此有效,是因為沒有直接的優化算法,允許有可能產生極其不同的結果。此外,他們通常會提出非常有趣的解決方案,這些解決方案往往能為問題提供有價值的結論。
它們是如何工作的
生成一組隨機權重。這是第一個智能體的神經網絡。對智能體執行一組測試。智能體收到基于測試的分數。重復此操作幾次以創建種群。選擇種群的前10%可以進行繁衍。從前10%中隨機選擇兩個父母,他們的權重是交叉的。每次交叉發生時,都有一個很小的突變機會:這是一個隨機值,不在父對象的權重中。
隨著智能體慢慢適應環境,此過程會慢慢優化智能體的性能。
優缺點:
優點:
計算不密集
不需要進行線性代數計算。唯一需要的機器學習計算是通過神經網絡前向傳播。因此,與深層神經網絡相比,需求非常廣泛。
適應性強
人們可以調整和插入許多不同的測試和方法來操縱遺傳算法的靈活性。人們可以在遺傳算法中創建一個GAN,方法是讓智能體作為生成器網絡,通過鑒別器進行測試。這是一個關鍵的好處,它使我相信遺傳算法在未來的應用將更加廣泛。
可以理解
對于普通神經網絡,該算法的學習模式是神秘的。對于遺傳算法來說,我們很容易理解為什么會發生一些事情:例如,當一個遺傳算法被賦予Tic-Tac-Toe環境時,某些可識別的策略會慢慢發展。這是一個很大的好處,因為使用機器學習是為了使用技術來幫助我們深入了解重要問題。
缺點:
需要很長時間
不好的交叉和突變會對程序的準確性產生負面影響,從而使程序收斂速度減慢或達到某個損失閾值。
代碼
既然你對遺傳算法及其優點和缺點有了相當全面的了解,我現在就可以向你展示該程序:
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,但是遺傳算法中的神經網絡是由下面的代碼創建的,在代碼中,它是以numpy為基礎構建的。
class?genetic_algorithm:def?execute(pop_size,generations,threshold,network):class?Agent:def?__init__(self,network):這是“genetic_algorithm”類的創建,它包含了所有與遺傳算法有關的函數以及它應該如何工作。主要函數是execute函數,它以pop_size,generations,threshold,network為參數。pop_size是生成的種群的大小,generations是表示epoch的術語,threshold是你滿意的損失值。X和y表示標記數據。network是神經網絡的結構。
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此腳本描述每個智能體的神經網絡的權重初始化和網絡傳播。
def?generate_agents(population,?network):return?[Agent(network)?for?_?in?range(population)]此函數創建將要測試的第一組智能體。
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適應度函數是該遺傳算法的獨特部分:
稍后將定義鑒別器型神經網絡。此模型將基于先前加載的MNIST數據集進行訓練。該模型以卷積網絡的形式返回結果。
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這個函數模仿了進化中的選擇理論:最好的種群生存,而其他則任由他們死去。
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要執行交叉和變異函數,需要將權重展平,并將其展開為原始形狀。
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交叉函數是程序中最復雜的函數之一。它生成兩個新的“子代”智能體,其權重被替換為兩個父代的交叉。這是創建權重的過程:
Flatten化父代的權重
生成兩個分割點
使用分割點作為索引來設置兩個子智能體的權重
這是特征交叉的全過程。
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這就是突變函數。展平與交叉函數相同。不是拆分點,而是選擇一個隨機點,用一個隨機值替換。
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函數的最后一部分,它執行已定義的所有函數。
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對于網絡變量,每個嵌套列表包含輸入神經元數、輸出神經元數和激活函數。execute函數返回最佳智能體。
結論
顯然,遺傳算法不會像基于梯度的算法那樣快速收斂,但是計算工作會在較長的時間內進行,這使得它在計算機上的密集度降低了!
感謝你閱讀我的文章!
往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習筆記專輯《統計學習方法》的代碼復現專輯 AI基礎下載機器學習的數學基礎專輯 本站知識星球“黃博的機器學習圈子”(92416895) 本站qq群704220115。 加入微信群請掃碼:總結
以上是生活随笔為你收集整理的【深度学习】遗传算法优化GAN的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Edge浏览器怎么打开开发者模式
- 下一篇: 【论文解读】经典CNN对2D3D掌纹及掌