Краткий обзор трансферного обучения и пример использования предварительно обученных моделей для глубокого обучения с InceptionV3.

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

Глубокое обучение

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

Так что же такое сверточная нейронная сеть?

Сверточная нейронная сеть - это просто еще один метод обучения сети (модели), чтобы дать точную классификацию. Из всех других нейронных сетей сверточные нейронные сети отлично подходят для обучения компьютерному зрению. Что делает CNN или (covnets) удивительными, так это то, что шаблоны, которые они изучают из изображений, инвариантны к переводу, то есть, если они улавливают шаблон в углу изображения, они распознают тот же шаблон в любом другом углу изображения, тогда как обычная сеть будет приходиться переучивать это снова и снова. Covnets также могут изучать пространственные иерархии шаблонов, что означает, что каждый уровень Covnet будет изучать что-то свое. Первый слой может изучать небольшие шаблоны, а следующий слой может изучать более крупные шаблоны, которые являются особенностями первого слоя. Эти характеристики получаются с помощью функции свертки.

Свертка

Функция свертки используется для получения карт признаков (матриц признаков) для сверточного слоя. По умолчанию, covnets настроили веса, которые состоят из ядра. Ядро используется для получения различных функций из входного изображения (входного слоя), например, его можно использовать для сбора резкости входного изображения, краев или сбора информации о том, как обнаружить край. Эта функция может быть представлена ​​как n * n, которая представляет собой матрицу, содержащую множество уникальных значений. Ядро сворачивает (скользит и умножается) поверх входного изображения, и скажем, входное изображение - (10,10), а ядро ​​- (3,3). Первый слайд (шаг) будет умножаться на 9 пикселей в самом верхнем левом углу входного изображения, чтобы получить на выходе один пиксель в верхнем левом углу новой матрицы, называемой картой характеристик.

Это умножение продолжается, когда ядро ​​движется по входному изображению вот так.

Этот непрерывный процесс не прекращается до тех пор, пока вся матрица признаков не будет заполнена этими свернутыми значениями, а после завершения матрицы признаков она не будет помещена в сверточный слой. Если сеть спроектирована для этого, другое ядро ​​будет создавать другую матрицу признаков с тем же входным изображением для хранения следующей матрицы признаков в том же сверточном слое.

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

Что такое трансферное обучение и чем оно может помочь?

Трансферное обучение делает жизнь всех проще и лучше. Хотя создание сверточных нейронных сетей с нуля - это весело, они могут быть немного дорогими, а также потребовать больших вычислительных мощностей. Поэтому, чтобы уменьшить количество энергии, необходимое для сети, мы используем трансферное обучение, которое представляет собой предварительно обученные веса, которые уже прошли обучение на другом изображении, чтобы повысить производительность нашей сети. Что делает использование предварительно обученных моделей оптимальным выбором, так это тот факт, что они уже были настроены и обучены на миллионах других изображений, которые состоят из тысяч классов в течение многих дней за раз, чтобы обеспечить высокопроизводительные предварительно обученные веса, которые нам нужны для того, чтобы с легкостью обучать собственную сеть (Адитья Анантрам, 2018).

Практическое применение

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

Описание данных

Набор данных содержит 81 104 изображения различных фруктов и овощей, состоящих из 120 уникальных классификаций для каждого изображения фруктов и овощей. Общее количество изображений разделено на наборы данных для обучения и тестирования. Набор обучающих данных содержит 60 486 изображений, а набор тестовых данных - 20 618 изображений.

Размер всех изображений составляет 100x100 пикселей, и они были собраны камерой logitech C920, которая использовалась для съемки фруктов и овощей (Михай Олтеан, 2019). Все фрукты и овощи были посажены в шахту с помощью тихоходного двигателя, где они были записаны за короткий промежуток времени, по 20 секунд каждый. Изображения для тестирования фруктов и овощей были сделаны с помощью смартфона Nexus 5X.

Модель

Выбранная модель трансферного обучения называется InceptionV3. Модель представляет собой сверточную нейронную сеть, архитектурно спроектированную так, чтобы иметь 48 уровней, глубоко обученных на формах изображений 299 на 299. Первоначальная сеть архитектуры Inception называлась GoogLeNet и представляла собой 27-слойную сверточную нейронную сеть, созданную еще в 2014 году (Shaikh, 2018). ). Название модели происходит от фильма Начало режиссера Кристофера Нолана, основанного на концепции погружения в сновидение Сон во сне, что переводится в сверточную нейронную сеть внутри сверточной нейронной сети.

