(python)GA(遗传算法)优化LSTM神经网络(亲测成功,速度慢)
1.項(xiàng)目概述
本文采用的是python編程,使用的數(shù)據(jù)集是mnist手寫數(shù)據(jù)集,該數(shù)據(jù)集主要是對0-9的手寫數(shù)字體識別,雖然說圖像識別方面用CNN識別率較高,但這里L(fēng)STM也可以獲取較高的準(zhǔn)確率。
2.優(yōu)化參數(shù)
本文優(yōu)化的是LSTM的層數(shù)參數(shù)和各層神經(jīng)元參數(shù),其中包含了lstm層和Dense層,其中我們規(guī)定了神經(jīng)網(wǎng)絡(luò)的層數(shù)不超過3層,每層的神經(jīng)元個(gè)數(shù)在[32,256]之間。
3.注意事項(xiàng)
1.本文的遺傳算法編碼并非2進(jìn)制編碼,而是由各個(gè)參數(shù)組成的一維數(shù)組。
2.在遺傳算法交叉、變異操作中,關(guān)于神經(jīng)網(wǎng)絡(luò)層數(shù)的參數(shù)不進(jìn)行交叉,只對神經(jīng)網(wǎng)神經(jīng)元個(gè)數(shù)進(jìn)行交叉、變異。
3.文件為兩部分每一部分為lstm的部分,一部分為ga部分
LSTM部分
#本章節(jié)GA_LSTM是關(guān)于遺傳算法優(yōu)化lstm算法的層數(shù)和全連接層數(shù)及每層神經(jīng)元的個(gè)數(shù) import numpy as np import pandas as pd import tensorflow as tf import matplotlib as plt from tensorflow.keras.layers import Input,LSTM,Dropout,Dense,BatchNormalization from tensorflow.keras import optimizers,losses,metrics,models,Sequential ''' 本文的主要內(nèi)容如下: 1.本文章是對lstm網(wǎng)絡(luò)的優(yōu)化,優(yōu)化的參數(shù)主要有:lstm層的層數(shù),lstm隱藏層的神經(jīng)元個(gè)數(shù),dense層的層數(shù),dense層的神經(jīng)元個(gè)數(shù) 2.本文章利用的是遺傳算法進(jìn)行優(yōu)化,其中編碼形式并未采用2進(jìn)制編碼,只是將2數(shù)組之間的元素交換位置。 3.本文的lstm和dense的層數(shù)都在1-3的范圍內(nèi),因?yàn)?層的網(wǎng)絡(luò)足以擬合非線性數(shù)據(jù) 4.程序主要分為2部分,第一部分是lstm網(wǎng)絡(luò)的設(shè)計(jì),第二部分是遺傳算法的優(yōu)化。 5.代碼的解釋已詳細(xì)寫在對應(yīng)的部分,有問題的同學(xué)可以在評論區(qū)進(jìn)行交流 ''' #導(dǎo)入數(shù)據(jù)集,本文用的是mnist手寫數(shù)據(jù)集,該數(shù)據(jù)主要是對手寫體進(jìn)行識別0-9的數(shù)字 def load_data():#從tensorflow自帶的數(shù)據(jù)集中導(dǎo)入數(shù)據(jù)(x_train,y_train),(x_test,y_test)=tf.keras.datasets.mnist.load_data()#主要進(jìn)行歸一化操作x_train, x_test = x_train / 255.0, x_test / 255.0return x_train,x_test,y_test,y_train#定義LSTM模型 def lstm_mode(inputs, units_num, sequences_state):#input主要是用來定義lstm的輸入,input的一般是在第一層lstm層之前,units_num即是隱藏層神經(jīng)元個(gè)數(shù),sequence_state即是lstm層輸出的方式lstm=LSTM(units_num,return_sequences=sequences_state)(inputs)print("lstm:",lstm.shape)return lstm#定義全連接層、BN層 def dense_mode(input,units_num):#這里主要定義全連接層的輸入,input參數(shù)定義dense的第一次輸入,units_num代表隱藏層神經(jīng)元個(gè)數(shù)#這里定義全連接層,采用L2正則化來防止過擬合,激活函數(shù)為reludense=Dense(units_num,kernel_regularizer=tf.keras.regularizers.l2(0.001),activation='relu')(input)print("dense:",dense.shape)#定義dropout層,概率為0.2drop_out=Dropout(rate=0.2)(dense)#定義BN層,可以理解為是隱藏層的標(biāo)準(zhǔn)化過程dense_bn=BatchNormalization()(drop_out)return dense,drop_out,dense_bn#這里定義的即是評價(jià)lstm效果的函數(shù)——也是遺傳算法的適應(yīng)度函數(shù) def aim_function(x_train,y_train,x_test,y_test,num):#這里傳入數(shù)據(jù)和參數(shù)數(shù)組num,num保存了需要優(yōu)化的參數(shù)#這里我們設(shè)置num數(shù)組中num[0]代表lstm的層數(shù)。lstm_layers=num[0]#num[2:2 + lstm_layers]分別為lstm各層的神經(jīng)元個(gè)數(shù),有同學(xué)不知道num(1)去哪了(num(1)為全連接層的層數(shù))lstm_units = num[2:2 + lstm_layers]#將numlstm_name = list(np.zeros((lstm_layers,)))# 設(shè)置全連接層的參數(shù)#num(1)為全連接的參數(shù)lstm_dense_layers = num[1]#將lstm層之后的地方作為全連接層各層的參數(shù)lstm_dense_units = num[2 + lstm_layers: 2 + lstm_layers + lstm_dense_layers]#lstm_dense_name = list(np.zeros((lstm_dense_layers,)))lstm_dense_dropout_name = list(np.zeros((lstm_dense_layers,)))lstm_dense_batch_name = list(np.zeros((lstm_dense_layers,)))#這主要是定義lstm的第一層輸入,形狀為訓(xùn)練集數(shù)據(jù)的形狀inputs_lstm = Input(shape=(x_train.shape[1], x_train.shape[2]))#這里定義lstm層的輸入(如果為第一層lstm層,則將初始化的input輸入,如果不是第一層,則接受上一層輸出的結(jié)果)for i in range(lstm_layers):if i == 0:inputs = inputs_lstmelse:inputs = lstm_name[i - 1]if i == lstm_layers - 1:sequences_state = Falseelse:sequences_state = True#通過循環(huán),我們將每層lstm的參數(shù)都設(shè)計(jì)完成lstm_name[i] = lstm_mode(inputs, lstm_units[i], sequences_state=sequences_state)#同理設(shè)計(jì)全連接層神經(jīng)網(wǎng)絡(luò)的參數(shù)for i in range(lstm_dense_layers):if i == 0:inputs = lstm_name[lstm_layers - 1]else:inputs = lstm_dense_name[i - 1]lstm_dense_name[i], lstm_dense_dropout_name[i], lstm_dense_batch_name[i] = dense_mode(inputs,units_num=lstm_dense_units[i])#這里是最后一層:分類層,softmaxoutputs_lstm = Dense(10, activation='softmax')(lstm_dense_batch_name[lstm_dense_layers - 1])print("last_dense",outputs_lstm.shape)# 利用函數(shù)式調(diào)試神經(jīng)網(wǎng)絡(luò),調(diào)用inputs和outputs之間的神經(jīng)網(wǎng)絡(luò)LSTM_model =tf.keras.Model(inputs=inputs_lstm, outputs=outputs_lstm)# 編譯模型LSTM_model.compile(optimizer=optimizers.Adam(),loss='sparse_categorical_crossentropy',metrics=['accuracy'])print("訓(xùn)練集形狀",x_train.shape)history = LSTM_model.fit(x_train, y_train,batch_size=32, epochs=1, validation_split=0.1, verbose=1)# 驗(yàn)證模型,model.evaluate返回的值是一個(gè)數(shù)組,其中score[0]為loss,score[1]為準(zhǔn)確度acc = LSTM_model.evaluate(x_test, y_test, verbose=0)return acc[1]GA優(yōu)化部分
#GA優(yōu)化lstm的遺傳算法部分 import GA_LSTM_lstm as ga import numpy as np import pandas as pd import matplotlib as plt import os #不顯示警告信息 os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' #設(shè)置遺傳算法的參數(shù) DNA_size = 2 DNA_size_max = 8 # 每條染色體的長度 POP_size = 20 # 種群數(shù)量 CROSS_RATE = 0.5 # 交叉率 MUTATION_RATE = 0.01# 變異率 N_GENERATIONS = 40 # 迭代次數(shù)#接收數(shù)據(jù) x_train,x_test,y_test,y_train = ga.load_data()# 定義適用度函數(shù),即aim_function函數(shù),接收返回值 def get_fitness(x):return ga.aim_function(x_train,y_train,x_test,y_test,num=x)# 生成新的種群 def select(pop,fitness):#這里主要是進(jìn)行選擇操作,即從20個(gè)種群中隨機(jī)選取重復(fù)隨機(jī)采樣出20個(gè)種群進(jìn)行種群初始化操作,p代表被選擇的概率,這里采用的是輪盤賭的方式idx = np.random.choice(np.arange(POP_size),size=POP_size,replace=True,p=fitness/fitness.sum())#將選擇的種群組成初始種群popreturn pop[idx]# 交叉函數(shù) def crossover(parent,pop):#這里主要進(jìn)行交叉操作,隨機(jī)數(shù)小于交叉概率則發(fā)生交叉if np.random.rand() < CROSS_RATE:#從20個(gè)種群中選擇一個(gè)種群進(jìn)行交叉i_ = np.random.randint(0,POP_size,size=1) # 染色體的序號#這里將生成一個(gè)8維的2進(jìn)制數(shù),并轉(zhuǎn)換層成bool類型,true表示該位置交叉,False表示不交叉cross_points = np.random.randint(0,2,size=DNA_size_max).astype(np.bool) # 用True、False表示是否置換# 這一部分主要是對針對不做變異的部分for i,point in enumerate(cross_points):'''第一部分:這里是指該位點(diǎn)為神經(jīng)元個(gè)數(shù)的位點(diǎn),本來該交換,但其中位點(diǎn)為0,什么意思呢?即[2,3,32,43,34,230,43,46,67]和[2,2,32,54,55,76,74,26,0],末尾的0位置就不應(yīng)該交叉,因?yàn)榻徊嫱旰?會對前兩位的參數(shù)產(chǎn)生影響。第二部分:即對前兩位不進(jìn)行交叉操作,因?yàn)榍皟晌淮淼氖菍訑?shù),層數(shù)交叉后會對神經(jīng)元的個(gè)數(shù)產(chǎn)生影響'''#第一部分if point == True and pop[i_,i] * parent[i] == 0:cross_points[i] = False#第二部分if point == True and i < 2:cross_points[i] = False# 將第i_條染色體上對應(yīng)位置的基因置換到parent染色體上parent[cross_points] = pop[i_,cross_points]return parent# 定義變異函數(shù) def mutate(child):#變異操作也只是針對后6位參數(shù)for point in range(DNA_size_max):if np.random.rand() < MUTATION_RATE:#2位參數(shù)之后的參數(shù)才才參與變異if point >= 2:if child[point] != 0:child[point] = np.random.randint(32,257)return child#初始化2列層數(shù)參數(shù) pop_layers = np.zeros((POP_size,DNA_size),np.int32) pop_layers[:,0] = np.random.randint(1,4,size=(POP_size,)) pop_layers[:,1] = np.random.randint(1,4,size=(POP_size,))# 種群 #初始化20x8的種群 pop = np.zeros((POP_size,DNA_size_max)) # 將初始化的種群賦值,前兩列為層數(shù)參數(shù),后6列為神經(jīng)元個(gè)數(shù)參數(shù) for i in range(POP_size):#隨機(jī)從[32,256]中抽取隨機(jī)數(shù)組組成神經(jīng)元個(gè)數(shù)信息pop_neurons = np.random.randint(32,257,size=(pop_layers[i].sum(),))#將2列層數(shù)信息和6列神經(jīng)元個(gè)數(shù)信息合并乘8維種群信息pop_stack = np.hstack((pop_layers[i],pop_neurons))#將這些信息賦值給pop種群進(jìn)行初始化種群for j,gene in enumerate(pop_stack):pop[i][j] = gene# 在迭代次數(shù)內(nèi),計(jì)算種群的適應(yīng)度函數(shù) for each_generation in range(N_GENERATIONS):# 初始化適應(yīng)度fitness = np.zeros([POP_size,])# 遍歷20個(gè)種群,對基因進(jìn)行操作for i in range(POP_size):pop_list = list(pop[i])# 第i個(gè)染色體上的基因#對賦值為0的基因進(jìn)行刪除for j,each in enumerate(pop_list):if each == 0.0:index = jpop_list = pop_list[:j]#將基因進(jìn)行轉(zhuǎn)換為int類型for k,each in enumerate(pop_list):each_int = int(each)pop_list[k] = each_int#將計(jì)算出來的適應(yīng)度填寫在適應(yīng)度數(shù)組中fitness[i] = get_fitness(pop_list)#輸出結(jié)果print('第%d代第%d個(gè)染色體的適應(yīng)度為%f'%(each_generation+1,i+1,fitness[i]))print('此染色體為:',pop_list)print('Generation:',each_generation+1,'Most fitted DNA:',pop[np.argmax(fitness),:],'適應(yīng)度為:',fitness[np.argmax(fitness)])# 生成新的種群pop = select(pop,fitness)# 復(fù)制一遍種群pop_copy = pop.copy()#遍歷pop中的每一個(gè)種群,進(jìn)行交叉,變異,遺傳操作for parent in pop:child = crossover(parent,pop_copy)child = mutate(child)parent = child運(yùn)行結(jié)果如下
1688/1688 [==============================] - 21s 10ms/step - loss: 0.7340 - accuracy: 0.8076 - val_loss: 0.1616 - val_accuracy: 0.9730 第1代第1個(gè)染色體的適應(yīng)度為0.966900 此染色體為: [1, 1, 151, 248] lstm: (None, 83) dense: (None, 200) last_dense (None, 10) 訓(xùn)練集形狀 (60000, 28, 28) 1688/1688 [==============================] - 19s 10ms/step - loss: 0.7532 - accuracy: 0.7855 - val_loss: 0.1744 - val_accuracy: 0.9672 第1代第2個(gè)染色體的適應(yīng)度為0.961300 此染色體為: [1, 1, 83, 200] lstm: (None, 28, 135) lstm: (None, 28, 41) lstm: (None, 126) dense: (None, 47) last_dense (None, 10) 訓(xùn)練集形狀 (60000, 28, 28) 1688/1688 [==============================] - 33s 17ms/step - loss: 0.7534 - accuracy: 0.7755 - val_loss: 0.1258 - val_accuracy: 0.9717 第1代第3個(gè)染色體的適應(yīng)度為0.967800 此染色體為: [3, 1, 135, 41, 126, 47] lstm: (None, 28, 247) lstm: (None, 28, 82) lstm: (None, 71) dense: (None, 190) dense: (None, 161) dense: (None, 124) last_dense (None, 10) 訓(xùn)練集形狀 (60000, 28, 28)歡迎點(diǎn)贊 收藏 加關(guān)注
參考鏈接:
python深度學(xué)習(xí)之GA(遺傳算法)優(yōu)化LSTM神經(jīng)網(wǎng)絡(luò)_柳小蔥的博客-CSDN博客_lstm優(yōu)化上次優(yōu)化完bp神經(jīng)網(wǎng)絡(luò)后,發(fā)現(xiàn)用matlab優(yōu)化高級的神經(jīng)網(wǎng)絡(luò)太慢了,于是用tensorflow繼續(xù)學(xué)習(xí)GA優(yōu)化部分。1.項(xiàng)目概述本文采用的是python編程,使用的數(shù)據(jù)集是mnist手寫數(shù)據(jù)集,該數(shù)據(jù)集主要是對0-9的手寫數(shù)字體識別,雖然說圖像識別方面用CNN識別率較高,但這里L(fēng)STM也可以獲取較高的準(zhǔn)確率。2.優(yōu)化參數(shù)本文優(yōu)化的是LSTM的層數(shù)參數(shù)和各層神經(jīng)元參數(shù),其中包含了lstm層和Dense層,其中我們規(guī)定了神經(jīng)網(wǎng)絡(luò)的層數(shù)不超過3層,每層的神經(jīng)元個(gè)數(shù)在[32,256]之間。3.注意事項(xiàng)https://liuxiaocong.blog.csdn.net/article/details/114830709?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2.no_search_link&utm_relevant_index=5
總結(jié)
以上是生活随笔為你收集整理的(python)GA(遗传算法)优化LSTM神经网络(亲测成功,速度慢)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hubbledotnet mysql_H
- 下一篇: 自助BI项目实施可行性分析报告