Почему большая нейронная сеть распространяется быстрее, чем меньшая - PullRequest
0 голосов
/ 01 июля 2018

Я написал следующие два NN в pytorch для сегментации изображения: Меньший:

class ConvNetV0(nn.Module):

def __init__(self):
    super(ConvNetV0, self).__init__()
    self.conv1 = nn.Conv2d(3, 30, 4, padding=2)
    self.conv2 = nn.Conv2d(30, 50, 16, padding=7, bias=True)
    self.conv3 = nn.Conv2d(50, 20, 2, stride=2)
    self.conv4 = nn.Conv2d(20, 2, 2, stride=2)

def forward(self, x):
    x = self.conv1(x)
    x = F.relu(x)
    x = self.conv2(x)
    x = F.relu(x)
    x = self.conv3(x)
    x = F.relu(x)
    y = self.conv4(x)
    return y

Чем больше:

class ConvNetV1(nn.Module):

def __init__(self):
    super(ConvNetV1, self).__init__()
    self.conv0 = nn.Conv2d(3, 50, 4, padding=1, stride=2)
    self.conv_r1 = nn.Conv2d(50, 40, 15, padding=7, bias=True)
    self.conv_r2 = nn.Conv2d(40, 25, 3, padding=1)
    self.conv_r3 = nn.Conv2d(25, 25, 2, stride=2)
    # self.conv_r3 = nn.MaxPool2d(2, stride=2)
    self.conv_b1 = nn.Conv2d(50, 15, 4, padding=1, stride=2)
    self.conv1 = nn.Conv2d(40, 2, 1)

def forward(self, x):
    x = self.conv0(x)
    x = F.relu(x)

    x1 = self.conv_r1(x)
    x1 = F.relu(x1)
    x1 = self.conv_r2(x1)
    x1 = F.relu(x1)
    x1 = self.conv_r3(x1)

    x2 = self.conv_b1(x)

    y = torch.cat([x1, x2], dim=1)
    y = self.conv1(y)
    return y

Однако во время обучения при размере мини-партии = 8. Меньшей сети требуется 2 с для выполнения одной итерации, в то время как для более крупной требуется всего 0,3 с.

Я также замечаю, что соотношение без параметров между двумя сетями составляет около 5: 6. Однако во время обучения меньшая сеть занимает только 1 ГБ видеопамяти, а большая - 3 ГБ. Так как у меня 1050ти есть 4ГБ ВРАМ. Я хотел бы обменять память на скорость. Есть идеи, как мне это сделать?

1 Ответ

0 голосов
/ 10 июля 2018

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

Фактически ваша первая модель выполняет ~ 630 миллионов операций, а вторая - около 270 миллионов. Обратите внимание, что во второй модели вы сразу уменьшаете размер карт объектов с 256x256 до 128x128, тогда как в первой модели вы уменьшаете размер только в двух последних свертках. Это имеет большое влияние на количество выполняемых операций.

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

Если вы хотите использовать V1 вместо этого, вы ничего не можете сделать. Вы можете попытаться использовать checkpoint s, представленные в Pytorch 0.4, для обмена вычислениями на память до точки, где вы можете увеличить пакет до 16. Он может работать немного быстрее или нет, в зависимости от того, сколько вычислительных ресурсов вам нужно обменять .

Еще одна простая вещь, которую вы можете сделать, чтобы она работала быстрее, если ваш входной размер не меняется, установлен torch.cudnn.benchmark = True. Это будет искать самый быстрый набор алгоритмов для конкретной конфигурации.

...