Построение сверточной нейронной сети с использованием PyTorch

Создание CNN с использованием PyTorch

 

Введение

 

Сверточная нейронная сеть (CNN или ConvNet) – это алгоритм глубокого обучения, специально разработанный для задач, где распознавание объектов критично, например, классификация, обнаружение и сегментация изображений. CNN способны достигать точности, сопоставимой с результатами современных исследований в сложных задачах компьютерного зрения, что позволяет применять их в таких областях, как системы наблюдения, управление складами и многое другое.

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

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

 

Как работают сверточные нейронные сети?

 

Сверточные нейронные сети (CNN) обычно используются для задач классификации изображений. В общих чертах CNN содержат три основных типа слоев:

  1. Сверточные слои. Применяют сверточные фильтры к входу для извлечения признаков. Нейроны в этих слоях называются фильтрами и захватывают пространственные шаблоны входа.
  2. Слой пулинга. Уменьшение размера признаковых карт, полученных из сверточных слоев, для уплотнения информации. Часто используются стратегии максимального пулинга и среднего пулинга.
  3. Полносвязные слои. Принимают высокоуровневые признаковые карты из сверточных и пулинговых слоев для классификации. Можно объединить несколько полносвязных слоев.

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

Например, один фильтр может активироваться при обнаружении вертикальных линий, создавая признаковую карту, отображающую вертикальные линии на изображении. Применение нескольких фильтров к одному входу создает стек признаковых карт, запечатлевающих различные аспекты изображения.

   

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

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

В PyTorch мы можем определить сверточные, пулинговые и полносвязные слои для создания архитектуры CNN. Вот пример кода:

# Слои свертки 
self.conv1 = nn.Conv2d(количество_входных_каналов, количество_выходных_каналов, размер_ядра)
self.conv2 = nn.Conv2d(количество_входных_каналов, количество_выходных_каналов, размер_ядра)

# Слой пулинга
self.pool = nn.MaxPool2d(размер_ядра)

# Полносвязные слои 
self.fc1 = nn.Linear(входные_признаки, выходные_признаки)
self.fc2 = nn.Linear(входные_признаки, выходные_признаки)

 

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

 

Начало работы с CNN

 

В этом разделе мы загрузим CIFAR10 и создадим и обучим модель классификации на основе сверточной нейронной сети с использованием PyTorch. Набор данных CIFAR10 содержит изображения размером 32×32 пикселя в цветовом пространстве RGB и включает десять классов, что является полезным для тестирования моделей классификации изображений. Классы обозначены целыми числами от 0 до 9.

Примечание: Пример кода представляет собой модифицированную версию из блога MachineLearningMastery.com.

Сначала мы будем использовать torchvision для загрузки и загрузки набора данных CIFAR10. Мы также будем использовать torchvision для преобразования тестового и обучающего наборов в тензоры.

импорт торч
импорт торч.нн как нн
импорт торч.оптим как оптим
импорт торчвижн

трансформ = торчвижн.трансформы.Составить(
    [торчвижн.трансформы.ToTensor()]
)

тренировка = торчвижн.наборыданных.CIFAR10(
    root="data", тренировка=True, скачать=True, трансформ=трансформ
)

тест = торчвижн.наборыданных.CIFAR10(
    root="data", тренировка=False, скачать=True, трансформ=трансформ
)

 

Скачивание https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz в data/cifar-10-python.tar.gz

100%|██████████| 170498071/170498071 [00:10<00:00, 15853600.54it/s]

Извлечение data/cifar-10-python.tar.gz в data
Файлы уже скачаны и проверены

 

После этого мы будем использовать загрузчик данных и разделить изображения на пакеты. 

размер_пакета = 32
загрузчик_тренировки = торч.utils.data.DataLoader(
    тренировка, размер_пакета=размер_пакета, перемешивание=True
)
загрузчик_теста = торч.utils.data.DataLoader(
    тест, размер_пакета=размер_пакета, перемешивание=True
)

 

Для визуализации изображения в одном пакете изображений мы будем использовать функцию make_grid из matplotlib и torchvision. 

из torchvision.utils импортировать make_grid
импорт matplotlib.pyplot как plt

def показать_пакет(dl):
    для изображений, метки в dl:
        fig, ax = plt.subplots(figsize=(12, 12))
        ax.set_xticks([]); ax.set_yticks([])
        ax.imshow(make_grid(изображения[:64], nrow=8).permute(1, 2, 0))
        break
показать_пакет(загрузчик_тренировки)

 

Как мы видим, у нас есть изображения автомобилей, животных, самолетов и лодок. 

   

