содержание
4, официальная реализация Pytorch
1. Введение модели
AlexNet — это первая глубокая сверточная нейронная сеть, применяемая для классификации изображений, предложенная Алексом Крижевским, которая выиграла конкурс классификации изображений ILSVRC (ImageNet Large Scale Visual Recognition Competition) 2012 года, заняв первое место в пятерке лучших тестов с коэффициентом ошибок 15,3%. Также после этого года были предложены более глубокие нейронные сети, такие как отличный vgg,GoogLeNet. Это неплохо для традиционных алгоритмов классификации машинного обучения.
AlexNet содержит несколько относительно новых технических моментов, а также впервые успешно применяет такие приемы, как ReLU, Dropout и LRN в CNN. В то же время AlexNet также использует GPU для ускорения вычислений.
AlexNet развил идею LeNet и применил основные принципы CNN к очень глубокой и широкой сети. AlexNet в основном использует следующие новые технологические точки:
(1) Успешно использовал ReLU в качестве функции активации CNN и подтвердил, что его эффект превосходит сигмоид в более глубоких сетях, и успешно решил проблему градиентной дисперсии сигмоида, когда сеть была глубже. Хотя функция активации ReLU была предложена давно, она не применялась до появления AlexNet.
(2) Dropout используется для случайного игнорирования некоторых нейронов во время обучения, чтобы избежать переобучения модели. Хотя Dropout обсуждается в отдельной статье, AlexNet применил его на практике и подтвердил его эффективность на практике. В AlexNet Dropout в основном используется в последних нескольких полносвязных слоях.
(3) Используйте перекрывающееся максимальное объединение в CNN. Раньше объединение средних значений обычно использовалось в CNN, а AlexNet использовала максимальное объединение, чтобы избежать размытого эффекта объединения средних значений. А в AlexNet предлагается сделать размер шага меньше размера ядра пула, чтобы между выходами слоя пула было перекрытие и покрытие, что улучшает богатство признаков.
(4) Слой LRN предлагается создать механизм конкуренции для активности локальных нейронов, чтобы значение с большей реакцией становилось относительно большим, и подавляло другие нейроны с меньшей обратной связью, что повышает обобщающую способность модели.
(5) Используйте CUDA для ускорения обучения глубоких сверточных сетей и используйте мощные возможности параллельных вычислений графических процессоров для обработки большого количества матричных операций во время обучения нейронной сети. AlexNet использует два графических процессора GTX 580 для обучения, а один GTX 580 имеет всего 3 ГБ видеопамяти, что ограничивает максимальный размер сети, которую можно обучить. Поэтому автор распределяет AlexNet на два графических процессора и хранит параметры половины нейронов в видеопамяти каждого графического процессора. Поскольку связь между графическими процессорами удобна и они могут обращаться к видеопамяти друг друга, минуя память хоста, также очень эффективно использовать несколько графических процессоров одновременно. В то же время конструкция AlexNet позволяет осуществлять связь между графическими процессорами только на определенных уровнях сети, что контролирует потерю производительности связи.
(6) Улучшение данных, случайным образом перехватывая область размером 224*224 (и горизонтально перевернутое зеркало) из исходного изображения 256*256, что эквивалентно увеличению в 2*(256-224)^2=2048 раз. данных. Если нет расширения данных, CNN со многими параметрами попадет в переоснащение только с исходным объемом данных.После использования расширения данных переоснащение может быть значительно уменьшено, а способность к обобщению может быть улучшена. Делая прогнозы, возьмите четыре угла изображения плюс 5 средних позиций и переверните их влево и вправо, чтобы получить в общей сложности 10 изображений, сделайте на них прогнозы и усредните 10 результатов. В то же время в документе AlexNet упоминается, что данные RGB изображения будут обрабатываться с помощью PCA, а для основного компонента выполняется гауссовское возмущение со стандартным отклонением 0,1, добавляющее некоторый шум, этот прием может снизить частоту ошибок. еще на 1%.
2. Структура модели
Прежде всего, эта картина разделена на верхнюю и нижнюю части сети.В статье упоминается, что эти две части сети соответствуют двум графическим процессорам соответственно.Только после достижения определенного сетевого уровня для взаимодействия требуется два графических процессора. , Этот параметр полностью основан на использовании двух блочных графических процессоров для повышения эффективности работы, на самом деле структура сети не сильно отличается. Для более удобного понимания предположим, что имеется только один GPU или используем CPU для выполнения операций, и будем анализировать структуру сети из этой несколько упрощенной области направления. Общее количество слоев в сети составляет 8 слоев, 5 слоев сверточных слоев и 3 слоя полносвязных слоев.
Первый слой: слой свертки 1, вход представляет собой изображение размером 224 × 224 × 3, количество ядер свертки равно 96, а два графических процессора в статье вычисляют соответственно 48 ядер; размер ядра свертки составляет 11 × 11. × 3, шаг = 4, шаг представляет размер шага, отступ = 2.
Каков размер графика после свертки?
wide = (224 + 2 * padding - kernel_size) / stride + 1 = 55
height = (224 + 2 * padding - kernel_size) / stride + 1 = 55
dimention = 96
Затем выполните (Local Response Normalized), а затем объединение pool_size = (3, 3), stride = 2, pad = 0, чтобы, наконец, получить карту признаков первого слоя свертки.
Результат окончательной свертки первого слоя составляет 96 × 55 × 55.
Второй слой: слой свертки 2, входными данными является карта признаков предыдущего слоя свертки, количество сверток равно 256, а два графических процессора в статье имеют 128 ядер свертки соответственно. Размер ядра свертки: 5 × 5 × 48, padding = 2, шаг = 1, затем выполните LRN и, наконец, max_pooling, pool_size = (3, 3), шаг = 2;
Третий слой: свертка 3, вход — выход второго слоя, количество ядер свертки — 384, kernel_size = (3×3×256), padding = 1, третий слой не выполняет LRN и Pool
Четвертый слой: свертка 4, вход — выход третьего слоя, количество ядер свертки — 384, kernel_size = (3 × 3), padding = 1, то же, что и третий слой, без LRN и Pool
Пятый слой: свертка 5, вход — выход четвертого слоя, количество ядер свертки — 256, kernel_size = (3 × 3), padding = 1. Затем сразу перейти к max_pooling, pool_size = (3, 3), stride = 2;
6-й, 7-й и 8-й слои являются полносвязными слоями, количество нейронов в каждом слое составляет 4096, а конечный результат softmax равен 1000, потому что, как упоминалось выше, количество классификаций в конкурсе ImageNet равно 1000. RELU и Dropout используются на полносвязном уровне.
На рисунке ниже представлена сводка вышеуказанных параметров.
3. Особенности модели
- Все сверточные слои используют ReLU в качестве функции нелинейного отображения, что ускоряет сходимость модели.
- Обучение модели на нескольких графических процессорах может не только повысить скорость обучения модели, но и увеличить масштаб использования данных.
- Используя LRN для нормализации локальных особенностей, результат может эффективно снизить частоту ошибок в качестве входных данных функции активации ReLU.
- Перекрывающееся максимальное объединение, то есть существует взаимосвязь между диапазоном объединения z и размером шага s z>s (например,Средний размер ядра составляет 3 × 3/2), чтобы избежать эффекта усреднения среднего пула.
- Используйте метод случайного отсева (dropout), чтобы выборочно игнорировать отдельные нейроны при обучении, чтобы избежать переобучения модели.
4, официальная реализация Pytorch
Официальный pytorch не следует строго за реализацией бумаги AlexNet, первая свертка — это 64 ядра свертки, а официальная — 96.
class AlexNet(nn.Module):
def __init__(self, num_classes=1000):
super(AlexNet, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(64, 192, kernel_size=5, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(192, 384, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(384, 256, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(256, 256, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
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(inplace=True),
nn.Dropout(),
nn.Linear(4096, 4096),
nn.ReLU(inplace=True),
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
5, реализация кераса
import os
import pandas as pd
import numpy as np
from keras.callbacks import EarlyStopping, ModelCheckpoint
from matplotlib import pyplot as plt
from skimage.io import imread, imshow
from skimage import transform
import warnings
from tqdm import tqdm
from keras.layers import Input, Lambda, Conv2D, MaxPool2D, BatchNormalization, Dense, Flatten, Dropout
from keras.models import Model
from keras.utils import to_categorical
def AlexNet(input_shape, num_classes):
inputs = Input(input_shape, name="Input")
x = ZeroPadding2D(((3, 0), (3, 0)))(inputs)
x = Conv2D(96,
(11, 11),
4,
kernel_initializer=initializers.RandomNormal(stddev=0.01),
name="Conv_1")(x)
x = Lambda(tf.nn.local_response_normalization, name="Lrn_1")(x)
x = Activation(activation="relu")(x)
x = MaxPool2D(name="Maxpool_1")(x)
x = Conv2D(256,
(5, 5),
kernel_initializer=initializers.RandomNormal(stddev=0.01),
padding="SAME",
name="Conv_2")(x)
x = Lambda(tf.nn.local_response_normalization, name="Lrn_2")(x)
x = Activation(activation="relu")(x)
x = MaxPool2D(name="Maxpool_2")(x)
x = Conv2D(384,
(3, 3),
padding="Same",
kernel_initializer=initializers.RandomNormal(stddev=0.01),
name="Conv_3_1")(x)
x = Conv2D(384,
(3, 3),
padding="Same",
kernel_initializer=initializers.RandomNormal(stddev=0.01),
name="Conv_3_2")(x)
x = Conv2D(256,
(3, 3),
activation="relu",
padding="Same",
kernel_initializer=initializers.RandomNormal(stddev=0.01),
name="Conv_3_3")(x)
x = MaxPool2D(name="Maxpool_3")(x)
x = Flatten(name="Flt_1")(x)
x = Dense(4096,
activation="relu",
kernel_initializer=initializers.RandomNormal(stddev=0.01),
name="fc_1")(x)
x = Dropout(0.5, name="drop_1")(x)
x = Dense(4096,
activation="relu",
kernel_initializer=initializers.RandomNormal(stddev=0.01),
name="fc_2")(x)
x = Dropout(0.5, name="drop_2")(x)
output = keras.layers.Dense(num_classes, activation="softmax", name="Output")(x)
m = keras.Model(inputs, output, name="AlexNet")
m.summary()
return m