在Python中的网格搜索

在Python中的网格搜索

在本教程中,我们将讨论网格搜索作为超参数调优的方法。我们还将学习网格搜索的工作原理,并实施它以优化机器学习(ML)方法的性能。

超参数调优 对于机器学习(ML)模型的正确工作非常重要。像 网格搜索 这样的方法似乎是超参数优化的基本工具。

网格搜索 方法考虑一些超参数组合,并选择返回较低误差分数的组合。当只有一些需要优化的超参数时,这种方法特别有用。然而,当机器学习模型变得复杂时,它的性能被其他加权随机搜索方法超越。

所以让我们开始了解网格搜索。

理解网格搜索

网格搜索 是一种优化算法,允许我们从我们提供的参数选择列表中选择最佳参数以优化问题,从而自动化“试错”方法。尽管我们可以将其应用于多个优化问题;但是,它最常被用于机器学习中以获取使模型提供最佳准确性的参数。

让我们考虑模型在输入中接受以下三个参数:

  1. 隐藏层的数量[2, 4]
  2. 每个层的神经元数量[5, 10]
  3. 迭代次数[10, 50]

如果我们想要尝试每个参数输入的两个选项(如上方方括号中所指定的),它将估计不同的组合。例如,一个可能的组合可能是[2, 5, 10]。手动找到这样的组合会非常麻烦。

现在,假设我们有十个不同的输入参数,并且我们想要尝试每个参数的五个可能值。每次我们想要改变参数的值,重新执行代码,并为参数的每种组合记录输出,都需要程序员手动输入。。

网格搜索自动化了这个过程,它接受每个参数的可能值并执行代码,以尝试每个可能的组合输出,并输出具有最佳准确性的组合。

安装所需的库

在 Python编程语言 中实施网格搜索之前,让我们简要讨论一些需要在系统中安装的必要库和框架。

这些库和框架如下:

  1. Python 3
  2. NumPy
  3. Pandas
  4. Keras
  5. Scikit-Learn

安装它们都非常简单。我们可以使用pip安装程序来安装这些库,如下所示:

$ pip install numpy tensorflow pandas scikit-learn keras

注意:如果在执行任何程序包时出现任何问题,请尝试重新安装并参考每个程序包的官方文档。

现在,让我们开始在Python中实现网格搜索。

Python中网格搜索的实现

在接下来的部分,我们将了解如何在实际应用中实现网格搜索。我们将仅执行代码,并深入讨论网格搜索所涉及的部分,而不讨论机器学习和数据预处理部分。

所以,让我们开始吧。

我们将使用包含有关不同人员的身高和体重的Diet数据集,根据性别、年龄和饮食类型等各种属性。我们可以借助Pandas的read_csv()函数直接从在线资源导入数据。

但在此之前,我们必须导入所需的程序包:

文件:mygrid.py

import sys
import pandas as pd
import numpy as np
from sklearn.model_selection import GridSearchCV, KFold
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.wrappers.scikit_learn import KerasClassifier
from keras.optimizers import Adam

解释:

在上面的代码片段中,我们导入了项目所需的包和库。可以保存程序文件并执行,以检查库和包是否已正确安装和导入。

成功导入包后,我们必须使用以下代码片段导入数据集并打印其前五行。

文件:mygrid.py

# importing the dataset
mydf = pd.read_csv("Diet_Dataset.csv")

# printing the first five lines of dataset
print(mydf.head())

输出:

   Person gender  Age  Height  pre.weight  Diet  weight6weeks
0      25          41     171          60     2          60.0
1      26          32     174         103     2         103.0
2       1      0   22     159          58     1          54.2
3       2      0   46     192          60     1          54.0
4       3      0   55     170          64     1          63.3

说明:

在上面的代码片段中,我们使用 pandas 库的 read_csv() 方法导入了数据集,并将其存储在变量 mydf 中。然后我们使用 head() 函数和 mydf 变量打印了前五行数据。

现在,我们将数据分成特征集和标签集,以便对数据集应用标准缩放。

下面是相同操作的代码片段:

文件:mygrid.py

# converting dataframe into numpy array
mydataset = mydf.values

X = mydataset[:, 0:6]
Y = mydataset[:, 6].astype(int)

# Normalizing the data using sklearn StandardScaler
from sklearn.preprocessing import StandardScaler

myscaler = StandardScaler().fit(X)

# Transforming and displaying the training data
X_stdized = myscaler.transform(X)

mydata = pd.DataFrame(X_stdized)

解释:

在上面的代码片段中,我们将pandas dataframe转换为NumPy数组。然后我们从sklearn库中导入StandardScaler模块,并使用该函数对数据进行归一化处理。然后我们使用transform()函数对训练数据进行转换和显示。

现在,让我们考虑以下代码片段以创建一个简单的深度学习模型。

文件:mygrid.py

