Дата просвещение

Search

Search IconIcon to open search

сверточные сети

Last updated Unknown Edit Source

# Определение

Свертки (2D convolutions) - представляют собой основной строительный блок сверточных нейронных сетей и нашли широкое применение в обработке различных видов данных, включая аудио, текст и даже временные ряды. Однако их популярность достигла пика при применении к задачам классификации изображений.

Изображения можно рассматривать как матрицы пикселей. Для представления черно-белых изображений используется один канал (Grayscale), в то время как для цветных изображений применяются три канала (RGB - красный, зеленый, синий).

Как обрабатывали изображения до появления сверток? Это было довольно просто - все пиксели изображения последовательно собирали в один массив. Можете представить, насколько большим может быть такой массив для hq изображения. Это первое ограничение такого подхода. Второе ограничение заключается в том, что при переходе к такому представлению мы теряем информацию о пространственном расположении объектов на изображении.

Чтобы объяснить свертки, давайте проведем аналогию с применением фильтра к изображению. Допустим, у нас есть фильтр размером 3x3, и мы хотим применить его к черно-белому изображению с одним каналом.

Свертки (2D convolutions) выполняют поэлементное умножение между двумя массивами, region и filter, а затем суммируют все полученные значения. Эта операция по сути является скалярным произведением (dot product).

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

Для регулирования размера выходного изображения и выбора данных, которые будут взяты в окне свертки, используют параметры padding и striding.

После применения свертки к изображению, обычно используют активационную функцию, такую как ReLU, для выделения “feature maps” и далее применяют операцию пулинга (pooling) для уменьшения размера “feature map”, при этом сохраняя важные данные.

Max Pooling: в этой операции выбирается максимальное значение из окна, и оно сохраняется. Максимальное пулинг часто используется для выделения наиболее активных функций в данном окне

Average Pooling: здесь вычисляется среднее значение всех элементов в окне, может помочь сгладить данные и уменьшить размерность, сохраняя при этом основную информацию.

Sum Pooling: суммируются все значения в окне. Это может быть полезно, если важна суммарная информация.

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

Классические модели CNN, такие как ResNet, EfficientNet, MobileNet и другие, используются в качестве “основы” (backbone) в более сложных архитектурах. Они внесли значительный вклад в развитие нейронных сетей и остаются важными инструментами и по сей день.

Давайте рассмотрим известный набор данных MNIST, который является игрушечным датасетом, содержащим изображения рукописных цифр от 0 до 9. Каждое изображение в этом датасете имеет размер 28 × 28 пикселей. Для решения задачи с использованием фреймворка PyTorch, нам необходимо создать простейшую нейронную сеть, нам нужно определить все необходимые слои: сверточные (convolutional), активации (activation), пуллинг (pooling) и полносвязанные (fully connected) слои. Также мы должны написать код для предварительной обработки данных и цикл обучения нейронной сети.

# Пример использования

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import torch
import torch.nn as nn
import torch.optim as optim
from torch.optim.lr_scheduler import StepLR
import torchvision
import torchvision.transforms as transforms

# Define your neural network
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 16, kernel_size=3, stride=1, padding=1)
        self.relu = nn.ReLU()
        self.maxpool = nn.MaxPool2d(kernel_size=2, stride=2)
        self.fc = nn.Linear(16 * 14 * 14, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = self.relu(x)
        x = self.maxpool(x)
        x = x.view(x.size(0), -1)  # Flatten the tensor
        x = self.fc(x)
        return x

transform=transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.1307,), (0.3081,))
        ])
dataset1 = datasets.MNIST('../data', train=True, download=True,
                   transform=transform)
dataset2 = datasets.MNIST('../data', train=False,
                   transform=transform)
train_loader = torch.utils.data.DataLoader(dataset1, batch_size=10, shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset2, batch_size=10, shuffle=False)


device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = Net().to(device)

# определяем основные компоненты обучения loss function, optimezer, sheduler
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adadelta(model.parameters(), lr=1.0)
scheduler = StepLR(optimizer, step_size=1, gamma=0.7)

# тренировка модели 10 эпох
for epoch in range(1, 11):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)  # Use CrossEntropyLoss here
        loss.backward()
        optimizer.step()
        if batch_idx % 100 == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.item()))

# Связи

# Ссылки

https://stanford.edu/~shervine/teaching/cs-230/cheatsheet-convolutional-neural-networks https://github.com/sooftware/conformer