Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шолле Ф. - Глубокое обучение на Python (Библиотека программиста) - 2023.pdf
Скачиваний:
6
Добавлен:
07.04.2024
Размер:
11.34 Mб
Скачать

302    Глава 8. Введение в глубокое обучение в технологиях зрения

Закончив.обучение,.оценим.модель.на.контрольных.данных:

model = keras.models.load_model("fine_tuning.keras") test_loss, test_acc = model.evaluate(test_dataset) print(f"Test accuracy: {test_acc:.3f}")

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

С.другой.стороны,.благодаря.современным.методам.глубокого.обучения.нам. удалось.достичь.такого.результата,.использовав.лишь.малую.часть.обучающих. данных.(около.10.%),.доступных.участникам.соревнования..Между.обучением. на.20.000.и.на.2000.образцов.огромная.разница!

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

КРАТКИЕ ИТОГИ ГЛАВЫ

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

.Сверточные.нейронные.сети.создают.иерархию.модульных.шаблонов.и.понятий.для.представления.видимого.мира.

.Когда.объем.данных.ограничен,.главной.проблемой.становится.переобучение..

Обогащение.данных.—.эффективное.средство.борьбы.с.переобучением.при. работе.с.изображениями.

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

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

Продвинутые9приемы глубокого обучения в технологиях

компьютерного зрения

В этой главе

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

33 Современные архитектуры сверточных нейронных сетей: остаточные связи, пакетная нормализация, раздельные свертки по глубине.

33 Методы визуализации и интерпретации знаний, заключенных в сверточной сети.

Ранее.вы.познакомились.с.основами.использования.глубокого.обучения.в.технологиях.компьютерного.зрения.на.примере.простых.моделей.(стеки.слоев. Conv2D .и.MaxPooling2D),.применяемых.для.решения.простой.задачи.(бинарная. классификация.изображений)..Но.компьютерное.зрение.—.это.не.только.клас- сификация.изображений!.В.этой.главе.будет.рассмотрен.более.широкий.круг. задач.и.представлены.некоторые.продвинутые.приемы.

9.1. ТРИ ОСНОВНЫЕ ЗАДАЧИ В СФЕРЕ КОМПЬЮТЕРНОГО ЗРЕНИЯ

До.сих.пор.наше.внимание.было.сосредоточено.на.моделях.классификации.изображений,.которые.принимают.изображение.и.возвращают.соответствующую.ему. метку..«Это.изображение,.вероятно,.содержит.кошку;.а.на.этом,.вероятно,.при- сутствует.собака»..Но.классификация.изображений.—.лишь.один.из.нескольких.

304    Глава 9. Введение в глубокое обучение в технологиях зрения

возможных.вариантов.применения.глубокого.обучения.в.компьютерном.зрении..

В.целом.в.данной.сфере.есть.три.основные.задачи.

.Классификация изображений..Цель.—.присвоить.изображению.одну.или.не- сколько.меток..Это.может.быть.однозначная.классификация.(изображение. можно.отнести.только.к.одной.категории).или.многозначная.(изображению. можно.присвоить.несколько.меток,.в.зависимости.от.наличия.на.нем.объектов. из.разных.категорий,.как.на.рис..9.1)..Например,.когда.вы.выполняете.поиск. по.ключевому.слову.в.приложении.Google.Photo,.ваш.запрос.обрабатывается. очень.большой.моделью.многозначной.классификации,.распознающей.более. 20.000.различных.классов.и.обученной.на.миллионах.изображений.

Рис. 9.1. Три основные задачи компьютерного зрения: классификация, сегментация и обнаружение объектов

.Сегментация изображений..Цель.—.сегментировать,.или.разбить,.изобра- жение.на.непересекающиеся.области,.каждая.из.которых.представляет.некоторую.категорию.(как.на.рис..9.1)..Например,.когда.в.Zoom.или.Google. Meet.вам.нужно.установить.отображение.какого-то.фона.за.собой.во.время. видеозвонка,.для.реализации.этой.опции.программа.использует.модель.сег-

9.2. Пример сегментации изображения    305

ментации.изображения,.отличающую.ваше.лицо.от.фона.за.ним.с.точностью. до.пикселя.