Идея, лежащая в основе дизайна GoogLeNet, заключалась в устранении проблем, которые обычно встречаются при переобучении при работе с более глубокими нейронными сетями. Переобучение обычно происходит, когда набор данных слишком мал и обучается в большой нейронной сети, а проблема переобучения заключается в искажении точности проверки (точности тестирования) модели. Точность тестирования - это мера того, насколько точно обученная сеть точно предсказывает изображения, которых она не видела. Решение для проектирования огромной сети для обеспечения такой точности состоит в создании редко связанной нейронной сети вместо полностью связанной нейронной сети (Shaikh, 2018), и именно по этой причине модель GoogLeNet выиграла конкурс визуального распознавания ImageNet с призом прогнозная точность 80% + еще в 2014 году.

Модель Архитектура

Модель InceptionV3 соединена с двумя полностью связанными слоями внизу, но ее размерность уменьшена с 3D до 1D с Global Average Pooling 2D перед этим соединением. Объединение также выдаст один ответ для каждой матрицы функций. После объединения следующий уровень архитектуры - это первый плотный скрытый слой с 512 единицами (нейронами), который будет подключен к окончательному выходному слою с 10 нейронами, чтобы соответствовать количеству классов фруктов и овощей. Так выглядит архитектура InceptionV3.

Вот так выглядят нижние полностью связанные слои, прикрепленные к архитектуре.

Также стоит упомянуть о тонкой настройке этих предварительно обученных моделей и связанных с ними весов. Я могу выбрать, какие веса я хочу использовать из модели, и это может быть верхняя половина, нижняя половина, середина, или я могу заморозить все веса. Это означает, что, какая бы часть предварительно обученной модели я ни заморозила, не будут тренируемыми весами, которые можно будет обновить для модели, которую я создаю. Я также могу выбрать веса изображения, на котором была обучена модель, но для этого примера методом проб и ошибок я решил не фиксировать веса. Моя реализация InceptionV3 будет использовать предварительно обученные веса на ImageNet. ImageNet - это база данных изображений, организованная в соответствии с иерархией« WordNet (в настоящее время только существительные), в которой каждый узел иерархии представлен сотнями и тысячами изображений. В настоящее время у нас в среднем более пятисот изображений на узел ». (ImageNet, 2017 г.)

Наконец код

Теперь, когда у вас есть представление о том, как выглядит набор данных и об архитектуре модели, пора приступить к выполнению.

Подготовка данных и обучение сети

Загрузка библиотек.

Перво-наперво; нам нужно загрузить необходимые библиотеки. При загрузке библиотек убедитесь, что все необходимые модули импортированы, чтобы мы могли подготовить данные и обучить модель.

# read in libraries
import tensorflow as tf
from tensorflow.keras import backend, models, layers, optimizers
import numpy as np
from tensorflow.keras.layers import GlobalAveragePooling2D
from tensorflow.keras.callbacks import EarlyStopping
from sklearn.model_selection import train_test_split
from tensorflow.keras.utils import plot_model
from IPython.display import display
from PIL import Image
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import os, shutil
from tensorflow.keras.models import Model
np.random.seed(42)

Загрузите данные и подготовьте их.

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

# Specify the base directory where images are located.
base_dir = '/kaggle/input/fruits/fruits-360/'

# Specify the traning, validation, and test dirrectories.  
train_dir = os.path.join(base_dir, 'Training')
test_dir = os.path.join(base_dir, 'Test')
# Normalize the pixels in the train data images, resize and augment the data.
train_datagen = ImageDataGenerator(
    rescale=1./255,# The image augmentaion function in Keras
    shear_range=0.2,
    zoom_range=0.2, # Zoom in on image by 20%
    horizontal_flip=True) # Flip image horizontally 
# Normalize the test data imagees, resize them but don't augment them
test_datagen = ImageDataGenerator(rescale=1./255) 

train_generator = train_datagen.flow_from_directory(
    train_dir,
    target_size=(299, 299),
    batch_size=16,
    class_mode='categorical')
test_generator = test_datagen.flow_from_directory(
    test_dir,
    target_size=(299, 299),
    batch_size=16,
    class_mode='categorical')

Подготовьте модель InceptionV3

Теперь, когда изображения подготовлены, пора импортировать и настроить предварительно обученную модель InceptionV3 для обучения передачи.

