首页 > 解决方案 > 为什么较大的神经网络比较小的神经网络反向传播更快

问题描述

我在pytorch中写了以下两个NN用于图像分割:较小的一个:

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

然而,在 mini-batch size = 8 的训练期间。较小的网络需要 2 秒才能完成一次迭代,而较大的网络只需 0.3 秒即可完成。

我还观察到两个网络之间的参数比约为 5:6。然而,在训练过程中,较小的网络只需要 1GB VRAM,而较大的网络需要 3GB。因为我的 1050ti 有 4GB VRAM。我想以内存换取速度。知道我该怎么做吗?

标签: performancedeep-learningconv-neural-networkpytorch

解决方案


我在您指定的大小的合成数据上对您的模型进行了快速基准测试。至少在我的系统上,差异实际上不是由模型向前或向后给出,而是由损失的计算给出。这很可能是因为第一个模型使用了更多的 GPU,因此操作的排队时间稍长

事实上,您的第一个模型执行了约 6.3 亿次操作,而第二个模型执行了约 2.7 亿次操作。请注意,在第二个模型中,您立即将特征图的大小从 256x256 减小到 128x128,而在第一个模型中,您仅在最后两个卷积中减小了大小。这对执行的操作数量有很大影响。

因此,如果您希望使用类似 V0 的模型并使其更快,您应该立即尝试减小特征图的大小。使用这个较小的模型(就内存而言),您还可以增加批量大小。

如果您想改用 V1,则无能为力。您可以尝试使用checkpointPytorch 0.4 中引入的 s 将计算换成内存,直到可以将批次增加到 16 的程度。它可能会运行得更快,也可能不会,这取决于您需要权衡多少计算。

如果您的输入大小不变,您可以做的另一件简单的事情是让它运行得更快,设置为torch.cudnn.benchmark = True。这将为特定配置寻找最快的算法集。


推荐阅读