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

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

Вступление

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

Предпосылки

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

Монтаж

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

  1. Python 3
  2. NumPy
  3. Панды
  4. Керас
  5. Scikit-Learn

Все они довольно просты в установке - вы можете щелкнуть по каждому, чтобы перейти на соответствующие веб-сайты, где представлены подробные инструкции по установке. Как правило, пакеты можно установить с помощью 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 возможных значений для каждого параметра. Это потребовало бы ручного ввода с нашей стороны каждый раз, когда мы хотим изменить значение параметра, повторно запустить код и отслеживать результаты для всех комбинаций параметров. Grid Search автоматизирует этот процесс, поскольку он просто берет возможные значения для каждого параметра и запускает код, чтобы опробовать все возможные комбинации, выводит результат для каждой комбинации, а также выводит комбинацию, которая дает наилучшую точность. Полезно, нет?

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

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

Мы будем использовать набор данных Pima Indian Diabetes, который содержит информацию о том, страдает ли пациент диабетом, на основе различных атрибутов, таких как концентрация глюкозы в крови, артериальное давление и т. Д. Используя 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() 

Выход:

набор данныхдиабета{.ezlazyload}

Как видите, все эти 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 

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

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

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

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

 # 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% . Это довольно мало, но волноваться не о чем! У нас все еще есть Grid Search, чтобы попытаться спасти положение. Итак, приступим к делу.

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

Если вы не используете Grid Search, вы можете напрямую вызвать метод fit() в модели, которую мы создали выше. Однако, чтобы использовать Grid Search, нам нужно передать некоторые параметры нашей функции 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} 

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

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

Заключение

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

comments powered by Disqus