这是我的第297篇原创文章。
一、引言
在深度学习中,超参数是指在训练模型时需要手动设置的参数,它们通常不能通过训练数据自动学习得到。超参数的选择对于模型的性能至关重要,因此在进行深度学习实验时,超参数调优通常是一个重要的步骤。常见的超参数包括:
- model.add()
- neurons(隐含层神经元数量)
- init_mode(初始权重方法)
- activation(激活函数)
- dropout(丢弃率)
- model.compile()
- loss(损失函数)
- optimizer(优化器)
- learning rate(学习率)
- momentum(动量)
- weight decay(权重衰减系数)
- model.fit()
- batch size(批量大小)
- epochs(迭代周期数)
一般来说,可以通过手动调优、网格搜索(Grid Search)、随机搜索(Random Search)、自动调参算法方式进行超参数调优在深度学习中,Epoch(周期)和 Batch Size(批大小)是训练神经网络时经常使用的两个重要的超参数。
-
Epoch(周期):一个Epoch就是将所有训练样本训练一次的过程。然而,当一个Epoch的样本(也就是所有的训练样本)数量可能太过庞大(对于计算机而言),就需要把它分成多个小块,也就是就是分成多个Batch 来进行训练。
-
Batch(批 / 一批样本):将整个训练样本分成若干个Batch。
-
Batch_Size(批大小):每批样本的大小。即1次迭代所使用的样本量。
-
Iteration(一次迭代):训练一个Batch就是一次Iteration(这个概念跟程序语言中的迭代器相似)每次迭代更新1次网络结构的参数
-
step(一步):训练一个样本就是一个step。
比如我有1000个训练样本,bachsize设置为10,则数据分成了100个batch,所有训练样本训练一次即一个epoch需要100个iteration,训练一个batch就是一次iteration。本文采用网格搜索选择Epoch和Batch_size。
二、实现过程
2.1 准备数据
dataset:
dataset = pd.read_csv("data.csv", header=None)
dataset = pd.DataFrame(dataset)
print(dataset)
2.2 数据划分
# 切分数据为输入 X 和输出 Y
X = dataset.iloc[:,0:8]
Y = dataset.iloc[:,8]
# 为了复现,设置随机种子
seed = 7
np.random.seed(seed)
random.set_seed(seed)
2.3 创建模型
需要定义个网格的架构函数create_model,create_model里面的参数要在KerasClassifier这个对象里面存在而且参数名要一致。
def create_model():
# 创建模型
model = Sequential()
model.add(Dense(50, input_shape=(8, ), kernel_initializer='uniform', activation='relu'))
model.add(Dropout(0.05))
model.add(Dense(1, kernel_initializer='uniform', activation='sigmoid'))
# 编译模型
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
model = KerasClassifier(model=create_model)
这里使用了scikeras库的KerasClassifier类来定义一个分类器,这里由于KerasClassifier有批量大小、迭代次数的参数,不需要自定义表示。
2.4 定义网格搜索参数
param_grid = {'batch_size': [20, 40], 'epochs': [10, 50]}
param_grid是一个字典,key是超参数名称,这里的名称必须要在KerasClassifier这个对象里面存在而且参数名要一致。value是key可取的值,也就是要尝试的方案。
2.5 进行参数搜索
from sklearn.model_selection import GridSearchCV
grid = GridSearchCV(estimator=model, param_grid=param_grid)
grid_result = grid.fit(X, Y)
使用sklearn里面的GridSearchCV类进行参数搜索,传入模型和网格参数。
2.6 总结搜索结果
print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
print("%f (%f) with: %r" % (mean, stdev, param))
结果:
经过网格搜索,批量大小的最优选择是20,迭代次数最优选择是50。
作者简介:
读研期间发表6篇SCI数据挖掘相关论文,现在某研究院从事数据算法相关科研工作,结合自身科研实践经历不定期分享关于Python、机器学习、深度学习、人工智能系列基础知识与应用案例。致力于只做原创,以最简单的方式理解和学习,关注我一起交流成长。需要数据集和源码的小伙伴可以关注底部公众号添加作者微信。