# Load InceptionV3 library
from tensorflow.keras.applications.inception_v3 import InceptionV3
# Always clear the backend before training a model
backend.clear_session()
# InceptionV3 model and use the weights from imagenet
conv_base = InceptionV3(weights = 'imagenet', #Useing the inception_v3 CNN that was trained on ImageNet data.  
                  include_top = False)

Создайте функциональную модель API.

Теперь давайте объединим предварительно обученные веса модели InceptionV3 с плотными слоями (полностью связанные слои) и уменьшим размерность модели между ними.

# Connect the InceptionV3 output to the fully connected layers
InceptionV3_model = conv_base.output
pool = GlobalAveragePooling2D()(InceptionV3_model)
dense_1 = layers.Dense(512, activation = 'relu')(pool)
output = layers.Dense(120, activation = 'softmax')(dense_1)

Отобразите функциональную модель API.

Чтобы понять архитектуру модели, мы можем отобразить функциональную модель API в целом, чтобы визуально увидеть глубину сети.

# Create an example of the Archictecture to plot on a graph
model_example = models.Model(inputs=conv_base.input, outputs=output)
# plot graph
plot_model(model_example)

(Модель слишком велика для отображения здесь на Medium, нажмите эту ссылку, чтобы увидеть)

Определите модель и скомпилируйте ее.

Чтобы обучить модель, нам необходимо определить функциональную модель API и скомпилировать модель с категориальной кросс-энтропией в качестве функции потерь и стохастическим градиентным спуском с параметрами скорости обучения и импульса.

# Define/Create the model for training
model_InceptionV3 = models.Model(inputs=conv_base.input, outputs=output)
# Compile the model with categorical crossentropy for the loss function and SGD for the optimizer with the learning
# rate at 1e-4 and momentum at 0.9
model_InceptionV3.compile(loss='categorical_crossentropy',
              optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
              metrics=['accuracy'])

Проверьте список устройств для используемого графического процессора.

Теперь я рекомендую использовать графический процессор для обучения этой модели, поскольку модель InceptionV3 имеет более 21 миллиона параметров, а обучение на процессоре может занять несколько дней. Если у вас есть графический процессор, вы можете использовать свой собственный, но я использовал графические процессоры Kaggle, поставляемые с их ноутбуками, что заняло у меня около 20–25 минут на обучение. Найдите устройство с графическим процессором, которое можно использовать, чтобы ускорить процесс обучения.

# Import from tensorflow the module to read the GPU device and then print
from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())

Обучите модель.

Найдя используемый графический процессор, мы включим его в наш код, чтобы окончательно обучить модель с помощью train_generator для обучающих данных и параметра validation_data, установленного в test_generator.

# Execute the model with fit_generator within the while loop utilizing the discovered GPU
import tensorflow as tf
with tf.device("/device:GPU:0"):
    history = model_InceptionV3.fit_generator(
        train_generator,
        epochs=5,
        validation_data=test_generator,
        verbose = 1,
        callbacks=[EarlyStopping(monitor='val_accuracy', patience = 5, restore_best_weights = True)])

99% точности валидации с потерей 0,0187 более чем хорошо.

Отображение точности тестирования модели и значения потери тестирования

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

