GoogLeNet: сети параллельного соединения

глубокое обучение
GoogLeNet: сети параллельного соединения

Аккаунт WeChat: ilulaoshi / Личный сайт:Мистер Лу.info/machine- сейчас...

В 2014 году в конкурсе распознавания изображений ImageNet компания Google GoogLeNet получила первый приз. Название GoogLeNet отдает дань уважения LeNet, но в структуре сети сложно увидеть тень LeNet. GoogLeNet впитала идею свёрточного слоя 1×1 в NiN и сделала на этой основе большие улучшения. В последующие годы исследователи внесли в GoogLeNet несколько улучшений, и в этом разделе представлена ​​первая версия этой серии моделей.

Начальный блок

Базовый блок свертки в GoogLeNet называется блоком Inception, названным в честь фильма «Начало». В фильме главный герой мечется между мечтами и реальностью и подчеркивает: «Нам нужно идти глубже». По сравнению с блоком NiN этот базовый блок имеет более сложную структуру, как показано на рисунке ниже.

Inception块

В начальном блоке есть 4 параллельных пути (Path). Первые три пути используют сверточные слои с размерами окна 1 × 1, 3 × 3 и 5 × 5 для извлечения информации в разных пространственных размерах, а средние два пути сначала выполняют свертку 1 × 1 на входе для уменьшения. каналов для уменьшения сложности модели. Четвертый путь использует максимальный слой объединения 3 × 3, за которым следует сверточный слой 1 × 1 для изменения количества каналов. Все 4 пути используют соответствующее заполнение, чтобы вход и выход были одинаковой высоты и ширины, или, если входное изображение имеет размер 12 × 12, то выходной размер четырех путей составляет 12 × 12, но количество выходных каналов отличается. На каждом конце мы объединяем выходы каждого пути в измерении канала. Например, выход пути 1 — 64 × 12 × 12, выход пути 2 — 128 × 12 × 12, выход пути 3 — 32 × 12 × 12, выход пути 4 — 32 × 12 × 12. , выход всего начального блока равен (64 + 128 + 32 + 32) × 12 × 12. Следовательно, настраиваемым гиперпараметром блока Inception является количество выходных каналов для разных путей.

Следующий код определяет начальный блок, параметрin_channelsколичество входных каналов,c1прибытьc4- количество выходных каналов для каждого пути.

class InceptionBlock(nn.Module):
    # `c1`--`c4` are the number of output channels for each path
    def __init__(self, in_channels, c1, c2, c3, c4, **kwargs):
        super(InceptionBlock, self).__init__(**kwargs)
        # Path 1 is a single 1 x 1 convolutional layer
        self.p1_1 = nn.Conv2d(in_channels, c1, kernel_size=1)
        # Path 2 is a 1 x 1 convolutional layer followed by a 3 x 3
        # convolutional layer
        self.p2_1 = nn.Conv2d(in_channels, c2[0], kernel_size=1)
        self.p2_2 = nn.Conv2d(c2[0], c2[1], kernel_size=3, padding=1)
        # Path 3 is a 1 x 1 convolutional layer followed by a 5 x 5
        # convolutional layer
        self.p3_1 = nn.Conv2d(in_channels, c3[0], kernel_size=1)
        self.p3_2 = nn.Conv2d(c3[0], c3[1], kernel_size=5, padding=2)
        # Path 4 is a 3 x 3 maximum pooling layer followed by a 1 x 1
        # convolutional layer
        self.p4_1 = nn.MaxPool2d(kernel_size=3, stride=1, padding=1)
        self.p4_2 = nn.Conv2d(in_channels, c4, kernel_size=1)

    def forward(self, x):
        p1 = F.relu(self.p1_1(x))
        p2 = F.relu(self.p2_2(F.relu(self.p2_1(x))))
        p3 = F.relu(self.p3_2(F.relu(self.p3_1(x))))
        p4 = F.relu(self.p4_2(self.p4_1(x)))
        # Concatenate the outputs on the channel dimension
        # the output channel number is c1 + c2 + c3 + c4
        return torch.cat((p1, p2, p3, p4), dim=1)

В начальном блоке используются разные сверточные слои для исследования входных данных, и мы можем объединять разные пути вместе в определенном соотношении.

GoogLeNet

По сравнению с AlexNet/VGG/NiN модель GoogLeNet выглядит более сложной и включает множество хорошо спроектированных модулей.

