Не секрет, что сверточные нейронные сети требуют больших вычислительных ресурсов. В этой истории мы будем строить расширенную сверточную нейронную сеть на py.

Начнем с импорта необходимых библиотек. Мы также будем импортировать torchvision , потому что это облегчит нашу жизнь, помогая нам импортировать набор данных CIFAR-10.

import torch
import torchvision as tv
import torchvision.transforms as transforms
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

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

# Loading and Transforming data
transform = transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize((0.4914, 0.4822, 0.4466), (0.247, 0.243, 0.261))])
trainTransform  = tv.transforms.Compose([tv.transforms.ToTensor(), tv.transforms.Normalize((0.4914, 0.4822, 0.4466), (0.247, 0.243, 0.261))])
trainset = tv.datasets.CIFAR10(root='../data', train=True,
download=True, transform=transform)
dataloader = torch.utils.data.DataLoader(trainset, batch_size=1, shuffle=False, num_workers=4)

Пришло время написать модель.

# Writing our model
class DilatedCNN(nn.Module):
  def __init__(self):
    super(DilatedCNN,self).__init__()
    self.convlayers = nn.Sequential(
      nn.Conv2d(in_channels = 3, out_channels = 6, kernel_size = 9, stride = 1, padding = 0, dilation=2),
      nn.ReLU(),
      nn.Conv2d(in_channels=6, out_channels=16, kernel_size = 3, stride = 1, padding= 0, dilation = 2),
      nn.ReLU(),
    )
    self.fclayers = nn.Sequential(
      nn.Linear(2304,120),
      nn.ReLU(),
      nn.Linear(120,84),
      nn.ReLU(),
      nn.Linear(84,10)
    )
  def forward(self,x):
    x = self.convlayers(x)
    x = x.view(-1,2304)
    x = self.fclayers(x)
    return x

Определить расширенные сверточные слои в pytorch действительно просто. Мы можем просто сделать это, передав аргумент dilation=<int> функции conv2d.

Теперь отправим нашу модель на обучение.

net = DilatedCNN()

#optimization and score function
loss_function = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(),lr=0.001,momentum=0.5)
#training of the model
for epoch in range(2):
    running_loss= 0.0
    for i,data in enumerate(dataloader,0):
        inputs, labels = data
        optimizer.zero_grad()
        outputs = net(inputs)
        
        #backward prop
        loss = loss_function(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
        if i%2000==1999:
            print('[%d, %5d] loss: %.3f'%(epoch+1,i+1,running_loss/2000))
            running_loss = 0.0
print("Training finished! Yay!!")

Вот и все! Если вы заметили, мы использовали размер фильтра 9X9, и все же он не занимал более 120% моего процессора. Используя расширенную сверточную нейронную сеть, я смог охватить большую пространственную область.

Чтобы узнать больше о расширенной сверточной нейронной сети - https://towardsdatascience.com/understanding-2d-dilated-convolution-operation-with-examples-in-numpy-and-tensorflow-with-d376b3972b25