Сверточная нейронная сеть с возможностями увеличения данных и обучения с передачей!
Общая информация
CNN
Сверточная нейронная сеть (CNN) является основой большинства технологий компьютерного зрения. В отличие от традиционных архитектур многослойного перцептрона, он использует две операции, называемые свертка и объединение, чтобы уменьшить изображение до его основных функций, и использует эти функции для понимания и классификации изображения.
Увеличение объема данных
Это метод, который можно использовать для искусственного увеличения размера набора обучающих данных путем создания модифицированных версий изображений в наборе данных. Обучение моделей нейронных сетей глубокого обучения на большем количестве данных может создавать вариации изображений, которые могут улучшить способность подходящих моделей обобщать то, что они узнали, для новых изображений.
Перенос обучения
Это идея преодоления изолированной парадигмы обучения и использования знаний, полученных для одной задачи, для решения связанных. Мы замораживаем ранние сверточные слои сети и обучаем только несколько последних слоев, которые делают прогноз. Идея состоит в том, что сверточные слои извлекают общие низкоуровневые функции, которые применимы ко всем изображениям, а более поздние слои определяют конкретные функции.
Почему Google Colab?
Обучение модели глубокого обучения на обычном ноутбуке требует больших вычислительных мощностей и часто выполняется бесконечно. Это может отговорить новичков от личного знакомства с миром глубокого обучения.
С помощью Colab вы можете выполнять код на облачных серверах Google, используя мощь оборудования Google, включая графические процессоры и TPU, независимо от мощности вашего компьютера.
Создание новой записной книжки
Чтобы создать новый блокнот на Colab, откройте https://colab.research.google.com/, и он автоматически покажет ваши предыдущие блокноты и даст возможность создать новый блокнот.
Здесь вы можете щелкнуть НОВУЮ ЗАПИСЬ, чтобы запустить новую записную книжку и запустить в ней свой код. По умолчанию это записная книжка Python 3.
Все записные книжки, которые вы создаете в Google Colab, по умолчанию хранятся на вашем Google Диске. На вашем диске есть папка с именем «Colab Notebooks», в которой вы можете найти все ваши записные книжки, созданные с помощью Google Colab.
Чтобы открыть записную книжку с Диска в Colab, щелкните правой кнопкой мыши нужную записную книжку и выберите «Открыть с помощью› Google Colaboratory ».
Загрузить данные с диска
Вы можете легко загрузить данные с Google Диска, подключив его к ноутбуку. Для этого введите в записную книжку следующий код.
from google.colab import drive drive.mount('/content/drive')
Это даст вам ссылку для открытия,
- Перейти по ссылке
- Войдите в свою учетную запись Google
- Скопируйте код
- Вставить в блокнот
Теперь, если вы видите в разделе «Файлы», вы найдете свой «диск».
Допустим, вы загрузили изображения в папку "Плотоядные".
Вы можете получить изображения, скопировав их путь и вставив их в переменные пути.
train_path='/content/drive/My Drive/carnivores/train' test_path='/content/drive/My Drive/carnivores/test'
Классификация изображений хищников
Данные состоят из изображений 4 хищников с 3 континентов → гепарда и гиены (Африка), ягуара (Южная Америка) и тигра (Азия). Обучающий набор состоит из 3600 изображений (900 для каждого хищника), а тестовый набор состоит из 400 изображений (100 для каждого хищника). У данных очень мало примеров, на которых можно поучиться, и, таким образом, это сложная проблема машинного обучения, но она также реалистична: во многих реальных случаях использования даже мелкомасштабный сбор данных может быть чрезвычайно дорогостоящим или иногда близким к -невозможно.
Для загрузки данных перейдите по следующей ссылке:
Мы будем использовать библиотеку нейронной сети глубокого обучения Keras, которая обеспечивает возможность подгонки моделей с использованием увеличения данных изображения с помощью класса ImageDataGenerator. Мы также будем использовать предварительно обученную модель InceptionV3 для трансферного обучения.
Импорт пакетов
import numpy as np import matplotlib.pyplot as plt import pandas as pd import sklearn import mathimport warnings warnings.filterwarnings("ignore")
Предварительно обученная модель CNN в качестве экстрактора признаков
Давайте воспользуемся Keras, загрузим модель InceptionV3 и зафиксируем блоки свертки, чтобы мы могли использовать ее как средство извлечения функций изображения.
import keras from keras.applications.inception_v3 import InceptionV3 from keras.models import Model,load_model conv_base = InceptionV3(weights='imagenet',include_top=False, input_shape=(300, 300, 3)) output = conv_base.layers[-1].output output = keras.layers.Flatten()(output) model_tl = Model(conv_base.input, output) model_tl.trainable = False for layer in model_tl.layers: layer.trainable = False layers = [(layer, layer.name, layer.trainable) for layer in model_tl.layers] model_layers=pd.DataFrame(layers, columns=['Layer Type', 'Layer Name', 'Layer Trainable']) print(model_layers)
Все слои модели InceptionV3 теперь заморожены (Layer Trainable имеет значение False для всех слоев), потому что мы не хотим, чтобы их веса изменялись во время обучения модели. Последняя карта функций активации в модели InceptionV3 дает нам узкие места, которые затем можно сгладить и передать в полностью подключенный классификатор глубокой нейронной сети.
Предварительная обработка и увеличение данных
Чтобы максимально использовать наши несколько обучающих примеров, мы «увеличим» их с помощью ряда случайных преобразований, чтобы наша модель никогда не увидела дважды одно и то же изображение. Это помогает предотвратить переоснащение и помогает модели лучше обобщить.
В Keras это можно сделать с помощью класса ImageDataGenerator. Этот класс позволяет:
- настраивать случайные преобразования и операции нормализации, которые будут выполняться с данными изображения во время обучения
- создавать экземпляры генераторов пакетов расширенных изображений (и их меток) через
.flow_from_directory(directory)
. Эти генераторы затем можно использовать с методами модели Keras, которые принимают генераторы данных в качестве входных данных.
from keras.models import Sequential from keras.layers import Dense, Dropout, Conv2D, MaxPool2D, Flatten from keras.preprocessing.image import ImageDataGenerator from keras import optimizers test_size=400 batch_size=32 epochs=25 train_path='/content/drive/My Drive/carnivores/train' test_path='/content/drive/My Drive/carnivores/validation' target_size=(300,300) #resize all images to 300x300 train_datagen = ImageDataGenerator(rescale=1./255, zoom_range=0.3, rotation_range=50, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, horizontal_flip=True, brightness_range = [0.8, 1.2], fill_mode='nearest', validation_split=0.2) test_datagen = ImageDataGenerator(rescale=1./255) # The list of classes will be automatically inferred from the subdirectory names/structure under train_dir train_generator = train_datagen.flow_from_directory( train_path, target_size=target_size,# batch_size=batch_size, class_mode='categorical', subset='training') validation_generator = train_datagen.flow_from_directory( train_path, target_size=target_size, batch_size=batch_size, class_mode='categorical', subset='validation')
Керас теперь добавил разделение на поезд / проверку из единого каталога с помощью ImageDataGenerator. Используя validation_split в ImageDataGenerator, данные обучения разделяются на 2 подмножества → обучение и проверка.
Архитектура модели здания
Давайте теперь построим архитектуру нашего классификатора глубокой нейронной сети, которая будет принимать в качестве входных данных упомянутые выше сглаженные узкие места.
from keras.models import Sequential from keras.layers import Dense, Dropout, Conv2D, MaxPool2D, Flatten from keras import optimizers # building a linear stack of layers with the sequential model model =Sequential() model.add(model_tl) # hidden layer model.add(Dense(128, activation='relu')) model.add(Dropout(0.2)) # output layer model.add(Dense(4, activation='softmax')) # compiling the sequential model model.compile(loss='categorical_crossentropy', optimizer=optimizers.RMSprop(lr=1e-4), metrics=['acc']) print(model.summary())
Сохранение контрольных точек модели
Google Colab обеспечивает максимальное время работы графического процессора 12 часов «в идеале» за раз, он может отключиться раньше этого срока, если они обнаружат неактивность (в течение 90 минут) или при большой нагрузке. Поэтому мы будем сохранять контрольные точки с помощью обратных вызовов в Keras перед подгонкой модели, чтобы наш прогресс не был потерян.
from keras.callbacks import * filepath="/content/drive/My Drive/MyCNN/epochs:{epoch:03d}-val_acc: {val_acc:.3f}.hdf5" checkpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=False, save_freq='epoch', mode='max') callbacks_list = [checkpoint]
- путь к файлу: для папки с именем MyCNN на диске (создайте эту новую папку на вашем диске), и каждый файл будет сохранен с номером эпохи и проверкой. точности, эти файлы содержат веса вашей нейронной сети.
- ModelCheckpoint: для аргументов, переданных в приведенном выше коде, он отслеживает точность проверки и сохраняет точность проверки после каждой эпохи.
- callbacks_list: сделайте его списком, чтобы вы могли добавлять в этот список любые другие обратные вызовы и передавать его в функцию соответствия во время обучения.
Возобновление тренировки после отключения
- Смонтируйте диск в новой среде выполнения
- Используйте ту же архитектуру и создайте модель
model.load_weights('/content/drive/My Drive/MyCNN/epochs:020-val_acc:0.985.hdf5')
загрузка весов с контрольной точки, где в 20-ю эпоху точность проверки достигла 98,5%.- Затем скомпилируйте и подогнайте модель (в model.fit () добавьте дополнительный параметр → initial_epoch = 20; последняя эпоха до сохранения вашей модели), возобновив с 21-й эпохи и так далее.
Модель обучения
Мы будем использовать архитектуру с контрольными точками и подогнать модель под данные обучения.
history = model.fit( train_generator, steps_per_epoch=train_generator.samples//batch_size, validation_data=validation_generator, validation_steps=validation_generator.samples//batch_size, epochs=epochs, verbose=1, shuffle=True, callbacks=callbacks_list)
Вы можете ясно видеть, что он начинает сохранять модель после каждой эпохи.
Модель Производительность
Для оценки и визуализации производительности модели мы создали функцию:
- LearningCurve: строит графики точности и потерь модели после каждой эпохи, чтобы понять, подходит ли модель для дурака или нет.
# Model evaluation scores_train = model.evaluate(train_generator,verbose=1) scores_validation = model.evaluate(validation_generator,verbose=1) print("Train Accuracy: %.2f%%" % (scores_train[1]*100)) print("Validation Accuracy: %.2f%%" % (scores_validation[1]*100)) #For plotting Accuracy and Loss def LearningCurve(history): # summarize history for accuracy 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.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() LearningCurve(history) #Save the trained model to a file model_weight_file='/content/drive/MyDrive/MyCNN/ carnivores_tlearn_img_aug_cnn.h5' model.save(model_weight_file)
Мы видим, что наша модель имеет точность обучения 99,51% и точность проверки 99,03%. Точность обучения и проверки довольно близки друг к другу, что указывает на то, что модель хорошо подходит.
Прогнозы
Мы будем использовать тестовые данные, чтобы делать прогнозы и смотреть, как наша модель работает с невидимыми данными.
# We take the ceiling because we do not drop the remainder of the batch compute_steps_per_epoch = lambda x: int(math.ceil(1. * x / batch_size)) test_steps = compute_steps_per_epoch(test_size) test_generator = test_datagen.flow_from_directory( test_path, target_size=target_size, batch_size=batch_size, class_mode=None, shuffle=False) test_generator.reset() #Calling the saved model for making predictions tl_img_aug_cnn = load_model(model_weight_file) pred=tl_img_aug_cnn.predict(test_generator, verbose=1, steps=test_steps) predicted_class_indices=np.argmax(pred,axis=1) labels = (test_generator.class_indices) labels = dict((v,k) for k,v in labels.items()) predictions = [labels[k] for k in predicted_class_indices] filenames=test_generator.filenames results=pd.DataFrame({"Filename":filenames, "Predictions":predictions}) #create a function for visualizing model performance import seaborn as sns 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) plt.show() ax= plt.subplot() sns.heatmap(pd.DataFrame(class_report).iloc[:-1, :].T, annot=True,ax=ax) ax.set_title('Classification Report') plt.show() from sklearn.metrics import confusion_matrix,classification_report,accuracy_score labels=['cheetah','hyena','jaguar','tiger'] test_labels = [fn.split('/')[0] for fn in filenames] cm=confusion_matrix(test_labels,predictions) print(cm) cr=classification_report(test_labels, predictions) class_report=classification_report(test_labels, predictions, target_names=labels, output_dict=True) print(cr) PerformanceReports(cm,class_report,labels)
Использование функции .predict()
даст результат в виде вероятностей, поэтому нам нужно преобразовать их в номер класса. В данном случае это было 4 класса, поэтому номера классов были 0,1,2 и 3.
predicted_class_indices=np.argmax(pred,axis=1)
Следующим шагом будет имя классов:
labels = (train_generator.class_indices)
labels = dict((v,k) for k,v in labels.items())
predictions = [labels[k] for k in predicted_class_indices]
Номера классов будут заменены названиями классов. Наконец, разместите его во фрейме данных, добавив к именам изображений предсказанный класс.
filenames=test_generator.filenames
results=pd.DataFrame({"Filename":filenames,
"Predictions":predictions})
Прежде чем ты уйдешь
Спасибо за чтение! Не стесняйтесь применять эту методологию к своим задачам классификации изображений. Если у вас есть какие-либо трудности или сомнения, пожалуйста, оставьте комментарий ниже. Мы всегда высоко ценим вашу поддержку. Если вы хотите связаться со мной, напишите мне на [email protected].