Понимание ‘scale_boxes’ в алгоритме YOLO сверточной нейронной сети (CNN)

Вопрос или проблема

Я изучаю свёрточные нейронные сети Эндрю Нг и нахожусь на третьей неделе курса, где рассматривается обнаружение объектов с использованием алгоритма YOLO. Я не понимаю один раздел в программном задании, который использует функцию под названием “scale_boxes”. Вот что описано о функции в материалах курса.

“*Существует несколько способов представления рамок, например, через их углы или через их середину и высоту/ширину. YOLO преобразует между несколькими такими форматами в разное время, используя следующие функции (которые мы предоставили):

boxes = yolo_boxes_to_corners(box_xy, box_wh)
которая преобразует координаты рамок yolo (x,y,w,h) в координаты углов рамок (x1, y1, x2, y2), чтобы соответствовать вводу yolo_filter_boxes

boxes = scale_boxes(boxes, image_shape)
Сеть YOLO была обучена работать с изображениями размером 608×608. Если вы тестируете эти данные на изображении другого размера, например, в наборе данных обнаружения автомобилей были изображения 720×1280, этот шаг масштабирует рамки так, чтобы они могли быть нанесены поверх оригинального изображения 720×1280.*”

И функция scale_boxes определяется следующим образом:

def scale_boxes(boxes, image_shape):
    """ Масштабирует предсказанные рамки, чтобы их можно было рисовать на изображении."""
    height = image_shape[0]
    width = image_shape[1]
    image_dims = K.stack([height, width, height, width])
    image_dims = K.reshape(image_dims, [1, 4])
    boxes = boxes * image_dims
    return boxes

Она используется в следующей функции ‘yolo_eval’:

def yolo_eval(yolo_outputs, image_shape = (720., 1280.), max_boxes=10, score_threshold=.6, iou_threshold=.5):
    """
    Преобразует выходные данные кодирования YOLO (множество рамок) в ваши предсказанные рамки вместе с их оценками, координатами рамок и классами.
    
    Аргументы:
    yolo_outputs -- выходные данные модели кодирования (для image_shape (608, 608, 3)), содержит 4 тензора:
                    box_confidence: тензор формы (None, 19, 19, 5, 1)
                    box_xy: тензор формы (None, 19, 19, 5, 2)
                    box_wh: тензор формы (None, 19, 19, 5, 2)
                    box_class_probs: тензор формы (None, 19, 19, 5, 80)
    image_shape -- тензор формы (2,) содержащий входную форму, в этой записной книжке мы используем (608., 608.) (должен быть типа float32)
    max_boxes -- целое число, максимальное количество предсказанных рамок, которые вы хотите
    score_threshold -- реальное значение, если [наивысшая вероятность класса < threshold], тогда избавляемся от соответствующей рамки
    iou_threshold -- реальное значение, порог "пересечения над объединением", используемый для фильтрации NMS
    
    Возвращает:
    scores -- тензор формы (None,), предсказанная оценка для каждой рамки
    boxes -- тензор формы (None, 4), предсказанные координаты рамок
    classes -- тензор формы (None,), предсказанный класс для каждой рамки
    """
    
    ### НАЧАЛО КОДА ### 
    
    # Получите выходные данные модели YOLO (≈1 строка)
    box_confidence, box_xy, box_wh, box_class_probs = yolo_outputs

    # Преобразуйте рамки для готовности для функций фильтрации (преобразуйте рамки box_xy и box_wh в угловые координаты)
    boxes = yolo_boxes_to_corners(box_xy, box_wh)

    # Используйте одну из функций, которую вы реализовали, чтобы выполнить фильтрацию по оценке с порогом оценки score_threshold (≈1 строка)
    scores, boxes, classes = yolo_filter_boxes(box_confidence,boxes,box_class_probs,score_threshold)

    # Масштабируйте рамки обратно к оригинальному размеру изображения.
    boxes = scale_boxes(boxes, image_shape)
   
    # Используйте одну из функций, которую вы реализовали, чтобы выполнить подавление неперекрывающейся максимальной рамки с 
    # максимальным количеством рамок, установленным max_boxes, и порогом iou_threshold (≈1 строка)
    scores, boxes, classes = yolo_non_max_suppression(scores,boxes,classes,max_boxes,iou_threshold)
    
    ### КОНЕЦ КОДА ###
    
    return scores, boxes, classes

Я не понимаю необходимость в функции 'scale_boxes'. Кажется, об этом нет никаких ответов/внимания в дискуссионных форумах, поэтому я задаю этот вопрос здесь.

Может ли кто-то подробно объяснить, что именно делает эта функция и почему она необходима?

Сеть YOLO была обучена работать с изображениями размером 608x608. Если вы тестируете эти данные на изображении другого размера--например, в наборе данных обнаружения автомобилей были изображения 720x1280--этот шаг масштабирует рамки так, чтобы они могли быть нанесены поверх оригинального изображения 720x1280.

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

Значения граничной рамки - это простые координаты на изображении. Они будут изменяться при изменении размера изображения. Представьте лицо на большом изображении и на крошечном изображении.

$\hspace{5cm}$enter image description here

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

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

Ответ или решение

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

Теория

Алгоритм YOLO (You Only Look Once) – это современный метод обнаружения объектов в изображении, который кроме высокой скорости обладает возможностью обнаруживать объекты сразу на все изображение, рассчётом ограничения (Bounding Boxes) и предсказанием класса объектов. Он был обучен на изображениях определенного размера, обычно 608x608 пикселей, а для выполнения предсказаний требуется обеспечить согласование предсказанных границ с различными размерами изображений, с которыми может сталкиваться алгоритм на практике.

Когда YOLO обрабатывает изображение, оно сначала масштабируется до размера 608x608, рассчитываются границы для этого размера, но при отображении на оригинальном изображении границы необходимо адаптировать под его реальные размеры. Без этого превращение на изображении нормализованных границ в результате предсказания будет не соответствовать реальным положению объектов, так как отражает границы сжатой версии изображения.

Пример

Предположим, пользователь предоставляет изображение размером 720x1280 для выполнения предсказания. YOLO изменит его размер до 608x608 перед применением модели. После получения границ вполне вероятно, что для верного отображения их придется снова масштабировать обратно к оригинальным размерам изображения – это где и применяется функция scale_boxes.

Функция scale_boxes явно масштабирует координаты боксов к оригинальной размерности изображения, чтобы их можно было корректно отобразить. Представьте, если на изображении обнаружена машина, которую система обвела границей (Bounding Box) с координатами для изображения 608x608, то без масштабирования эти границы не покажут машину правильным образом на изображении 720x1280.

Применение

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

Как выглядит реализация:

def scale_boxes(boxes, image_shape):
    """Scales the predicted boxes in order to be drawable on the image."""
    height = image_shape[0]
    width = image_shape[1]
    image_dims = K.stack([height, width, height, width])
    image_dims = K.reshape(image_dims, [1, 4])
    boxes = boxes * image_dims
    return boxes

В этой функции используется библиотека Keras для выполнения преобразований тензоров. На практике scale_boxes выполняет простое умножение координат границ на размерность изображения, преобразовывая шкалу с 608x608 к истинным размерам изображения.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...