# Create a dictionary of the model history 
import matplotlib.pyplot as plt
history_dict = history.history
loss_values = history_dict['loss']
val_loss_values = history_dict['val_loss']
acc_values = history_dict['accuracy']
val_acc_values = history_dict['val_accuracy']
epochs = range(1, len(history_dict['accuracy']) + 1)
# Plot the training/validation loss
plt.plot(epochs, loss_values, 'bo', label = 'Training loss')
plt.plot(epochs, val_loss_values, 'b', label = 'Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
# Plot the training/validation accuracy
plt.plot(epochs, acc_values, 'bo', label = 'Training accuracy')
plt.plot(epochs, val_acc_values, 'b', label = 'Validation accuracy')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()

# Evaluate the test accuracy and test loss of the model
test_loss, test_acc = model_InceptionV3.evaluate_generator(test_generator)
print('Model testing accuracy/testing loss:', test_acc, " ", test_loss)

Анализ результатов

Результаты для точного прогнозирования 120 классов изображений фруктов и овощей показывают точность тестирования 99% при значении потерь 1,8%. Величина потерь - это мера того, насколько далеко наши результаты находятся и чего мы ожидали. Обучение проводилось через 5 эпох и занимало около 20–25 минут каждая, чтобы достичь такой точности с помощью графического процессора kaggle для ускорения процесса. Обучающие данные представляли собой процесс из 3781 шага (итераций), при котором размер пакета данных каждые 16 выборок передавался вперед и назад, чтобы дать нам один проход. Один проход равен одной итерации.

Вывод

В заключение, трансферное обучение - очень эффективный способ научить наборы данных распознавать и классифицировать изображения. Он обеспечивает быструю настройку, не вдаваясь в подробное проектирование архитектуры сверточной нейронной сети с нуля, и обеспечивает высокую точность при предыдущем обучении предварительно обученной модели. Вы можете зайти в записную книжку моего проекта Kaggle для чего-нибудь еще.

использованная литература

Адитья Анантрам. (2018, 17 октября). Глубокое обучение для начинающих с использованием трансферного обучения в Керасе. Получено 24 апреля 2020 г. с веб-сайта Medium: https://towardsdatascience.com/keras-transfer-learning-for-beginners-6c9b8b7143e.

Шейх Ф. (18 октября 2018 г.). Понимание начальной сети с нуля (с кодами Python). Получено 7 мая 2020 г. с веб-сайта Analytics Vidhya: https://www.analyticsvidhya.com/blog/2018/10/understanding-inception-network-from-scratch/

Шолле, Ф. (2018). Глубокое обучение с помощью Python. Остров Шелтер (Нью-Йорк, Estados Unidos): Manning, Cop.

Файл: Valid-padding-convolution.gif - Wikimedia Commons. (2018, 6 июля). Получено 6 мая 2020 г. с веб-сайта Wikimedia.org: https://commons.wikimedia.org/wiki/File:Valid-padding-convolution.gif

Получить бесплатные фотографии концепции интеллекта с человеческим мозгом на синем фоне онлайн | Загрузите последние бесплатные изображения и бесплатные иллюстрации. (2020). Получено 9 мая 2020 г. с веб-сайта Freerangestock.com: https://freerangestock.com/photos/65677/concept-of-intelligence-with-human-brain-on-blue-background.html

Получите бесплатные фотографии продавца фруктов и овощей в Италии онлайн | Загрузите последние бесплатные изображения и бесплатные иллюстрации. (2020). Получено 9 мая 2020 г. с веб-сайта Freerangestock.com: https://freerangestock.com/photos/37652/fruit-and-vegetables-vendor-italy.html

Https://github.com/syt123450, syt123450. (2020). Слой - GlobalPooling2d. Получено 6 мая 2020 г. с веб-сайта Tensorspace.org: https://tensorspace.org/html/docs/layerGlobalPooling2d.html

ImageNet. (2017). Получено 7 мая 2020 г. с веб-сайта Image-net.org: http://www.image-net.org/.

Крут Патель. (2019, 8 сентября). Сверточные нейронные сети - Руководство для начинающих - На пути к науке о данных. Получено 24 апреля 2020 г. с веб-сайта Medium: https://towardsdatascience.com/convolution-neural-networks-a-beginners-guide-implementing-a-mnist-hand-written-digit-8aa60330d022

Михай Олтеан. (2020). Fruits 360. Получено 6 мая 2020 г. с веб-сайта Kaggle.com: https://www.kaggle.com/moltean/fruits.

Милтон-Баркер, А. (17 февраля 2019 г.). Глубокая сверточная архитектура Inception V3 для классификации острого миелоидного / лимфобластного лейкоза. Получено 6 мая 2020 г. с веб-сайта Intel.com: https://software.intel.com/en-us/articles/inception-v3-deep-convolutional-architecture-for-classifying-acute-myeloidlymphoblastic

Пракхар Ганеш. (2019, 18 октября). Типы ядер свертки: упрощенное - к науке о данных. Получено 24 апреля 2020 г. с веб-сайта Medium: https://towardsdatascience.com/types-of-convolution-kernels-simplified-f040cb307c37.

Unsplash. (2020). Ясень от Modern Afflatus. Получено 9 мая 2020 г. с веб-сайта Unsplash.com: https://unsplash.com/@modernafflatusphotography

VisibleBreadcrumbs. (2016). Получено 27 апреля 2020 г. с веб-сайта Mathworks.com: https://www.mathworks.com/help/deeplearning/ref/inceptionv3.html

Авторы Википедии. (2020, 2 мая). Я, робот (фильм). Получено 5 мая 2020 г. с веб-сайта Википедии: https://en.wikipedia.org/wiki/I,_Robot_(film).