Станьте свидетелем мощи глубокого обучения на огромных наборах данных!
В этой части 2 статьи мы создадим нашу нейронную сеть (ИНС) с использованием фреймворка keras.
Для части 1 (с использованием традиционного классификатора) перейдите по следующей ссылке:
Исходный код можно найти по следующей ссылке:
Обработка данных
Мы будем использовать данные, обработанные в Части 1. Обработанный набор данных состоит из 20 выбранных объектов, и нам нужно классифицировать, является ли астероид потенциально опасным или нет. Целевая переменная делится на 2 класса.
Импорт пакетов
Keras - простой инструмент для построения нейронной сети. Это высокоуровневый фреймворк, основанный на бэкэндах tensorflow, theano или cntk.
#Dependencies import tensorflow as tf import keras from keras.models import Sequential from keras.layers import Dense, Dropout from keras import optimizers from sklearn.metrics import confusion_matrix,classification_report,matthews_corrcoef
Построение нейронной сети
Мы определим функцию, которая будет содержать нашу архитектуру модели нейронной сети, чтобы ее можно было легко вызвать позже.
def NNmodel(init_mode,act,opt,n_top_features=n_top_features): #Setting random.seed for numpy and tensorflow to ensure reproducible results np.random.seed(42) tf.random.set_seed(42) # building a linear stack of layers with the sequential model model = Sequential() # hidden layer model.add(Dense(16,input_dim=n_top_features, kernel_initializer=init_mode, activation=act)) model.add(Dropout(0.2)) model.add(Dense(16, kernel_initializer=init_mode,activation=act)) model.add(Dropout(0.2)) # output layer model.add(Dense(1, activation='sigmoid')) # compiling the sequential model model.compile(loss='binary_crossentropy', metrics=['acc'], optimizer=opt) return model
- kernel_initializer: нейронная сеть должна начинаться с некоторых весов, а затем итеративно обновлять их до лучших значений. Этот термин используется для инициализации весов. (задается параметром init_mode функции NNmodel)
- Функция активации: это передаточная функция, которая используется для сопоставления выходных данных одного слоя с другим. (задается параметром act функции NNmodel). Для выходного слоя активация может быть «сигмоидной» (двоичный код) или «softmax» (мульти-класс).
- алгоритм оптимизации: они связывают вместе функцию потерь и параметры модели, обновляя модель в ответ на выходные данные функции потерь. Они придают вашей модели наиболее точную форму, изменяя веса. (задается параметром opt функции NNmodel)
- loss: вычисляется для получения градиентов относительно весов модели и соответствующего обновления этих весов с помощью обратного распространения ошибки. («Binary_crossentropy» для двоичного класса; «category_crossentropy» для мультикласса)
В нашем наборе данных вход состоит из 20 измерений (используется 20 основных функций), а на выходе - 2 значения (двоичный класс). Таким образом, входной и выходной слой имеют 20 и 1 размерность соответственно (но для мультиклассов выходной слой имеет размеры, равные количеству классов). В нашей нейронной сети мы используем два скрытых слоя по 16 измерений каждый.
Примечание. Выбрать количество скрытых слоев и узлов сложно, но есть определенные правила, которые могут помочь.
Чтобы лучше понять нейронные сети, обратитесь к этим статьям, в которых подробно объясняется тема:
Настройка гиперпараметров Keras
Вы можете использовать модели глубокого обучения из Keras с библиотекой scikit-learn на Python. Это позволит вам использовать возможности библиотеки scikit-learn для оптимизации гиперпараметров модели.
Чтобы выполнить случайный поиск с помощью последовательных моделей Keras, вы должны превратить эти модели в sklearn-совместимые оценщики с помощью Keras Wrappers для Scikit -Изучить API: [подробнее см. В документации]. Библиотека Keras предоставляет удобную оболочку для моделей глубокого обучения, которые можно использовать в качестве оценок классификации или регрессии в scikit-learn.
batch_size = 64 epochs = 10 from keras.wrappers.scikit_learn import KerasClassifier model_CV = KerasClassifier(build_fn=NNmodel, epochs=epochs, batch_size=batch_size, verbose=1) # define the search parameters init_mode = ['he_uniform','glorot_uniform'] act=['relu','selu','tanh'] opt=['rmsprop','adam'] param_distributions={'init_mode':init_mode,'act':act,'opt':opt} #Use RandomizedSearchCV to tune hyperparameters rand = RandomizedSearchCV(estimator=model_CV, param_distributions=param_distributions, n_jobs=-1, cv=3,random_state=42,verbose=10) rand_result = rand.fit(X_train_sfs_scaled, y_train) # print results print(f'Best Accuracy for {rand_result.best_score_} using {rand_result.best_params_}') #Store the best search results in NNmodel parameters init_mode=rand_result.best_params_['init_mode'] act=rand_result.best_params_['act'] opt=rand_result.best_params_['opt']
Мы передаем имя функции (NNmodel) классу KerasClassifier с помощью аргумента build_fn. Мы также передаем дополнительные аргументы epochs = 10 и batch_size = 64. Они автоматически объединяются и передаются функции fit (), которая вызывается изнутри классом KerasClassifier.
Настроенные гиперпараметры для нашего набора данных выглядят так: {init_mode = ’glorot_uniform’, act = ’tanh’, opt = ’adam’}
Модель обучения
Мы будем использовать настроенные гиперпараметры и подогнать модель под данные обучения.
labels=['Non-Hazardous','Hazardous'] NNperformance(init_mode,act,opt,n_top_features,epochs, batch_size,labels,X_train_sfs_scaled, y_train,X_test_sfs_scaled, y_test)
Здесь нам нужно указать метки классов и подогнать под модель. История обучения модели состоит из точности модели и потерь после каждой эпохи, которые можно визуализировать в виде кривых обучения для оценки производительности модели.
Модель Производительность
Для оценки и визуализации производительности модели мы создали три функции:
- LearningCurve: строит графики точности и потерь модели после каждой эпохи, чтобы понять, подходит ли модель для дурака или нет.
- PerformanceReports: строит матрицу неточностей и отчеты по классификации, чтобы оценить полноту и точность модели.
- NNPerformance: он подбирает модель к обучающим данным, делает прогнозы и вызывает две вышеуказанные функции для оценки производительности.
def LearningCurve(history): # summarize history for accuracy plt.subplot(211) plt.plot(history.history['acc']) plt.plot(history.history['val_acc']) plt.title('model accuracy') plt.ylabel('accuracy') plt.xlabel('epoch') plt.legend(['train', 'validation'], loc='upper left') plt.show() # summarize history for loss plt.subplot(212) plt.plot(history.history['loss']) plt.plot(history.history['val_loss']) plt.title('model loss') plt.ylabel('loss') plt.xlabel('epoch') plt.legend(['train', 'validation'], loc='upper left') plt.show() def PerformanceReports(conf_matrix,class_report,labels): ax= plt.subplot() sns.heatmap(conf_matrix, annot=True,ax=ax) # labels, title and ticks ax.set_xlabel('Predicted labels') ax.set_ylabel('True labels') ax.set_title('Confusion Matrix') ax.xaxis.set_ticklabels(labels) ax.yaxis.set_ticklabels(labels[::-1]) plt.show() sns.heatmap(pd.DataFrame(class_report).iloc[:-1, :].T, annot=True) plt.show() def NNperformance(init_mode,act,opt,n_top_features,epochs, batch_size,labels,X_train_sfs_scaled, y_train,X_test_sfs_scaled, y_test): np.random.seed(42) tf.random.set_seed(42) #fit the keras model on the dataset start_time = timeit.default_timer() model=NNmodel(init_mode,act,opt,n_top_features) history=model.fit(X_train_sfs_scaled, y_train, epochs=epochs, batch_size=batch_size,validation_data= (X_test_sfs_scaled, y_test),shuffle=True) scores_train = model.evaluate(X_train_sfs_scaled, y_train) scores_test = model.evaluate(X_test_sfs_scaled, y_test) print('Train Accuracy: %.2f' % (scores_train[1]*100)) print('Test Accuracy: %.2f' % (scores_test[1]*100)) # make class predictions with the model y_pred = model.predict_classes(X_test_sfs_scaled) cm=confusion_matrix(y_test,y_pred) cr=classification_report(y_test, y_pred, target_names=labels, output_dict=True) mcc= matthews_corrcoef(y_test, y_pred) print('Matthews Correlation Coefficient: ',mcc) PerformanceReports(cm,cr,labels) LearningCurve(history) elapsed = timeit.default_timer() - start_time print('Execution Time for deep learning model: %.2f minutes'% (elapsed/60))
- Глядя на кривые обучения, модель хорошо подходит, поскольку графики обучения и тестирования точности и потерь близки друг к другу.
- Точность - 64%
- Отзыв - 74%
Из графиков производительности моделей можно увидеть, что, хотя точность высока, точность и отзывчивость для опасных астероидов низки. Это можно объяснить тем, что данные несбалансированы, поскольку опасный класс астероидов составляет лишь 0,22% целевой переменной. (Из части 1)
Устранение дисбаланса классов
Мы можем использовать различные методы, такие как SMOTE, Near Miss, Random Sampling и т. Д., Чтобы справиться с дисбалансом классов. Мы использовали BorderlineSMOTE для решения этой проблемы, но вы можете попробовать эти различные выпрямители и увидеть изменения.
from imblearn.over_sampling import SMOTE,RandomOverSampler,BorderlineSMOTE from imblearn.under_sampling import NearMiss,RandomUnderSampler smt = SMOTE() nr = NearMiss() bsmt=BorderlineSMOTE(random_state=42) ros=RandomOverSampler(random_state=42) rus=RandomUnderSampler(random_state=42) X_train_bal, y_train_bal = bsmt.fit_sample(X_train_sfs_scaled, y_train) NNperformance(init_mode,act,opt,n_top_features,epochs, batch_size,labels,X_train_bal, y_train_bal,X_test_sfs_scaled, y_test)
- Глядя на кривые обучения, модель хорошо подходит, поскольку графики обучения и тестирования точности и потерь близки друг к другу.
- Точность - 64%
- Отзыв - 100% (улучшено с 74%)
Давайте сравним производительность модели сбалансированной нейронной сети с производительностью сбалансированного традиционного классификатора →
Из части 1 (традиционный классификатор)
- Точность - 23,2%
- Отзыв - 100%
Мы ясно видим, что точность нейронной сети намного выше (64%) по сравнению с точностью традиционного классификатора (23,2%). Это показывает силу глубокого обучения, когда дело касается огромных наборов данных.
Прежде чем ты уйдешь
Спасибо за чтение! Не стесняйтесь применять эту методологию к своим задачам классификации. Если у вас есть какие-либо трудности или сомнения, пожалуйста, оставьте комментарий ниже. Мы всегда высоко ценим вашу поддержку. Если вы хотите связаться со мной, напишите мне на [email protected].