Введение

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

Обнаружение объектов: фундаментальная задача

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

Представляем RetinaNet

RetinaNet, представленная Цунг-И Линь, Прией Гоял, Россом Гиршиком, Каймингом Хе и Петром Долларом в статье «Фокальная потеря для обнаружения плотных объектов», предлагает новое решение недостатков предыдущих моделей обнаружения объектов. Основное новшество RetinaNet заключается в потере фокуса, которая решает проблему дисбаланса классов, присутствующую в большинстве наборов данных для обнаружения объектов.

Фокальная потеря: смягчение классового дисбаланса

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

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

Архитектура функциональной пирамидальной сети (FPN)

Архитектура RetinaNet основана на сети Feature Pyramid Network (FPN), которая позволяет модели эффективно обнаруживать объекты различных размеров. FPN создает многомасштабную пирамиду объектов, используя карты объектов как с низким, так и с высоким разрешением. Эта пирамидальная структура облегчает обнаружение объектов в различных масштабах, расширяя возможности модели одновременно обрабатывать маленькие и большие объекты.

Якорные коробки и регрессия

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

Преимущества и приложения

Конструкция RetinaNet и механизм потери фокуса предлагают несколько преимуществ:

  1. Точное обнаружение. При потере фокуса приоритет отдается примерам, которые трудно классифицировать, что приводит к повышению точности, особенно для небольших или сложных объектов.
  2. Эффективность. Уменьшая влияние фоновых примеров, RetinaNet ускоряет сходимость во время обучения.
  3. Инвариантность к масштабу. Архитектура FPN и поля привязки позволяют модели обнаруживать объекты разных размеров, не требуя отдельных моделей или значительных модификаций.
  4. Реальные приложения: RetinaNet находит применение в различных областях, таких как автономное вождение, наблюдение, медицинская визуализация и промышленная автоматизация, где надежное и эффективное обнаружение объектов имеет решающее значение.

Код

Вот упрощенная реализация модели обнаружения объектов RetinaNet на Python с использованием библиотеки PyTorch. Обратите внимание, что этот код представляет собой общий обзор и может потребовать корректировок в зависимости от вашего конкретного набора данных и требований.

import torch
import torch.nn as nn
import torchvision.models as models

class FocalLoss(nn.Module):
    def __init__(self, alpha=0.25, gamma=2):
        super(FocalLoss, self).__init__()
        self.alpha = alpha
        self.gamma = gamma

    def forward(self, pred, target):
        ce_loss = nn.CrossEntropyLoss()(pred, target)
        pt = torch.exp(-ce_loss)
        focal_loss = self.alpha * (1 - pt) ** self.gamma * ce_loss
        return focal_loss

class RetinaNet(nn.Module):
    def __init__(self, num_classes, backbone='resnet50'):
        super(RetinaNet, self).__init__()

        # Load the backbone network (ResNet-50 in this case)
        self.backbone = models.resnet50(pretrained=True)
        # Remove the last classification layer
        self.backbone = nn.Sequential(*list(self.backbone.children())[:-2])

        # Create Feature Pyramid Network (FPN) layers
        self.fpn = ...

        # Create classification and regression heads for each FPN level
        self.cls_heads = ...
        self.reg_heads = ...

    def forward(self, x):
        # Forward pass through the backbone
        C3, C4, C5 = self.backbone(x)

        # Forward pass through FPN
        features = self.fpn([C3, C4, C5])

        # Generate class and regression predictions
        cls_predictions = [cls_head(feature) for cls_head, feature in zip(self.cls_heads, features)]
        reg_predictions = [reg_head(feature) for reg_head, feature in zip(self.reg_heads, features)]

        return cls_predictions, reg_predictions

# Example usage
num_classes = 80  # Adjust based on your dataset
model = RetinaNet(num_classes)

# Define loss functions
cls_criterion = FocalLoss()
reg_criterion = nn.SmoothL1Loss()

# Define optimizer
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# Training loop
for epoch in range(num_epochs):
    for images, targets in dataloader:  # Your data loading mechanism
        optimizer.zero_grad()
        cls_preds, reg_preds = model(images)

        cls_loss = cls_criterion(cls_preds, targets['class_labels'])
        reg_loss = reg_criterion(reg_preds, targets['bounding_boxes'])

        total_loss = cls_loss + reg_loss
        total_loss.backward()
        optimizer.step()

        print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {total_loss.item():.4f}')

Обратите внимание, что этот код является базовым примером и не включает в себя все детали, необходимые для полнофункциональной реализации RetinaNet. Вам потребуется реализовать слои FPN, генерацию поля привязки, постобработку для вывода, загрузку данных и другие компоненты в зависимости от ваших конкретных потребностей и структуры вашего набора данных. Кроме того, в приведенном примере используется магистральная сеть ResNet-50; вы также можете изучить другие магистрали для повышения производительности.

Вот пример того, как вы можете использовать обученную модель RetinaNet для обнаружения объектов с использованием набора данных COCO и библиотеки torchvision:

import torch
from torchvision.models.detection import retinanet_resnet50_fpn
from torchvision.transforms import functional as F
from PIL import Image

# Load a pre-trained RetinaNet model
model = retinanet_resnet50_fpn(pretrained=True)
model.eval()

# Load an example image
image_path = 'path/to/your/image.jpg'
image = Image.open(image_path)

# Apply transformations to the image
image_tensor = F.to_tensor(image)
image_tensor = F.normalize(image_tensor, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])

# Perform inference
with torch.no_grad():
    predictions = model([image_tensor])

# Use torchvision to visualize detections
import torchvision.transforms as T
from torchvision.ops import boxes as box_ops

v_image = image.copy()
v_image = T.ToTensor()(v_image)
v_image = T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])(v_image)

results = predictions[0]
scores = results['scores']
boxes = results['boxes']
labels = results['labels']

# Keep only predictions with score > 0.5
keep = scores > 0.5
scores = scores[keep]
boxes = boxes[keep]
labels = labels[keep]

# Visualize the detections
v_image = v_image.squeeze().permute(1, 2, 0)
v_image = v_image.cpu().numpy()
draw = Image.fromarray((v_image * 255).astype('uint8'))

draw_boxes = box_ops.box_convert(boxes, 'xyxy', 'xywh')
draw_boxes[:, 2:] *= 0.5  # Scale the boxes

draw_boxes = draw_boxes.cpu().numpy()
for box, label, score in zip(draw_boxes, labels, scores):
    color = tuple(map(int, (255, 0, 0)))
    ImageDraw.Draw(draw).rectangle(box, outline=color, width=3)
    ImageDraw.Draw(draw).text((box[0], box[1]), f"Class: {label}, Score: {score:.2f}", fill=color)

# Display the image with bounding boxes
draw. Show()

В этом примере мы используем функцию retinanet_resnet50_fpn из torchvision для загрузки предварительно обученной модели RetinaNet с магистральной сетью ResNet-50 и архитектурой FPN. Затем мы предварительно обрабатываем пример изображения с помощью преобразования, выполняем прямой проход через модель и используем RetinaNetPostProcessor для получения результатов обнаружения. Результаты обнаружения включают метки классов, оценки и координаты ограничивающего прямоугольника для каждого обнаруженного объекта.

Обязательно замените 'path/to/your/image.jpg' фактическим путем к изображению, которое вы хотите протестировать. Кроме того, вам может потребоваться установить необходимые пакеты, если вы еще этого не сделали:

pip install torch torchvision pillow

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

Заключение

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