使用随机搜索算法寻找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)

以上代码算法是笔者根据对随机搜索算法的概念理解编写的,若存在不足之处还望各位读者给予指正。