# defining the function to create model
def create_my_model(learnRate, dropoutRate):
    # Creating model
    mymodel = Sequential()
    mymodel.add(Dense(6, input_dim = 6, kernel_initializer = 'normal', activation = 'relu'))
    mymodel.add(Dropout(dropoutRate))
    mymodel.add(Dense(3, input_dim = 6, kernel_initializer = 'normal', activation = 'relu'))
    mymodel.add(Dropout(dropoutRate))
    mymodel.add(Dense(1, activation = 'sigmoid'))

    # Compiling the model
    my_Adam = Adam(learning_rate = learnRate)
    mymodel.compile(loss = 'binary_crossentropy', optimizer = my_Adam, metrics = ['accuracy'])
    return mymodel

解释:

下面的代码片段定义了一个函数, create_my_model() 接受两个参数, learnRatedropoutRate ,我们使用 Sequential() 函数创建了模型 mymodel 。我们还使用了 add() 函数和 Dense() 函数、 Dropout() 函数。最后,我们使用 compile() 函数编译了模型。

因此,当我们执行这段代码时,将加载数据集,对其进行预处理,并创建一个机器学习模型。由于我们只关心网格搜索的工作原理,我们没有进行训练/测试分割,并且我们将模型拟合到了整个数据集上。

在下一节中,我们将了解网格搜索如何通过优化参数来简化程序员的工作。

不使用网格搜索训练模型

在下面显示的代码片段中,我们将根据随机选择的参数值或基于直觉创建一个模型,并查看模型的性能:

文件:mygrid.py

# Declaring the values of the parameter
dropoutRate = 0.1
epochs = 1
batchSize = 20
learnRate = 0.001

# Creating the model object by calling the create_my_model function we created above
mymodel = create_my_model(learnRate, dropoutRate)

# Fitting the model onto the training data
mymodel.fit(X_stdized, Y, batch_size = batchSize, epochs = epochs, verbose = 1)

输出:

4/4 [==============================] - 41s 14ms/step - loss: 0.9364 - accuracy: 0.0000e+00

解释:

在上面的代码片段中,我们声明了参数的值,即 dropoutRate,epochs,batchSizelearnRate 。然后,我们调用 create_my_model() 函数创建模型对象。然后,我们将模型拟合到训练数据上。

结果是,我们得到的准确率是0.0000e+00。

使用网格搜索优化超参数

如果我们不使用网格搜索方法,我们可以直接在上面创建的模型上调用 fit() 函数。但是为了使用网格搜索方法,我们必须传入一些参数给 create_my_model() 函数。此外,我们还必须为每个参数声明具有不同选项的网格以尝试。让我们在不同的部分中执行。

首先,我们将尝试修改 create_my_model() 函数以便接受来自调用函数的参数,如下所示:

文件:mygrid.py

def create_my_model(learnRate, dropoutRate):
    # Creating the model
    mymodel = Sequential()
    mymodel.add(Dense(6, input_dim = 6, kernel_initializer = 'normal', activation = 'relu'))
    mymodel.add(Dropout(dropoutRate))
    mymodel.add(Dense(3, input_dim = 6, kernel_initializer = 'normal', activation = 'relu'))
    mymodel.add(Dropout(dropoutRate))
    mymodel.add(Dense(1, activation = 'sigmoid'))

    # Compile the model
    myadam = Adam(learning_rate = learnRate)
    mymodel.compile(loss = 'binary_crossentropy', optimizer = myadam, metrics = ['accuracy'])
    return mymodel

# Creating the model object
mymodel = KerasClassifier(build_fn = create_my_model, verbose = 1)

Explanation:

在上面的代码片段中,我们对之前的 create_my_model 函数进行了一些更改,并使用了 KerasClassifier 来创建模型对象。

现在,让我们实现网格搜索算法,并将数据集拟合到其中:

文件:mygrid.py

# Defining the arguments that we want to use in Grid Search along
# with the list of values that we want to try out
learnRate = [0.001, 0.02, 0.2]
dropoutRate = [0.0, 0.2, 0.4]
batchSize = [10, 20, 30]
epochs = [1, 5, 10]

# Making a dictionary of the grid search parameters
paramgrid = dict(learnRate = learnRate, dropoutRate = dropoutRate, batch_size = batchSize, epochs = epochs )

# Building and fitting the GridSearchCV
mygrid = GridSearchCV(estimator = mymodel, param_grid = paramgrid, cv = KFold(random_state = None), verbose = 10)

gridresults = mygrid.fit(X_stdized, Y)

# Summarizing the results in a readable format
print("Best: " + gridresults.best_score_ + " using " + gridresults.best_params_)

means = gridresults.cv_results_['mean_test_score']
stds = gridresults.cv_results_['std_test_score']
params = gridresults.cv_results_['params']

for mean, stdev, param in zip(means, stds, params):
    print(mean + "(" + stdev + ")" + " with: " + param)

输出:

Best: 0.00347268912077, using {batch_size=10, dropoutRate=0.4, epochs=5, learnRate=0.2}

说明:

以上输出显示了产生最佳准确率的参数组合。

最后,我们可以得出结论,网格搜索在Python编程语言中非常容易实现,为我们节省了大量的人力成本。我们可以列出所有需要调整的参数,声明需要测试的值,执行代码,然后忘记它。这个过程非常简单方便,需要程序员输入较少。一旦找到了最佳的参数组合,我们可以将其用于最终模型。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程