Автор оригинала: Muhammad Junaid Khalid.
Вступление
В этом уроке мы поговорим об очень мощном алгоритме оптимизации (или автоматизации), то есть алгоритме поиска сетки. Он чаще всего используется для настройки гиперпараметров в моделях машинного обучения. Мы узнаем, как реализовать его с помощью Python, а также применим его в реальном приложении, чтобы увидеть, как он может помочь нам выбрать лучшие параметры для нашей модели и повысить ее точность. Итак, начнем.
Предпосылки
Чтобы следовать этому учебнику, вы должны иметь базовое представление о Python или каком-либо другом языке программирования. Желательно, но не обязательно, чтобы у вас были некоторые базовые знания о машинном обучении. Кроме того, эта статья удобна для начинающих и может быть использована кем угодно.
Установка
Чтобы пройти через этот учебник, вам необходимо иметь следующие библиотеки/фреймворки, установленные в вашей системе:
Все они довольно просты в установке – вы можете нажать на каждый из них, чтобы перейти на их соответствующие веб-сайты, где приведены подробные инструкции по установке. Как правило, пакеты могут быть установлены с помощью pip:
$ pip install numpy pandas tensorflow keras scikit-learn
Если у вас возникнут какие-либо проблемы, пожалуйста, обратитесь к официальной документации из каждого пакета.
Что такое Поиск по сетке?
Поиск по сетке-это, по сути, алгоритм оптимизации, который позволяет вам выбрать наилучшие параметры для вашей задачи оптимизации из списка параметров, которые вы предоставляете, следовательно, автоматизируя метод “проб и ошибок”. Хотя он может быть применен ко многим задачам оптимизации, но наиболее широко известен благодаря его использованию в машинном обучении для получения параметров, при которых модель дает наилучшую точность.
Предположим, что ваша модель принимает в качестве входных данных следующие три параметра:
- Количество скрытых слоев [2, 4]
- Количество нейронов в каждом слое [5, 10]
- Количество эпох [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% выше при поиске по сетке.