.Обнаружение объектов..Цель.—.нарисовать.прямоугольники.(которые.на- зывают.ограничивающими рамками).вокруг.интересующих.объектов.на.изображении.и.связать.каждый.прямоугольник.с.некоторым.классом..Автопилот. автомобиля,.например,.может.использовать.модель.обнаружения.объектов. для.наблюдения.за.автомобилями,.пешеходами.и.знаками,.попадающими. в.поле.зрения.своих.камер.

9.2. ПРИМЕР СЕГМЕНТАЦИИ ИЗОБРАЖЕНИЯ

Чтобы.сегментировать.изображение,.в.глубоком.обучении.используется.модель. для.назначения.класса.каждому.пикселю.изображения.—.таким.образом.изобра- жение.сегментируется.на.разные.зоны.(например.«фон».и.«передний.план».или. «дорога»,.«автомобиль».и.«тротуар»)..Данная.категория.методов.может.найти. применение.в.инструментах.редактирования.изображений.и.видео,.автоматическом.управлении.транспортными.средствами,.робототехнике,.медицине.и.т..д.

Есть.два.разных.варианта.сегментации.изображений.(рис..9.2).

.Семантическая сегментация.—.когда.каждый.пиксель.независимо.друг.от. друга.относится.к.некоторой.семантической.категории.(скажем,.«кошка»)..

В.этом.случае,.если.на.изображении.есть.две.кошки,.все.соответствующие. пиксели .будут .включены .в .одну .и .ту .же .общую .категорию .— .«кошка». (рис..9.2).

.Сегментация экземпляров.—.направлена.не.только.на.классификацию.пиксе- лей.изображения.по.категориям,.но.и.на.выделение.отдельных.экземпляров. объекта..Поэтому.на.изображении.с.двумя.кошками.экземпляры.«кошка.1». и.«кошка.2».будут.распознаны.как.две.отдельные.группы.пикселей.

Рис. 9.2. Семантическая сегментация и сегментация экземпляров

306    Глава 9. Введение в глубокое обучение в технологиях зрения

Сосредоточимся.на.семантической.сегментации:.в.примере.ниже.мы.еще.раз. исследуем.изображения.кошек.и.собак,.но.на.этот.раз.постараемся.научиться. различать.основной.предмет.и.его.фон.

Для.работы.нам.понадобится.набор.данных.Oxford-IIIT.Pets.(www.robots.ox.ac.uk/ ~vgg/data/pets/),.содержащий.7390.изображений.различных.пород.кошек.и.собак. вместе.с.соответствующими.масками.сегментации..Маска сегментации.—.это. эквивалент.метки.в.задаче.сегментации.изображения;.изображение.того.же. размера,.что.и.входное.изображение,.с.одним.цветовым.каналом,.в.котором. каждое.целочисленное.значение.обозначает.класс.соответствующего.пикселя. на.входном.изображении..В.нашем.случае.пиксели.масок.сегментации.могут. принимать.одно.из.трех.целочисленных.значений:

. 1.(передний.план);

. 2.(фон);

. 3.(контур).

Для.начала.загрузим.и.распакуем.набор.данных,.использовав.утилиты.wget.и.tar:

!wget http://www.robots.ox.ac.uk/~vgg/data/pets/data/images.tar.gz !wget http://www.robots.ox.ac.uk/~vgg/data/pets/data/annotations.tar.gz !tar -xf images.tar.gz

!tar -xf annotations.tar.gz

Входные.изображения.сохраняются.в.виде.файлов.JPG.в.папке.images/ .(на- пример,.images/Abyssinian_1.jpg),.а.соответствующие.маски.сегментации.—.в.виде. файлов.PNG.с.теми.же.именами.в.папке.annotations/trimaps/ .(например,.annotations/ trimaps/Abyssinian_1.png).

Подготовим.список.путей.к.входным.файлам.и.файлам.масок:

import os

input_dir = "images/"

target_dir = "annotations/trimaps/"

input_img_paths = sorted( [os.path.join(input_dir, fname)

for fname in os.listdir(input_dir) if fname.endswith(".jpg")])