Затем мы создадим нашу модель сверточной нейронной сети. Для этого мы должны создать класс Python и инициализировать свертки, maxpool и полносвязные слои. Наша архитектура имеет 2 сверточных слоя с пулингом и линейные слои. 

После инициализации мы не будем соединять все слои последовательно в функции forward. Если вы новичок в PyTorch, вам следует прочитать статью “Интерпретируемые нейронные сети с использованием PyTorch”, чтобы подробнее понять каждый компонент. 

класс МодельСНС(нн.Module):
    def __init__(self):
        super().__init__()
        self.сверт1 = нн.Conv2d(3, 32, размер_ядра=(3,3), шаг=1, заполнение=1)
        self.акт1 = нн.ReLU()
        self.выкл1 = нн.Dropout(0.3)
 
        self.сверт2 = нн.Conv2d(32, 32, размер_ядра=(3,3), шаг=1, заполнение=1)
        self.акт2 = нн.ReLU()
        self.пул2 = нн.MaxPool2d(размер_ядра=(2, 2))
 
        self.плоск = нн.Flatten()
 
        self.полносвяз3 = нн.Linear(8192, 512)
        self.акт3 = нн.ReLU()
        self.выкл3 = нн.Dropout(0.5)
 
        self.полносвяз4 = нн.Linear(512, 10)
 
    def forward(self, x):
        # вход 3x32x32, выход 32x32x32
        x = self.акт1(self.сверт1(x))
        x = self.выкл1(x)
        # вход 32x32x32, выход 32x32x32
        x = self.акт2(self.сверт2(x))
        # вход 32x32x32, выход 32x16x16
        x = self.пул2(x)
        # вход 32x16x16, выход 8192
        x = self.плоск(x)
        # вход 8192, выход 512
        x = self.акт3(self.полносвяз3(x))
        x = self.выкл3(x)
        # вход 512, выход 10
        x = self.полносвяз4(x)
        return x

 

Теперь мы инициализируем нашу модель, установим функцию потерь и оптимизатор. 

модель = МодельСНС()
лосс_фн = нн.CrossEntropyLoss()
оптимизатор = оптим.SGD(модель.parameters(), lr=0.001, momentum=0.9)

 

В этапе обучения мы будем обучать нашу модель в течение 10 эпох.

  1. Мы используем функцию forward модели для прямого прохода, затем обратный проход с использованием функции потерь и, наконец, обновление весов. Этот шаг практически одинаков для всех типов нейронных сетей.
  2. Затем мы используем загрузчик тестовых данных для оценки производительности модели в конце каждой эпохи.
  3. Вычисление точности модели и вывод результатов.
n_epochs = 10
for epoch in range(n_epochs):
    for i, (images, labels) in enumerate(trainloader):
        # Прямой проход 
        outputs = model(images)
        loss = loss_fn(outputs, labels)

        # Обратный проход и оптимизация
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    correct = 0
    total = 0
    with torch.no_grad():
        for images, labels in testloader:
            outputs = model(images)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()

    print('Эпоха %d: Точность: %d %%' % (epoch,(100 * correct / total)))

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

Эпоха 0: Точность: 41 %
Эпоха 1: Точность: 46 %
Эпоха 2: Точность: 48 %
Эпоха 3: Точность: 50 %
Эпоха 4: Точность: 52 %
Эпоха 5: Точность: 53 %
Эпоха 6: Точность: 53 %
Эпоха 7: Точность: 56 %
Эпоха 8: Точность: 56 %
Эпоха 9: Точность: 57 %

С помощью PyTorch вам не нужно создавать все компоненты сверточных нейронных сетей с нуля, так как они уже доступны. Это становится еще проще, если вы используете `torch.nn.Sequential`. PyTorch разработан таким образом, чтобы быть модульным и предлагать большую гибкость при построении, обучении и оценке нейронных сетей.

Заключение

В этой статье мы рассмотрели, как создать и обучить сверточную нейронную сеть для классификации изображений с использованием PyTorch. Мы рассмотрели основные компоненты архитектуры CNN – сверточные слои для извлечения признаков, слои пулинга для уменьшения размерности и полносвязные слои для предсказания.

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

    Абид Али Аван (@1abidaliawan) – сертифицированный профессиональный ученый-исследователь данных, который любит создавать модели машинного обучения. В настоящее время он фокусируется на создании контента и написании технических блогов о технологиях машинного обучения и науке о данных. Абид имеет степень магистра по управлению технологиями и степень бакалавра по инженерии телекоммуникаций. Его цель – создать продукт искусственного интеллекта с использованием графовых нейронных сетей для студентов, страдающих от психических заболеваний.