使用随机搜索算法寻找LSTM模型最优超超参数组合,以改善模型的性能和提高模型的预测精度。选取模型训练次数、模型隐含层的神经元个数和序列长度作为超参数;根据实际模型设置三个超参数的范围。每次从超参数空间(第一次从超参数全空间随机抽取,第二次之后从子空间随机抽取)中抽取27组超参数组合进行搜索,最后将模型的搜索结果保存到EXCEL文件中。
import openpyxl as op
from random import choice
from random import sample
import pandas as pd
import numpy as np
from keras.applications.densenet import layers
from keras.losses import mean_absolute_error
from sklearn.metrics import r2_score
from sklearn.preprocessing import MinMaxScaler
import tensorflow as tf
from keras.models import Sequential
import warnings
warnings.filterwarnings('ignore')
# 设置超参数范围
epoch_list_all=[*range(20, 100, 1)] # 训练次数
neure_list_all=[*range(10, 100, 1)] # 神经元个数
seq_len_list_all=[*range(5, 40, 1)] # 序列长度
# print("epoch=",choice(epoch_list),"neure=",choice(neure_list),"seq_len=",choice(seq_len_list))
# 初始化存放三个超参数的列表
List=[]
# 存放每次搜索中超参数组合
# 存放每次搜索所有的超参数组合
CCS_all=[]
# 存放每次搜索中最优的超参数组合
CCS_best=[]
# 最优超参数组合
epoch_best=None
neure_best=None
seq_len_best=None
# 初始化最优(小)的平均绝对误差
MAE_best=100
# 更新最优超参数列表函数
def Change_num(index_X,X_all_list):
if(3<=index_X<=(len(X_all_list)-3)):
list_X=X_all_list[index_X-3:index_X+2]
elif(index_X<3):
list_X=X_all_list[:5]
else:
list_X=X_all_list[-5:]
print("list_X=",list_X)
return list_X
# 随机抽取27组进行训练
for i in range(0,27):
epoch=choice(epoch_list_all)
neure=choice(neure_list_all)
seq_len=choice(seq_len_list_all)
# print("epoch=",epoch,"nerue=",neure,"seq_len=",seq_len)
List.append(1)
List[i]=[epoch,neure,seq_len]
print(List)
leean=2
# 开始随机搜索搜索
for f in range(6):
# 模型评价指标指标MAE列表初始化
MAE_list = []
for s in range(27):
# LSTM模型(将构建的LSTM模型放入循环内)
# 将模型中的训练次数改为List[s][0] 神经元个数改为List[s][1] 序列长度改为List[s][2]
# 将每组超参数所对应的MAE值存放于MAE_list列表中
MAE_list.append(1)
# Pred为预测数据,Real为真实数据
MAE_list[s]=np.sum(np.absolute(Pred-Real))/len(Real)
# 将每次搜索的所有超参数组合以及对应的MAE值存入excel文件
bg = op.load_workbook(r"Excel文件路径") # 应先将excel文件放入到工作目录下
sheet = bg["Sheet1"] # “Sheet1”表示将数据写入到excel文件的sheet1下
sheet.cell(leean,1,List[s][0]) # 训练次数
sheet.cell(leean, 2, List[s][1]) # 神经元个数
sheet.cell(leean, 3, List[s][2]) # 序列长度
sheet.cell(leean, 4, MAE_list[s]) # MAE
bg.save("Excel文件路径") # 对文件进行保存
leean=leean+1
# 对比各组超参数组合对应的MAE,找出最小MAE所对应的较优超参数组合
indexs=MAE_list.index(min(MAE_list))
# 找出较优超参数组合各个超参数
epochs,neures,seq_lens=List[indexs][0],List[indexs][1],List[indexs][2]
CCS_best.append(1)
CCS_best[f]=[epochs,neures,seq_lens]
# 缓存较优超参数组合
if(MAE_list[indexs]<MAE_best):
MAE_best=MAE_list[indexs]
epoch_best=epochs
neure_best=neures
seq_len_best=seq_lens
# 超参数范围寻找范围调整
# 删除本次搜索的最优超参数,以免下次搜索还是找到它(避免出现局部最优)
index_epoch=epoch_list_all.index(epochs)
del epoch_list_all[index_epoch]
index_nerue=neure_list_all.index(neures)
del neure_list_all[index_nerue]
index_seq_len=seq_len_list_all.index(seq_lens)
del seq_len_list_all[index_seq_len]
# print("较优超参数组合坐标1:",index_epoch,index_nerue,index_seq_len)
# 根据超参数的位置选择调整下一带超参数组
epoch_new=Change_num(index_epoch,epoch_list_all)
neure_new=Change_num(index_nerue,neure_list_all)
seq_len_new=Change_num(index_seq_len,seq_len_list_all)
List=[]
# 更新三个超参数的列表
for y in range(27):
List.append(1)
List[y]=[choice(epoch_new),choice(neure_new),choice(seq_len_new)]
CCS_all.append(1)
CCS_all[f]=List
print("第",f,"次搜索!\n")
print("epoch:", epoch_best, "nerue:", neure_best, "seq_len:", seq_len_best, "\n")
print("最小的MAE:", MAE_best)
print("CCS_all=",CCS_all)
print("CCS_best=",CCS_best)
print("最优超参数组合:\n")
print("epoch:",epoch_best,"nerue:",neure_best,"seq_len:",seq_len_best,"\n")
print("MAE:",MAE_best)
以上代码算法是笔者根据对随机搜索算法的概念理解编写的,若存在不足之处还望各位读者给予指正。