13.5 Обнаружение объектов в нескольких масштабах
В разделе 13.4 мы создавали несколько якорных рамок с центром в каждом пикселе входного изображения. По сути, эти рамки представляют выборку разных областей изображения. Однако если создавать якорные рамки для каждого пикселя, то в итоге получится слишком много рамок для вычислений. Представим входное изображение размером . Если с центром в каждом пикселе создать пять рамок разной формы, нужно будет разметить и предсказать более 2 миллионов якорных рамок ().
13.5.1 Многомасштабные якорные рамки
Уменьшить число якорных рамок несложно. Например, можно равномерно выбрать небольшую долю пикселей входного изображения и создавать рамки с центрами в них. Кроме того, для разных масштабов можно создавать разное количество рамок разного размера. Интуитивно понятно, что маленькие объекты встречаются на изображении в большем разнообразии положений, чем большие. Например, объекты размером , и могут появиться на изображении четырьмя, двумя и одним способом соответственно. Поэтому при обнаружении мелких объектов с помощью мелких рамок можно выбирать больше областей, а для крупных объектов — меньше.
Чтобы показать, как генерировать якорные рамки в нескольких масштабах, сначала загрузим изображение. Его высота и ширина равны 561 и 728 пикселям.
MXNet:
%matplotlib inline
from d2l import mxnet as d2l
from mxnet import image, np, npx
npx.set_np()
img = image.imread('../img/catdog.jpg')
h, w = img.shape[:2]
h, w
PyTorch:
%matplotlib inline
from d2l import torch as d2l
import torch
img = d2l.plt.imread('../img/catdog.jpg')
h, w = img.shape[:2]
h, w
PaddlePaddle:
%matplotlib inline
from d2l import paddle as d2l
import warnings
warnings.filterwarnings("ignore")
import paddle
img = d2l.plt.imread('../img/catdog.jpg')
h, w = img.shape[:2]
h, w
Напомним, что в разделе 6.2 мы называли двумерный выход свёрточного слоя картой признаков (feature map). Задав форму карты признаков, мы можем определить центры якорных рамок, равномерно распределённые по любому изображению.
Функция display_anchors определена ниже. Мы создаём якорные рамки (anchors) на карте признаков (fmap), используя каждую ячейку (пиксель) как центр якорной рамки. Поскольку значения координат в якорных рамках (anchors) уже поделены на ширину и высоту карты признаков (fmap), эти значения лежат между 0 и 1 и задают относительное положение якорной рамки на карте признаков.
Так как центры якорных рамок (anchors) распределены по всем ячейкам карты признаков (fmap), эти центры должны быть равномерно распределены по любому входному изображению в соответствии с их относительным пространственным положением. Более конкретно, при заданных ширине и высоте карты признаков fmap_w и fmap_h следующая функция равномерно выбирает пиксели в fmap_h строках и fmap_w столбцах любого входного изображения. С центрами в этих равномерно выбранных пикселях будут созданы якорные рамки размера s (предполагается, что список s содержит один элемент) с разными соотношениями сторон (ratios).
MXNet:
def display_anchors(fmap_w, fmap_h, s):
d2l.set_figsize()
# Значения первых двух измерений не влияют на результат
fmap = np.zeros((1, 10, fmap_h, fmap_w))
anchors = npx.multibox_prior(fmap, sizes=s, ratios=[1, 2, 0.5])
bbox_scale = np.array((w, h, w, h))
d2l.show_bboxes(d2l.plt.imshow(img.asnumpy()).axes,
anchors[0] * bbox_scale)
PyTorch:
def display_anchors(fmap_w, fmap_h, s):
d2l.set_figsize()
# Значения первых двух измерений не влияют на результат
fmap = d2l.zeros((1, 10, fmap_h, fmap_w))
anchors = d2l.multibox_prior(fmap, sizes=s, ratios=[1, 2, 0.5])
bbox_scale = d2l.tensor((w, h, w, h))
d2l.show_bboxes(d2l.plt.imshow(img).axes,
anchors[0] * bbox_scale)
PaddlePaddle:
def display_anchors(fmap_w, fmap_h, s):
d2l.set_figsize()
# Значения первых двух измерений не влияют на результат
fmap = paddle.zeros(shape=[1, 10, fmap_h, fmap_w])
anchors = d2l.multibox_prior(fmap, sizes=s, ratios=[1, 2, 0.5])
bbox_scale = paddle.to_tensor((w, h, w, h))
d2l.show_bboxes(d2l.plt.imshow(img).axes,
anchors[0] * bbox_scale)
Сначала рассмотрим обнаружение мелких объектов. Чтобы рамки было легче различить на рисунке, рамки с разными центрами здесь не перекрываются: масштаб якорных рамок равен 0.15, высота и ширина карты признаков равны 4. Видно, что центры якорных рамок на 4 строках и 4 столбцах изображения распределены равномерно.
display_anchors(fmap_w=4, fmap_h=4, s=[0.15])
Далее уменьшим высоту и ширину карты признаков вдвое и используем якорные рамки большего размера для обнаружения крупных объектов. При масштабе 0.4 некоторые якорные рамки будут перекрывать друг друга.
display_anchors(fmap_w=2, fmap_h=2, s=[0.4])
Наконец, ещё раз уменьшим высоту и ширину карты признаков вдвое и увеличим масштаб якорных рамок до 0.8. Теперь центр якорной рамки совпадает с центром изображения.
display_anchors(fmap_w=1, fmap_h=1, s=[0.8])
13.5.2 Обнаружение в нескольких масштабах
Теперь, когда мы создали якорные рамки в нескольких масштабах, мы используем их для обнаружения объектов разных размеров в разных масштабах. Ниже мы опишем метод обнаружения на основе свёрточной нейронной сети, который реализуем в разделе 13.7.
На одном масштабе пусть у нас есть карт признаков формы . По методу из раздела 13.5.1 мы создаём групп якорных рамок, и в каждой группе рамок с одинаковым центром. Например, на первом масштабе описанного выше эксперимента при 10 (число каналов) картах признаков размером мы получаем 16 групп якорных рамок, в каждой из которых 3 рамки с одинаковым центром. Затем каждая якорная рамка размечается классом и смещением относительно истинной ограничивающей рамки. На текущем масштабе модель обнаружения должна предсказать классы и смещения для групп якорных рамок входного изображения, где у разных групп разные центры.
Предположим, что карт признаков здесь — промежуточный результат, который свёрточная сеть выдаёт при прямом распространении для входного изображения. Поскольку на каждой карте признаков есть разных пространственных положений, одно и то же пространственное положение можно рассматривать как элементов. По определению рецептивного поля из раздела 6.2 элементов карт признаков в одном и том же пространственном положении имеют одинаковое рецептивное поле на входном изображении: они описывают одну и ту же информацию входного изображения в пределах этого рецептивного поля. Поэтому мы можем преобразовать элементов карт признаков в одном и том же пространственном положении в классы и смещения для якорных рамок, построенных с центром в этом положении. По сути, мы используем информацию входного изображения в области определённого рецептивного поля, чтобы предсказать классы и смещения якорных рамок, расположенных вблизи этой области.
Когда карты признаков разных слоёв имеют на входном изображении рецептивные поля разного размера, их можно использовать для обнаружения объектов разного размера. Например, можно спроектировать нейронную сеть так, чтобы элементы карт признаков ближе к выходному слою имели более широкие рецептивные поля; тогда они смогут обнаруживать на входном изображении более крупные объекты.
Короче говоря, мы можем использовать глубокую нейронную сеть, которая строит иерархическое представление изображения на нескольких уровнях, и так реализовать обнаружение объектов в нескольких масштабах. В разделе 13.7 мы разберём конкретный пример, который показывает, как это работает.
Резюме
- В нескольких масштабах мы можем создавать якорные рамки разных размеров для обнаружения объектов разных размеров.
- Задав форму карт признаков, мы можем определить центры равномерно распределённых на любом изображении якорных рамок.
- Мы используем информацию входного изображения в области определённого рецептивного поля, чтобы предсказать классы и смещения якорных рамок, расположенных вблизи этой области.
- Глубокое обучение позволяет использовать иерархическое представление изображения на нескольких уровнях для обнаружения объектов в нескольких масштабах.
Упражнения
- Согласно нашему обсуждению в разделе 7.1, глубокие нейронные сети постепенно строят иерархию абстракций признаков изображения по мере увеличения глубины сети. Соответствуют ли карты признаков разных масштабов в обнаружении объектов в нескольких масштабах разным уровням абстракции? Почему?
- В эксперименте из раздела 13.5.1 на первом масштабе (
fmap_w=4, fmap_h=4) создайте равномерно распределённые якорные рамки, которые могут перекрываться. - Дана переменная карты признаков формы , где , и — число каналов, высота и ширина карты признаков. Как преобразовать эту переменную в классы и смещения якорных рамок? Какова форма результата?
MXNet: Обсуждение
PyTorch: Обсуждение
PaddlePaddle: Обсуждение