target_paths = sorted( [os.path.join(target_dir, fname)

for fname in os.listdir(target_dir)

if fname.endswith(".png") and not fname.startswith(".")])

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

Выведем.на.экран.изображение.(рис..9.3):

9.2. Пример сегментации изображения    307

import matplotlib.pyplot as

plt

 

from tensorflow.keras.utils

import load_img, img_to_array

plt.axis("off")

 

 

Вывести девятое

 

 

plt.imshow(load_img(input_img_paths[9]))

 

входное изображение

 

 

Рис. 9.3. Пример изображения

и.его.маску.(рис..9.4):

Рис. 9.4. Соответствующая целевая маска

308    Глава 9. Введение в глубокое обучение в технологиях зрения

В исходном наборе данных метки имеют значения 1, 2 и 3. Мы вычитаем 1, чтобы привести метки в диапазон от 0 до 2, а затем умножаем на 127, чтобы получить метки 0 (черный цвет), 127 (серый), 254 (почти белый)

def display_target(target_array):

normalized_array = (target_array.astype("uint8") - 1) * 127 plt.axis("off")

plt.imshow(normalized_array[:, :, 0])

img = img_to_array(load_img(target_paths[9], color_mode="grayscale")) display_target(img)

Аргумент color_mode="grayscale" обеспечивает обработку загружаемого изображения как имеющего единственный цветовой канал

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

import

numpy as np

 

Все изображения будут

Общее

 

import

random

 

масштабироваться

 

 

 

 

до размеров 200 × 200

количество

img_size = (200, 200)

 

 

 

образцов

 

 

 

num_imgs = len(input_img_paths)

 

 

 

Перемешивание файлов (изначально

 

 

 

random.Random(1337).shuffle(input_img_paths)

 

 

они были отсортированы по породам).

 

 

В обеих инструкциях используется

random.Random(1337).shuffle(target_paths)

 

 

одно и то же начальное число (1337),

 

 

 

 

чтобы гарантировать единый порядок

def path_to_input_image(path):

 

 

входных и целевых файлов

 

 

 

return img_to_array(load_img(path, target_size=img_size))

def path_to_target(path): img = img_to_array(

load_img(path, target_size=img_size, color_mode="grayscale"))

img = img.astype("uint8") - 1

 

Вычитается 1, чтобы преобразовать

 

return img

метки в 0, 1 и 2

 

 

input_imgs = np.zeros((num_imgs,) + img_size + (3,), dtype="float32") targets = np.zeros((num_imgs,) + img_size + (1,), dtype="uint8")

for i in range(num_imgs):

input_imgs[i] = path_to_input_image(input_img_paths[i]) targets[i] = path_to_target(target_paths[i])

num_val_samples = 1000 train_input_imgs = input_imgs[:-num_val_samples] train_targets = targets[:-num_val_samples] val_input_imgs = input_imgs[-num_val_samples:] val_targets = targets[-num_val_samples:]

Разделение данных на обучающий

Резервирование 1000 образцов

и проверочный наборы

для проверочного набора

Загрузка всех изображений в массив input_imgs типа float32 и масок в массив targets типа uint8 (в одном и том же порядке). Входные изображения имеют три канала (значения

RBG), а цели — один канал

(с целочисленными метками)

Не забывайте изменять масштаб входных значений до диапазона [0–1]

9.2. Пример сегментации изображения    309

Теперь.определим.модель:

from tensorflow import keras

from tensorflow.keras import layers

def get_model(img_size, num_classes):

inputs = keras.Input(shape=img_size + (3,)) x = layers.Rescaling(1./255)(inputs)

Обратите внимание, что мы везде используем padding="same", чтобы избежать влияния отступов

от границ на размер

карты объектов

x =

layers.Conv2D(64, 3, strides=2, activation="relu", padding="same")(x)

x =

layers.Conv2D(64, 3, activation="relu", padding="same")(x)

x =

layers.Conv2D(128, 3, strides=2, activation="relu", padding="same")(x)

x =

layers.Conv2D(128, 3, activation="relu", padding="same")(x)

x =

layers.Conv2D(256, 3, strides=2, padding="same", activation="relu")(x)

x =

layers.Conv2D(256, 3, activation="relu", padding="same")(x)

