Рубрики
Без рубрики

Алгоритм оптимизации поиска сетки в Python

В статье объясняется, как использовать алгоритм оптимизации поиска сетки в Python для настройки гиперпараметров алгоритмов глубокого обучения.

Автор оригинала: Muhammad Junaid Khalid.

Вступление

В этом уроке мы поговорим об очень мощном алгоритме оптимизации (или автоматизации), то есть алгоритме поиска сетки. Он чаще всего используется для настройки гиперпараметров в моделях машинного обучения. Мы узнаем, как реализовать его с помощью Python, а также применим его в реальном приложении, чтобы увидеть, как он может помочь нам выбрать лучшие параметры для нашей модели и повысить ее точность. Итак, начнем.

Предпосылки

Чтобы следовать этому учебнику, вы должны иметь базовое представление о Python или каком-либо другом языке программирования. Желательно, но не обязательно, чтобы у вас были некоторые базовые знания о машинном обучении. Кроме того, эта статья удобна для начинающих и может быть использована кем угодно.

Установка

Чтобы пройти через этот учебник, вам необходимо иметь следующие библиотеки/фреймворки, установленные в вашей системе:

  1. Python 3
  2. NumPy
  3. Панды
  4. Керас
  5. Scikit-Учись

Все они довольно просты в установке – вы можете нажать на каждый из них, чтобы перейти на их соответствующие веб-сайты, где приведены подробные инструкции по установке. Как правило, пакеты могут быть установлены с помощью pip:

$ pip install numpy pandas tensorflow keras scikit-learn

Если у вас возникнут какие-либо проблемы, пожалуйста, обратитесь к официальной документации из каждого пакета.

Что такое Поиск по сетке?

Поиск по сетке-это, по сути, алгоритм оптимизации, который позволяет вам выбрать наилучшие параметры для вашей задачи оптимизации из списка параметров, которые вы предоставляете, следовательно, автоматизируя метод “проб и ошибок”. Хотя он может быть применен ко многим задачам оптимизации, но наиболее широко известен благодаря его использованию в машинном обучении для получения параметров, при которых модель дает наилучшую точность.

Предположим, что ваша модель принимает в качестве входных данных следующие три параметра:

  1. Количество скрытых слоев [2, 4]
  2. Количество нейронов в каждом слое [5, 10]
  3. Количество эпох [10, 50]

Если для каждого входного параметра мы хотим опробовать два варианта (как указано в квадратных скобках выше), то он составляет до 2 3 =8 различных комбинаций (например, одна из возможных комбинаций – [2,5,10]). Делать это вручную было бы головной болью.

Теперь представьте, что у нас есть 10 различных входных параметров, и мы хотим попробовать 5 возможных значений для каждого параметра. Это потребовало бы ручного ввода с нашей стороны каждый раз, когда мы хотим изменить значение параметра, перезапустить код и отслеживать результаты для всех комбинаций параметров. Поиск по сетке автоматизирует этот процесс, так как он просто берет возможные значения для каждого параметра и запускает код, чтобы опробовать все возможные комбинации, выводит результат для каждой комбинации, а также выводит комбинацию, которая дает наилучшую точность. Полезно, не так ли?

Реализация Поиска по Сетке

Ладно, хватит болтать. Давайте применим поиск по сетке к реальному приложению. Обсуждение части машинного обучения и предварительной обработки данных выходит за рамки этого учебника, поэтому мы просто запустим его код и подробно поговорим о той части, где используется поиск сетки. Давайте начнем!

Мы будем использовать набор данных Pima Indian Diabetes Dataset, который содержит информацию о том, является ли пациент диабетиком, основанную на различных атрибутах, таких как концентрация глюкозы в крови, кровяное давление и т. Д. Используя метод Pandas read_csv () , вы можете напрямую импортировать набор данных из онлайн-ресурса.

Следующий сценарий импортирует необходимые библиотеки:

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
import sys
import pandas as pd
import numpy as np

Следующий сценарий импортирует набор данных и устанавливает заголовки столбцов для этого набора данных.

columns = ['num_pregnant', 'glucose_concentration', 'blood_pressure', 'skin_thickness',
           'serum_insulin', 'BMI', 'pedigree_function', 'age', 'class']

data_path = "https://raw.githubusercontent.com/mkhalid1/Machine-Learning-Projects-Python-/master/Grid%20Search/pima-indians-diabetes.csv"

df = pd.read_csv(data_path, names=columns)

Давайте взглянем на первые 5 строк набора данных:

df.head()

Выход:

набор данных по диабету

Как вы можете видеть, все эти 5 строк являются метками для описания каждого столбца (на самом деле их 9), поэтому они нам не нужны. Мы начнем с удаления этих строк без данных, а затем заменим все значения NaN на 0:

# Remove first 9 non-data rows
df = df.iloc[9:]

# Replace NaN (Not a Number) values with 0 in each column
for col in columns:
    df[col].replace(0, np.NaN, inplace=True)

df.dropna(inplace=True) # Drop all rows with missing values
dataset = df.values # Convert dataframe to numpy array

Следующий сценарий делит данные на наборы объектов и меток и применяет стандартное масштабирование к набору данных:

X = dataset[:,0:8]
Y = dataset[:, 8].astype(int)

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

scaler = StandardScaler().fit(X)

# Transform and display the training data
X_standardized = scaler.transform(X)

data = pd.DataFrame(X_standardized)

