Computer Vision Object Detection

In this blog, we will implement an object detection task in computer vision from scratch. We will use Python and the PyTorch framework and use a simple Convolutional Neural Network (CNN) model for object detection. I

## 1. Preparations

First, make sure the following libraries are installed:

- Python 3.6 or later
- PyTorch 1.0 or later
- torchvision
- NumPy
- OpenCV

You can install these libraries with the following commands:

pip install torch torchvision numpy opencv-python

## 2. Dataset

We will use the [PASCAL VOC](http://host.robots.ox.ac.uk/pascal/VOC/) dataset. This is a commonly used computer vision dataset containing 20 categories of objects. You can download the dataset from [here](http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar).

After downloading and decompressing the dataset, we will use the `VOCDetection` class in torchvision to load the dataset:

from torchvision.datasets import VOCDetection

voc_root = "/path/to/VOCdevkit/VOC2012"  # 请将此路径替换为实际的数据集路径
voc_data = VOCDetection(voc_root, year="2012", image_set="train", download=False)

## 3. Preprocessing data

We need to do some preprocessing on the data to fit our model. First, we resize the image to a fixed size (e.g. 224x224 pixels) and convert the image and annotation data into PyTorch tensors:

import torch
import torchvision.transforms as transforms

# 图像预处理
image_transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
])

# 标注数据预处理
def voc_collate_fn(batch):
    images, targets = zip(*batch)
    images = torch.stack([image_transform(image) for image in images])
    return images, targets

Next, we'll use PyTorch's `DataLoader` class to load the data:

from torch.utils.data import DataLoader

batch_size = 4
data_loader = DataLoader(voc_data, batch_size=batch_size, shuffle=True, collate_fn=voc_collate_fn)

## 4. Build the model

We will build a simple Convolutional Neural Network (CNN) for object detection. Here we use a simplified version of the [Faster R-CNN](https://arxiv.org/abs/1506.01497) model as an example. To simplify the problem, we only classify images without bounding box regression.

import torch.nn as nn

class SimpleFasterRCNN(nn.Module):
    def __init__(self, num_classes):
        super(SimpleFasterRCNN, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1)
        self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.conv2 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1)
        self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.fc1 = nn.Linear(128 * 56 * 56, 4096)
        self.fc2 = nn.Linear(4096, num_classes)

    def forward(self, x):
        x = self.pool1(F.relu(self.conv1(x)))
        x = self.pool2(F.relu(self.conv2(x)))
        x = x.view(x.size(0), -1)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

num_classes = 21  # 包括背景类
model = SimpleFasterRCNN(num_classes)

## 5. Training the model

We will train our model using a Stochastic Gradient Descent (SGD) optimizer and a cross-entropy loss function. Let's set some training parameters and start training:

import torch.optim as optim
import torch.nn.functional as F

# 设置训练参数
num_epochs = 10
learning_rate = 0.001
momentum = 0.9

# 使用 GPU,如果可用
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

# 定义优化器和损失函数
optimizer = optim.SGD(model.parameters(), lr=learning_rate, momentum=momentum)
criterion = nn.CrossEntropyLoss()

# 训练模型
for epoch in range(num_epochs):
    for i, (images, targets) in enumerate(data_loader):
        images = images.to(device)
        labels = [torch.tensor([ann["category_id"] for ann in target], dtype=torch.long) for target in targets]
        labels = torch.cat(labels).to(device)

        # 前向传播
        outputs = model(images)

        # 计算损失
        loss = criterion(outputs, labels)

        # 反向传播并优化
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if (i + 1) % 100 == 0:
            print(f"Epoch [{epoch + 1}/{num_epochs}], Step [{i + 1}/{len(data_loader)}], Loss: {loss.item():.4f}")

## 6. Evaluate the model

To evaluate the performance of the model, we can calculate the accuracy of the model on the validation set. First, we need to load the validation set data into a new DataLoader:

voc_val_data = VOCDetection(voc_root, year="2012", image_set="val", download=False)
val_data_loader = DataLoader(voc_val_data, batch_size=batch_size, shuffle=False, collate_fn=voc_collate_fn)

Next, we can calculate the accuracy of the model on the validation set:

model.eval()
correct = 0
total = 0

with torch.no_grad():
    for images, targets in val_data_loader:
        images = images.to(device)
        labels = [torch.tensor([ann["category_id"] for ann in target], dtype=torch.long) for target in targets]
        labels = torch.cat(labels).to(device)

        outputs = model(images)
        _, predicted = torch.max(outputs, 1)

        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f"Accuracy on the validation set: {100 * correct / total:.2f}%")

This simple model may not achieve high performance on the PASCAL VOC dataset, but it serves as an introductory example for object detection tasks. For better performance, you can try to use a more complex model like  Faster R-CNN , YOLO  or  SSD and use pretrained weights for transfer learning.

Guess you like

Origin blog.csdn.net/a871923942/article/details/130884600