x =

layers.Conv2DTranspose(256, 3, activation="relu", padding="same")(x)

x =

layers.Conv2DTranspose(

 

 

 

 

256, 3, activation="relu", padding="same", strides=2)(x)

x =

layers.Conv2DTranspose(128, 3, activation="relu", padding="same")(x)

x =

layers.Conv2DTranspose(

 

 

 

 

128, 3, activation="relu", padding="same", strides=2)(x)

x =

layers.Conv2DTranspose(64, 3, activation="relu", padding="same")(x)

x =

layers.Conv2DTranspose(

 

 

 

 

64, 3, activation="relu", padding="same", strides=2)(x)

outputs = layers.Conv2D(num_classes, 3, activation="softmax",

 

 

 

 

padding="same")(x)

 

 

 

 

Модель завершается классификатором

model = keras.Model(inputs, outputs)

пикселей с активацией softmax,

return model

который относит каждый выходной

 

 

пиксель к одной из трех категорий

model =

get_model(img_size=img_size, num_classes=3)

 

 

 

model.summary()

 

 

 

Вот.вывод.метода.model.summary():

Model: "model"

_________________________________________________________________

Layer (type) Output Shape Param #

=================================================================

input_1 (InputLayer) [(None, 200, 200, 3)] 0

_________________________________________________________________

rescaling (Rescaling) (None, 200, 200, 3) 0

_________________________________________________________________

conv2d (Conv2D) (None, 100, 100, 64) 1792

_________________________________________________________________

conv2d_1 (Conv2D) (None, 100, 100, 64) 36928

_________________________________________________________________

conv2d_2 (Conv2D) (None, 50, 50, 128) 73856

_________________________________________________________________

conv2d_3 (Conv2D) (None, 50, 50, 128) 147584

_________________________________________________________________

310    Глава 9. Введение в глубокое обучение в технологиях зрения

conv2d_4 (Conv2D) (None, 25, 25, 256) 295168

_________________________________________________________________

conv2d_5 (Conv2D) (None, 25, 25, 256) 590080

_________________________________________________________________

