Вернуться на страницу brain2net: https://brain2net.ru/post/212/#more-212
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() включены наборы слоев для свертки – Свертка, Пулинг, Функция активации.
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
model = ModelConv()
Подготовка входных данных для работы сверточной нейронной сети с использованием готовых наборов данных.
Пакет torchvision состоит из различных известных наборов данных, архитектур моделей и общего преобразования изображений для компьютерного зрения.
torchvision.transforms - функции преобразования изображений, которые могут выполняться последовательно.
torchvision.datasets.MNIST - готовый набор рукописных цифр в градации серого.
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] - насыщенность конкретного цветового пикселя
# Метод оценки точности
# 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), а затем помещает его в традиционную функцию перекрестной энтропии для получения результата.
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))
# train = True
benchmark(trainLoader,model, lr=0.1)
print('Accuracy: {0:.4f}'.format(accuracy(testLoader,model)))
Сверточная нейронная сеть разбита на две цепочки: блок features (все сверточные слои) и блок classifier.
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
data = [] # Обучающий или проверочный набор данных, состоящий из кортежей
m3 - 3-х мерная матрица. Первая размерность которой это цветовой канал. Две других размерностей - это холст с двухмерным изображением.
В цикле загружаются в список data все экземпляры выборки m3 = torch.tensor(m3).float() data += [(m3, label)]
Далее формируется структура как было описано выше trainLoader = torch.utils.data.DataLoader(dataset=data, batch_size=batchSize, shuffle=True)
Литература
Вернуться на страницу brain2net: https://brain2net.ru/post/212/#more-212