GoogLeNet网络结构,输入在最下方

Мы используем вход размером 96×96, чтобы продемонстрировать изменение размера данных после каждого шага.

def googlenet():
    # input shape: 1 * 96 * 96
    # convolutional and max pooling layer 
    # 1 * 96 * 96 -> 64 * 24 * 24
    b1 = nn.Sequential(nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3),
                   nn.ReLU(),
                   nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
    # convolutional and max pooling layer 
    # 64 * 24 * 24 -> 192 * 12 * 12
    b2 = nn.Sequential(nn.Conv2d(64, 64, kernel_size=1),
                   nn.ReLU(),
                   nn.Conv2d(64, 192, kernel_size=3, padding=1),
                   nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
    # 2 InceptionBlock
    # 192 * 12 * 12 -> 480 * 6 * 6
    b3 = nn.Sequential(InceptionBlock(192, 64, (96, 128), (16, 32), 32),
                   InceptionBlock(256, 128, (128, 192), (32, 96), 64),
                   nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
    # 5 InceptionBlock
    # 480 * 6 * 6 -> 832 * 3 * 3
    b4 = nn.Sequential(InceptionBlock(480, 192, (96, 208), (16, 48), 64),
                   InceptionBlock(512, 160, (112, 224), (24, 64), 64),
                   InceptionBlock(512, 128, (128, 256), (24, 64), 64),
                   InceptionBlock(512, 112, (144, 288), (32, 64), 64),
                   InceptionBlock(528, 256, (160, 320), (32, 128), 128),
                   nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
    # 2 InceptionBlock and max pooling layer
    # 832 * 3 * 3 -> 1024 * 1
    b5 = nn.Sequential(Inception(832, 256, (160, 320), (32, 128), 128),
                   Inception(832, 384, (192, 384), (48, 128), 128),
                   # AdaptiveMaxPool2d convert the matrix into 1 * 1 scalar
                   nn.AdaptiveMaxPool2d((1,1)),
                   nn.Flatten())
    # final linear layer, for classification label number
    # 1024 -> 10
    net = nn.Sequential(b1, b2, b3, b4, b5, nn.Linear(1024, 10))
    return net

В этом коде весь GoogLeNet разбирается на 5 частей:

  1. b1: 7 × 7 сверточных слоев и 3 × 3 объединяющих слоя
  2. b2: 1 × 1 сверточный слой, 3 × 3 сверточных слоя и 3 × 3 максимальных объединяющих слоя
  3. b3: 2 последовательных начальных блока и 3 × 3 максимальных слоя объединения
  4. b4: 5 последовательных начальных блоков и 3 × 3 максимальных слоя объединения
  5. b5: 2 последовательных начальных блока следуют за слоем объединения глобальных средних значений, после слоя объединения глобальных средних значений каждый канал становится скаляром 1×1.

мы начинаем сb3Например,b3Есть два начальных блока.В первом начальном блоке размеры выходного канала четырех путей равны 64, 128, 32 и 32 соответственно.Соотношение этих четырех путей: 64:128:32:32 = 2: 4:1:1. Эти параметры получены в результате обширных экспериментов с набором данных ImageNet.

Наконец, количество категорий меток становится размером 1024. Если используется Fashion-MNIST, выходная категория равна 10.

Процесс обучения модели в основном аналогичен LeNet, AlexNet и VGG, которые использовались ранее, и все коды помещаются вGitHubначальство.

резюме

  • Начальный блок эквивалентен подсети с 4 путями. Существуют сверточные слои и слои с максимальным объединением с различными размерами окна в 4 путях, и 4 пути извлекают информацию параллельно.
  • GoogLeNet объединяет несколько тщательно разработанных начальных блоков и других слоев. Соотношение распределения номеров каналов в начальном блоке получено в результате большого количества экспериментов с набором данных ImageNet.
  • GoogLeNet и ее преемники когда-то были одной из самых эффективных моделей ImageNet.

использованная литература

  1. Szegedy, C., Liu, W., Jia, Y., Sermanet, P., Reed, S., & Anguelov, D. & Rabinovich, A.(2015). Going deeper with convolutions. In Proceedings of the IEEE conference on computer vision and pattern recognition (pp. 1-9).
  2. 2 come.love/chapter_con…
  3. Тан Шусен Что/погружение-в-Д…