Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Компьютерное зрение. Практикум

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
☆
channel_mean = x_train.mean((0, 2, 3)) channel_std = x_train.std((0, 2, 3))
train_transforms = transforms.Compose([ transforms.ToPILImage(), transforms.RandomHorizontalFlip(0.5), transforms.Resize((256, 256)), transforms.RandomRotation(30), transforms.RandomCrop((224, 224)), transforms.ColorJitter(brightness=0.3, contrast=0.3, saturation=0.3, hue=0.1), transforms.ToTensor(), transforms.Normalize(mean=channel_mean, std=channel_std), ])
val_transforms = transforms.Compose([ transforms.ToPILImage(), transforms.Resize((256, 256)), transforms.CenterCrop((224, 224)), transforms.ToTensor(), transforms.Normalize(mean=channel_mean, std=channel_std), ])
# Добавим аугментации на уровне датасета. class AddTransformsDataset(torch.utils.data.Dataset): def __init__(self, x, y, transforms=None): self.x = x self.y = y self.transforms = transforms
def __len__(self) -> int:
51
return len(self.x)
def __getitem__(self, index: int): image = self.x[index] if self.transforms is not None: image = self.transforms(image) return image, self.y[index]
train_dataset = AddTransformsDataset(x_train, y_train, transforms =
train_transforms)
val_dataset = AddTransformsDataset(x_val, y_val, transforms = val_transforms)
train_dataloader = torch.utils.data.DataLoader( dataset=train_dataset, batch_size=200, shuffle=True, drop_last=True, num_workers=2, )
val_dataloader = torch.utils.data.DataLoader( dataset=val_dataset, batch_size=200, shuffle=False, drop_last=False, num_workers=2, )
Запустим обучение модели
%%time
# Напишем цикл обучения модели.
52
from IPython.display import clear_output
# Для ускорения обучения используем видеокарту компьютера # или виртуальной машины, если есть такая возможность.
device = torch.device('cuda:0') if torch.cuda.is_available() else torch.device('cpu')
num_epochs = 100 val_every = 1
# Подготовим модель. Этот код был приведен выше для примера
weights = models.ResNet18_Weights.DEFAULT model = models.resnet18(weights=weights) for param in model.parameters(): param.requires_grad = False model.fc = torch.nn.Linear(model.fc.in_features, len(classes))
model = model.to(dtype=x_train.dtype, device=device) #передадим модель на
устройство. Это может быть видеокарта или процессор
optimizer = torch.optim.SGD( [param for param in model.parameters() if param.requires_grad], # только
обучаемые параметры
lr=1e-2, momentum=0.9, nesterov=True, )
scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.5)
# В модели не используется Softmax, так что в качестве функции потерь нужно
53
# использовать кросс-энтропию (подаются ненормированные логиты). loss_fn = torch.nn.CrossEntropyLoss()
losses = {"train": [], "val": []}
for epoch in range(1, num_epochs + 1):
# В одной эпохе обучения мы проходим по всем объектам из обучающей
выборки – классический вариант.
local_losses = [] for x_batch, y_batch in train_dataloader: optimizer.zero_grad()
pred = model(x_batch.to(device)) loss = loss_fn(pred, y_batch.to(device))
loss.backward() optimizer.step() local_losses.append(loss.item())
losses["train"].append(sum(local_losses) / len(local_losses))
# Каждые val_every итераций считаем значение loss на валидации.
if epoch % val_every == 0: with torch.no_grad(): local_losses = [] for x_batch, y_batch in val_dataloader: val_pred = model(x_batch.to(device)) val_loss = loss_fn(val_pred, y_batch.to(device)) local_losses.append(val_loss.item())
54
losses["val"].append(sum(local_losses) / len(local_losses))
# Каждые k итераций уменьшаем шаг градиентного спуска.
if epoch % 30 == 0: scheduler.step()
# Каждые 10 итераций рисуем графики loss.
if epoch % 10 == 0: clear_output(True) fig, ax = plt.subplots(figsize=(30, 10)) plt.title("Графикошибки") plt.plot(losses["train"], ".-", label="Ошибканаобучении") plt.plot(torch.arange(0, epoch, val_every), losses["val"], ".-", label="Ошибка
на валидации")
plt.xlabel("Итерация обучения")
plt.ylabel("Значение ошибки") plt.legend() plt.grid() plt.show()
Рисунок 2.11 – Изменение значения ошибки модели ResNET во время
обучения
55
Результат работы дообученной модели представлен на рисунке 2.12.
Рисунок 2.12 – Результат работы модели ResNet
Задание. Выполните дообучение модели на произвольном датасете и решите
задачу классификации. В качестве примера можете взять следующие наборы
данных.
Pokemon Image Dataset (kaggle.com) – определить тип покемона по его
фотографии
Butterfly Image Classification (kaggle.com) – классификация бабочек по фото Weather Image Recognition (kaggle.com) – определить какая погода пофото Vegetable Image Dataset (kaggle.com) – определить тип овоща на фото Chessman image dataset (kaggle.com) – определить тип шахматной фигуры на
фото
56
3 Детекция объектов на изображении
На данный момент архитектуры семейства YOLO и R-CNN пользуются
широкой популярностью в задаче обработки изображений в реальном времени.
Как было сказано выше сверточные нейронные сети используют локальные
участки изображения для их обработки, однако если размер участка будет
небольшим, то скорость обработки изображения будет низкой, если размер участка
будет большим, то возможна потеря точности. Первая нейронная сеть из семейства
архитектур Region-basedCNN (R-CNN) с помощью детерминированных алгоритмов
компьютерного зрения выделяла на изображении массив прямоугольников
(boundingbox) в которых возможно находится объект, а затем нейронная сеть
определяла к какому из классов принадлежит изображение находящиеся в прямоугольнике. На рисунке 3.1 проиллюстрирован принцип работы R-CNN.
Рисунок 3.1 – Принцип работы R-CNN
Последующие работы пытались улучшить результат поиска прямоугольников,
для которых находится объект. Так, например, в работе для поиска
прямоугольников использовалась нейронная сеть Region Proposal Network, которая
обучалась для нахождения «интересных» boundingbox.
Архитектура YOLO (You Only Look Once) – это архитектура нейронной сети
для обнаружения объектов в реальном времени. Ее основным преимуществом
57
является высокая скорость работы, так как YOLO позволяет одновременно
обнаруживать и классифицировать объекты на изображении за один проход
нейронной сети.
Принцип работы YOLO представлен на рисунке 3.2. Каждое изображение
разбивается на блоки SxS.
Рисунок 3.2 – Принцип работы нейронной сети YOLO с разбиением на блоки
и предсказанием класса для каждого блока.
На рисунке 3.3 представлена архитектура нейронной сети YOLOv1,
изначально сеть обучалась для классификации объектов на изображении. После
обучения классификации первые 20 слоев были заморожены (то есть их веса будут
неизменны при дальнейшем обучении) затем к сети добавили 4 сверточных слоя и
58
один полносвязный слой для извлечения информации о boudingbox и
соответствующих им классах.
Рисунок 3.3 – Архитектура нейронной сети YOLOv1
Как результат, данная нейронная сеть обладает высокой скоростью работы и
точностью, сопоставимой с R-CNN, что делает ее предпочтительной в использовании решения задач обнаружения объектов.
3.1 Лабораторная работа № 3 Задача детекции
Решим задачу детекции. Задача детекции заключается в определении где
находится объект на изображении и определение к какому классу он относится.
Пример задачи детекции представлен на рисунке 3.4.
59
Рисунок 3.4 – Пример задачи детекции
Самой популярной архитектурой для решения задачи детекции является
архитектура YOLO. Архитектура YOLO (You Only Look Once) – это архитектура
нейронной сети для обнаружения объектов в реальном времени. Ее основным
преимуществом является высокая скорость работы, так как YOLO позволяет
одновременно обнаруживать и классифицировать объекты на изображении за один
проход нейронной сети.
Архитектура динамично развивается, и постоянно выходят обновления. На
60
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]