Сверточная нейронная сеть с возможностями увеличения данных и обучения с передачей!

Общая информация

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].