conv2d_transpose (Conv2DTran (None, 25, 25, 256) 590080

_________________________________________________________________

conv2d_transpose_1 (Conv2DTr (None, 50, 50, 256) 590080

_________________________________________________________________

conv2d_transpose_2 (Conv2DTr (None, 50, 50, 128) 295040

_________________________________________________________________

conv2d_transpose_3 (Conv2DTr (None, 100, 100, 128) 147584

_________________________________________________________________

conv2d_transpose_4 (Conv2DTr (None, 100, 100, 64) 73792

_________________________________________________________________

conv2d_transpose_5 (Conv2DTr (None, 200, 200, 64) 36928

_________________________________________________________________

conv2d_6 (Conv2D) (None, 200, 200, 3) 1731

=================================================================

Total params: 2,880,643 Trainable params: 2,880,643 Non-trainable params: 0

_________________________________________________________________

Первая .половина .модели .очень .похожа .на .типичную .сверточную .сеть, .используемую.для.классификации.изображений:.стек.слоев.Conv2D .с.постепенно. увеличивающимися.размерами.фильтров..Мы.трижды.повторяем.уменьшение. наполовину.разрешения.наших.изображений,.что.дает.активацию.с.размерами. (25, 25, 256)..Цель.этой.первой.половины.—.закодировать.изображения.в.карты. признаков.меньшего.размера,.где.каждое.пространственное.местоположение. (или .пиксель).содержит.информацию .о .большем .пространственном.фрагменте.исходного.изображения..Конечный.эффект.можно.интерпретировать. как.сжатие.

Одно.из.важных.различий.между.первой.половиной.этой.модели.и.моделями. классификации,.которые.были.показаны.ранее.в.этой.книге,.заключается.в.способе.уменьшения.разрешения..В.сверточных.сетях.в.предыдущей.главе.для.уменьшения.разрешения.карт.признаков.мы.использовали.слои.MaxPooling2D..Здесь. мы.увеличили.шаг свертки.во.всех.остальных.сверточных.слоях.(если.вы.забыли,. какой.эффект.оказывает.изменение.шага.свертки,.вернитесь.к.подразделу.«Шаг. свертки».в.пункте.8.1.1)..В.случае.сегментации.изображения.важно.позаботиться. о.пространственной привязке.информации.на.изображении,.так.как.на.выходе. модели.должны.создаваться.попиксельные.целевые.маски..Поэтому.мы.выбрали. данное.решение..Применение.метода.на.основе.выбора.максимального.значения. из.соседних.в.окне.2.×.2.полностью.уничтожит.информацию.о.местоположении. в.каждом.таком.окне:.вы.получите.одно.скалярное.значение.для.каждого.окна,. не.имея.представления,.из.которого.из.четырех.местоположений.в.окне.оно. было.получено..То.есть,.несмотря.на.то.что.данный.метод.хорошо.подходит.для. задач.классификации,.в.задаче.сегментации.он.нам.только.навредит..Между.тем.

9.2. Пример сегментации изображения    311

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

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

Вторая.половина.модели.организована.как.стек.слоев.Conv2DTranspose..Что.это. за.слои?.Дело.в.том,.что.результатом.первой.половины.модели.является.карта. признаков.с.формой.(25, 25, 256),.а.нам.нужно.получить.на.выходе.результат. той.же.формы,.что.и.целевые.маски.(200, 200, 3)..То.есть.к.выходным.данным. первой.половины.модели.нужно.применить.преобразования,.увеличивающие. разрешение.карт.признаков..Именно.такое.преобразование.реализует.слой. Conv2DTranspose:.его.можно.рассматривать.как.сверточный.слой,.который.учится увеличивать разрешение..Если.исходные.данные.с.формой.(100, 100, 64) .пропустить.через.слой.Conv2D(128, 3, strides=2, padding="same"),.то.на.выходе. получится.результат.формы.(50, 50, 128)..Если.этот.вывод.пропустить.через. слой.Conv2DTranspose(64, 3, strides=2, padding="same"),.получим.результат. с.формой.(100, 100, 64),.как.и.у.оригинала..То.есть.после.сжатия.входных.данных. в.карты.признаков.с.формой.(25, 25, 256).с.помощью.стека.слоев.Conv2D.можно. просто.применить.соответствующую.последовательность.слоев.Conv2DTranspose,. чтобы.получить.изображения.с.формой.(200, 200, 3).

Теперь.скомпилируем.и.обучим.модель:

model.compile(optimizer="rmsprop", loss="sparse_categorical_crossentropy")

callbacks = [ keras.callbacks.ModelCheckpoint("oxford_segmentation.keras",

save_best_only=True)

]

history = model.fit(train_input_imgs, train_targets, epochs=50,

callbacks=callbacks, batch_size=64,

validation_data=(val_input_imgs, val_targets))

и.построим.графики.изменения.потерь.на.этапах.обучения.и.проверки.(рис..9.5):

epochs = range(1, len(history.history["loss"]) + 1) loss = history.history["loss"]

val_loss = history.history["val_loss"] plt.figure()

plt.plot(epochs, loss, "bo", label="Потери на этапе обучения") plt.plot(epochs, val_loss, "b", label="Потери на этапе проверки") plt.title("Потери на этапах обучения и проверки")

plt.legend()

312    Глава 9. Введение в глубокое обучение в технологиях зрения

Рис. 9.5. Графики изменения потерь на этапах обучения и проверки

Как.видите,.на.полпути.(где-то.в.районе.25-й.эпохи).начал.проявляться.эффект. переобучения..Загрузим.модель,.показавшую.наименьшие.потери.на.проверочных.данных,.и.посмотрим,.как.ее.использовать.для.прогнозирования.маски. сегментации.(рис..9.6):

from tensorflow.keras.utils import array_to_img

model = keras.models.load_model("oxford_segmentation.keras")

i = 4

test_image = val_input_imgs[i] plt.axis("off") plt.imshow(array_to_img(test_image))

mask = model.predict(np.expand_dims(test_image, 0))[0]

def display_mask(pred): mask = np.argmax(pred, axis=-1) mask *= 127

plt.axis("off")

plt.imshow(mask) display_mask(mask)

Утилита для вывода прогноза модели

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