Вернуться на страницу brain2net: https://brain2net.ru/post/212/#more-212

PyTopch. Сверточная нейронная сеть

Convolutional Networks

In [1]:
import torch
import torch.nn as nn

Слой Conv2d — это двумерная свертка.

nn.Conv2d(in_channels,out_channels, kernel_size, stride, padding)

Изображение в оттенках серого состоит из массива шириной x пикселов и высотой y пикселов. Цветное RGB-изображение будет состоять из 3-х таких массивов. Количество входдных каналов - in_channels.

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

kernel_size - описывает высоту и ширину фильтра.Это или отдельный скаляр, задающий квадрат, или кортеж для прямоугольного фильтра. Проводится умножендие каждого элемента в матрице на соответствующий член в другой матрице и результат складывается. Затем фильтр перемещается и процесс повторяется . stride показывает, на сколько шагов по всем входным данным мы продвигаемся, когда настраиваем фильтр на новую позицию. Можно продвигаться с шагом 1, что дает карту признаков того же размера, что и ввода. Можно передать кортеж (a, b), что позволило бы перемещать a поперек и b вниз на каждом шаге.

padding (отступ) – добавляется указанное количество строк и солбцов с нулями. Если не задавать отступ, любые пограничные случаи, с которыми столкнется PyTorch в последних столбцах ввода, просто отбрасываются. Как и в случае с stride и kernel_size, можно передать кортеж для отступа height × weight, а не отдельное число, которое заполняется одинаково в обоих направлениях.

Слои пулинга (субдискретизации) используются в сочетании со слоями свертки. Эти слои снижают разрешение сети от предыдущего входного слоя, что дает меньше параметров на нижних слоях. Такое сжатие приводит к более быстрым вычислениям вначале и помогает предотвратить переобучение сети.

nn.MaxPool2d(kernel_size=3, stride=2)

Ядро сдвигаясь на шаг выделяет тензоры во входном поле, аналогично движению ядра по изображению в свертке. MaxPool берет максимальное значение каждого из этих тензоров. Как и в слоях свертки, в Max Pool есть опция дополнительных гиперпараметров для управления степенью дополнения входного тензора данных нулями (padding), которая создает границу нулевых значений вокруг тензора в случае, если шаг выходит за пределы окна тензора.

nn.Sequential() позволяет создавать цепочку слоев по логическому принципу. Данные последовательно проходят через каждый элемент массива слоев.

В примере ниже в отдельне nn.Sequential() включены наборы слоев для свертки – Свертка, Пулинг, Функция активации.

In [2]:
class ModelConv(nn.Module):
    def __init__(self):
        super(ModelConv, self).__init__() 
        self.layer1 = nn.Sequential(nn.Conv2d(1,16, kernel_size=5, stride=1, padding=2),
             nn.ReLU(),
             nn.MaxPool2d(kernel_size=2, stride=2))
        self.layer2 = nn.Sequential(nn.Conv2d(16, 32, kernel_size=5, stride=1, padding=2),
             nn.ReLU(),
             nn.MaxPool2d(kernel_size=2, stride=2))        
        self.fc1 = nn.Linear(32*7*7, 10)
        
    def forward(self, x):
        out= self.layer1(x)
        out= self.layer2(out)
        out=out.view(out.size(0), -1)
        out = self.fc1(out)
        return out
In [3]:
model = ModelConv()

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

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

torchvision.transforms - функции преобразования изображений, которые могут выполняться последовательно.

torchvision.datasets.MNIST - готовый набор рукописных цифр в градации серого.

In [4]:
import torchvision
import torchvision.transforms as transforms
batchSize = 100
trainSet = torchvision.datasets.MNIST(root='./data', train = True, transform=transforms.ToTensor(), download=True)
trainLoader = torch.utils.data.DataLoader(dataset=trainSet, batch_size=batchSize, shuffle = True)
testSet = torchvision.datasets.MNIST(root='./data', train = False, transform=transforms.ToTensor(), download=True)
testLoader = torch.utils.data.DataLoader(dataset=testSet, batch_size=batchSize, shuffle = True)

trainSet[9] - экземпляр из обучающей выборки. Картеж из матрицы признаков и метки.

trainSet[9][0] - матрица признаков экземпляра.

trainSet[9][1] - метка класса экземпляра

trainSet[9][0][0] - двухмерная матрица признаков (пикселей), соответствующия одному из цветовых коналов.

trainSet[9][0][0][0][0] - насыщенность конкретного цветового пикселя

In [5]:
# Метод оценки точности
# accuracy = (TP + TN) / (TP + TN + FP + FN)

def accuracy(testLoader,model):    
    correct, total = 0, 0
    with torch.no_grad():
        for data in testLoader:
            images, labels = data
            outputs = model(images)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()      
    return(correct / total)

torch.optim.SGD - стохастический градиентый спуск

torch.nn.CrossEntropyLoss() функция перекрестной энтропии. Функция выполняет сигмоидизацию выходного результата (устанавливает данные между 0-1), а затем помещает его в традиционную функцию перекрестной энтропии для получения результата.

In [6]:
import torch.optim as optim
import time

def benchmark(trainLoader, model, epochs=1, lr=0.01):
    model.__init__()
    start=time.time()
    optimiser = optim.SGD(model.parameters(), lr=lr)
    criterion = nn.CrossEntropyLoss()
    for epoch in range(epochs):
        for i, (images, labels) in enumerate(trainLoader):
            optimiser.zero_grad()
            outputs = model(images)
            loss = criterion(outputs, labels)
            loss.backward()
            optimiser.step()
    print('Accuracy: {0:.4f}'.format(accuracy(trainLoader,model)))
    print('Training time: {0:.2f}'.format(time.time() - start))   
In [7]:
# train = True
benchmark(trainLoader,model, lr=0.1)
Accuracy: 0.9756
Training time: 23.33
In [8]:
print('Accuracy: {0:.4f}'.format(accuracy(testLoader,model)))
Accuracy: 0.9763

Другой пример формирования nn.Sequential()

Сверточная нейронная сеть разбита на две цепочки: блок features (все сверточные слои) и блок classifier.

In [9]:
class CNNNet(nn.Module):
    def __init__(self, num_classes=2):
        super(CNNNet, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(64, 192, kernel_size=5, padding=2),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(192, 384, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.Conv2d(384, 256, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=3, stride=2),
        )
        self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
        self.classifier = nn.Sequential(
            nn.Dropout(),
            nn.Linear(256 * 6 * 6, 4096),
            nn.ReLU(),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(),
            nn.Linear(4096, num_classes)
        )
    def forward(self, x):
        x = self.features(x)
        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.classifier(x)
        return x

Вариант подготовки собственных данных для нейронной сети

In [10]:
data = []  # Обучающий или проверочный набор данных, состоящий из кортежей

m3 - 3-х мерная матрица. Первая размерность которой это цветовой канал. Две других размерностей - это холст с двухмерным изображением.

В цикле загружаются в список data все экземпляры выборки m3 = torch.tensor(m3).float() data += [(m3, label)]

Далее формируется структура как было описано выше trainLoader = torch.utils.data.DataLoader(dataset=data, batch_size=batchSize, shuffle=True)

Литература

  1. Deep Learning with PyTorch. Quick Start Guide // David Julian
  2. Пойнтер Ян Программируем с PyTorch: Создание приложений глубокого обучения. - СПб.: Питер, 2020. - 256 с.: ил.

Вернуться на страницу brain2net: https://brain2net.ru/post/212/#more-212