Следующий метод создает нашу простую модель глубокого обучения:

def create_model(learn_rate, dropout_rate):
    # Create model
    model = Sequential()
    model.add(Dense(8, input_dim=8, kernel_initializer='normal', activation='relu'))
    model.add(Dropout(dropout_rate))
    model.add(Dense(4, input_dim=8, kernel_initializer='normal', activation='relu'))
    model.add(Dropout(dropout_rate))
    model.add(Dense(1, activation='sigmoid'))

    # Compile the model
    adam = Adam(lr=learn_rate)
    model.compile(loss='binary_crossentropy', optimizer=adam, metrics=['accuracy'])
    return model

Это весь код, который вам нужно будет запустить, чтобы загрузить набор данных, предварительно обработать его и создать свою модель машинного обучения. Поскольку мы заинтересованы только в том, чтобы увидеть функциональность поиска по сетке, я не выполнял разделение поезда/теста, и мы будем подгонять модель ко всему набору данных.

В следующем разделе мы рассмотрим, как поиск по сетке облегчает нашу жизнь, оптимизируя наши параметры.

Обучение модели без поиска сетки

В приведенном ниже коде мы создадим модель, используя значения параметров, которые мы выбрали случайным образом или на основе нашей интуиции, и посмотрим, как работает наша модель:

# Declare parameter values
dropout_rate = 0.1
epochs = 1
batch_size = 20
learn_rate = 0.001

# Create the model object by calling the create_model function we created above
model = create_model(learn_rate, dropout_rate)

# Fit the model onto the training data
model.fit(X_standardized, Y, batch_size=batch_size, epochs=epochs, verbose=1)

Выход:

Epoch 1/1
130/130 [==============================] - 0s 2ms/step - loss: 0.6934 - accuracy: 0.6000

Точность, которую мы получили, как вы можете видеть ниже, составляет 60,00% . Это довольно низко, но беспокоиться не о чем! У нас все еще есть поиск сетки, чтобы попытаться спасти положение. Итак, давайте перейдем к делу.

Оптимизация гиперпараметров с помощью поиска по сетке

Если вы не используете поиск по сетке, вы можете напрямую вызвать метод fit() в модели, которую мы создали выше. Однако, чтобы использовать поиск по сетке, нам нужно передать некоторые параметры нашей функции create_model () . Кроме того, нам нужно объявить нашу сетку с различными опциями, которые мы хотели бы попробовать для каждого параметра. Давайте сделаем это по частям.

Сначала мы модифицируем нашу функцию create_model () , чтобы принимать параметры от вызывающей функции:

def create_model(learn_rate, dropout_rate):
    # Create model
    model = Sequential()
    model.add(Dense(8, input_dim=8, kernel_initializer='normal', activation='relu'))
    model.add(Dropout(dropout_rate))
    model.add(Dense(4, input_dim=8, kernel_initializer='normal', activation='relu'))
    model.add(Dropout(dropout_rate))
    model.add(Dense(1, activation='sigmoid'))

    # Compile the model
    adam = Adam(lr=learn_rate)
    model.compile(loss='binary_crossentropy', optimizer=adam, metrics=['accuracy'])
    return model

# Create the model
model = KerasClassifier(build_fn=create_model, verbose=1)

Теперь мы готовы реализовать наш алгоритм поиска сетки и подогнать под него набор данных:

# Define the parameters that you wish to use in your Grid Search along
# with the list of values that you wish to try out
learn_rate = [0.001, 0.02, 0.2]
dropout_rate = [0.0, 0.2, 0.4]
batch_size = [10, 20, 30]
epochs = [1, 5, 10]

seed = 42

# Make a dictionary of the grid search parameters
param_grid = dict(learn_rate=learn_rate, dropout_rate=dropout_rate, batch_size=batch_size, epochs=epochs )

# Build and fit the GridSearchCV
grid = GridSearchCV(estimator=model, param_grid=param_grid,
                    cv=KFold(random_state=seed), verbose=10)

grid_results = grid.fit(X_standardized, Y)

# Summarize the results in a readable format
print("Best: {0}, using {1}".format(grid_results.best_score_, grid_results.best_params_))

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

for mean, stdev, param in zip(means, stds, params):
    print('{0} ({1}) with: {2}'.format(mean, stdev, param))

Выход:

Best: 0.7959183612648322, using {'batch_size': 10, 'dropout_rate': 0.2, 'epochs': 10, 'learn_rate': 0.02}

На выходе мы видим, что он дает нам комбинацию параметров, которая дает наилучшую точность.

Можно с уверенностью сказать, что поиск сетки был довольно легко реализован в Python и сэкономил нам много времени, с точки зрения человеческого труда. Вы можете просто перечислить все параметры, которые хотите настроить, объявить значения для тестирования, запустить свой код и забыть об этом. С вашей стороны больше не требуется никакой информации. Как только будет найдена наилучшая комбинация параметров, вы можете просто использовать ее для своей окончательной модели.

Вывод

Подводя итог, мы узнали, что такое поиск по сетке, как он может помочь нам оптимизировать нашу модель и какие преимущества он влечет за собой, например автоматизацию. Кроме того, мы научились реализовывать его в нескольких строках кода на языке Python. Чтобы увидеть его эффективность, мы также обучили модель машинного обучения с выполнением поиска по сетке и без него, и точность была на 19% выше при поиске по сетке.