计算机视觉物体检测

在本篇博客中,我们将从零开始实现一个计算机视觉中的物体检测任务。我们将使用 Python 和 PyTorch 框架,并使用一个简单的卷积神经网络(CNN)模型进行物体检测。我

## 1. 准备工作

首先,确保已经安装了以下库:

- Python 3.6 或更高版本
- PyTorch 1.0 或更高版本
- torchvision
- NumPy
- OpenCV

你可以使用以下命令安装这些库:

pip install torch torchvision numpy opencv-python

## 2. 数据集

我们将使用 [PASCAL VOC](http://host.robots.ox.ac.uk/pascal/VOC/) 数据集。这是一个常用的计算机视觉数据集,包含 20 个类别的物体。你可以从 [这里](http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar) 下载数据集。

下载并解压数据集后,我们将使用 torchvision 中的 `VOCDetection` 类来加载数据集:

from torchvision.datasets import VOCDetection

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

## 3. 预处理数据

我们需要对数据进行一些预处理,以适应我们的模型。首先,我们将图像调整到固定大小(例如 224x224 像素),并将图像和标注数据转换为 PyTorch 张量:

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

接下来,我们将使用 PyTorch 的 `DataLoader` 类来加载数据:

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. 构建模型

我们将构建一个简单的卷积神经网络(CNN)来进行物体检测。这里我们使用一个简化版本的 [Faster R-CNN](https://arxiv.org/abs/1506.01497) 模型作为示例。为了简化问题,我们仅对图像进行分类,而不进行边界框回归。

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. 训练模型

我们将使用随机梯度下降(SGD)优化器和交叉熵损失函数来训练我们的模型。让我们设置一些训练参数并开始训练:

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. 评估模型

为了评估模型的性能,我们可以计算模型在验证集上的准确率。首先,我们需要将验证集数据加载到一个新的 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)

接下来,我们可以计算模型在验证集上的准确率:

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}%")

这个简单的模型可能无法在 PASCAL VOC 数据集上获得很高的性能,但它可以作为物体检测任务的入门示例。要获得更好的性能,您可以尝试使用更复杂的模型,如如 Faster R-CNNYOLO 或 SSD,并使用预训练的权重进行迁移学习。

猜你喜欢

转载自blog.csdn.net/a871923942/article/details/130884600