Реализация базового блока keras InceptionResnetV2 не соответствует реализации в оригинальной статье?

#keras #deep-learning #neural-network #conv-neural-network

#keras #глубокое обучение #нейронная сеть #conv-нейронная сеть

Вопрос:

Я пытался сравнить сводку модели InceptionResnetV2 из реализации Keras с той, которая указана в их документе, и, похоже, она не имеет большого сходства, когда дело доходит до блока filter_concat .

Первые строки модели summary() такие, как показано ниже. (в моем случае входные данные изменены на 512×512, но, насколько мне известно, это не влияет на количество фильтров на слой, поэтому мы также можем использовать их для отслеживания перевода бумажного кода):

 Model: "inception_resnet_v2"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to
==================================================================================================
input_1 (InputLayer)            (None, 512, 512, 3)  0
__________________________________________________________________________________________________
conv2d_1 (Conv2D)               (None, 255, 255, 32) 864         input_1[0][0]
__________________________________________________________________________________________________
batch_normalization_1 (BatchNor (None, 255, 255, 32) 96          conv2d_1[0][0]
__________________________________________________________________________________________________
activation_1 (Activation)       (None, 255, 255, 32) 0           batch_normalization_1[0][0]
__________________________________________________________________________________________________
conv2d_2 (Conv2D)               (None, 253, 253, 32) 9216        activation_1[0][0]
__________________________________________________________________________________________________
batch_normalization_2 (BatchNor (None, 253, 253, 32) 96          conv2d_2[0][0]
__________________________________________________________________________________________________
activation_2 (Activation)       (None, 253, 253, 32) 0           batch_normalization_2[0][0]
__________________________________________________________________________________________________
conv2d_3 (Conv2D)               (None, 253, 253, 64) 18432       activation_2[0][0]
__________________________________________________________________________________________________
batch_normalization_3 (BatchNor (None, 253, 253, 64) 192         conv2d_3[0][0]
__________________________________________________________________________________________________
activation_3 (Activation)       (None, 253, 253, 64) 0           batch_normalization_3[0][0]
__________________________________________________________________________________________________
max_pooling2d_1 (MaxPooling2D)  (None, 126, 126, 64) 0           activation_3[0][0]
__________________________________________________________________________________________________
conv2d_4 (Conv2D)               (None, 126, 126, 80) 5120        max_pooling2d_1[0][0]
__________________________________________________________________________________________________
batch_normalization_4 (BatchNor (None, 126, 126, 80) 240         conv2d_4[0][0]
__________________________________________________________________________________________________
activation_4 (Activation)       (None, 126, 126, 80) 0           batch_normalization_4[0][0]
__________________________________________________________________________________________________
conv2d_5 (Conv2D)               (None, 124, 124, 192 138240      activation_4[0][0]
__________________________________________________________________________________________________
batch_normalization_5 (BatchNor (None, 124, 124, 192 576         conv2d_5[0][0]
__________________________________________________________________________________________________
activation_5 (Activation)       (None, 124, 124, 192 0           batch_normalization_5[0][0]
__________________________________________________________________________________________________
max_pooling2d_2 (MaxPooling2D)  (None, 61, 61, 192)  0           activation_5[0][0]
__________________________________________________________________________________________________
conv2d_9 (Conv2D)               (None, 61, 61, 64)   12288       max_pooling2d_2[0][0]
__________________________________________________________________________________________________
batch_normalization_9 (BatchNor (None, 61, 61, 64)   192         conv2d_9[0][0]
__________________________________________________________________________________________________
activation_9 (Activation)       (None, 61, 61, 64)   0           batch_normalization_9[0][0]
__________________________________________________________________________________________________
conv2d_7 (Conv2D)               (None, 61, 61, 48)   9216        max_pooling2d_2[0][0]
__________________________________________________________________________________________________
conv2d_10 (Conv2D)              (None, 61, 61, 96)   55296       activation_9[0][0]
__________________________________________________________________________________________________
batch_normalization_7 (BatchNor (None, 61, 61, 48)   144         conv2d_7[0][0]
__________________________________________________________________________________________________
batch_normalization_10 (BatchNo (None, 61, 61, 96)   288         conv2d_10[0][0]
__________________________________________________________________________________________________
activation_7 (Activation)       (None, 61, 61, 48)   0           batch_normalization_7[0][0]
__________________________________________________________________________________________________
activation_10 (Activation)      (None, 61, 61, 96)   0           batch_normalization_10[0][0]
__________________________________________________________________________________________________
average_pooling2d_1 (AveragePoo (None, 61, 61, 192)  0           max_pooling2d_2[0][0]
__________________________________________________________________________________________________
.
.
. 
many more lines
  

На рисунке 3 их статьи (рисунок прилагается ниже) показано, как формируется базовый блок как для InceptionV4, так и для InceptionResnetV2. На рисунке 3 в базовом блоке есть три объединения фильтров, но в выходных данных, которые я показал вам выше, объединение, похоже, представляет собой смесь последовательных максимальных пулов или что-то в этом роде (первая конкатенация должна появиться рядом после max_pooling2d_1 ). Это увеличивает количество фильтров, как и должна выполняться конкатенация, но конкатенация не выполняется. Кажется, что фильтры устанавливаются последовательно! Кто-нибудь имеет представление о том, что происходит в этом выводе? Он действует так же, как описанный в документе?

Для сравнения я нашел реализацию keras InceptionV4, и они, похоже, выполняют filter_concat concatenate_1 для первой конкатенации в STEM-блоке. Вот выходные данные первых строк summary() .

 Model: "inception_v4"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to
==================================================================================================
input_1 (InputLayer)            (None, 512, 512, 3)  0
__________________________________________________________________________________________________
conv2d_1 (Conv2D)               (None, 255, 255, 32) 864         input_1[0][0]
__________________________________________________________________________________________________
batch_normalization_1 (BatchNor (None, 255, 255, 32) 96          conv2d_1[0][0]
__________________________________________________________________________________________________
activation_1 (Activation)       (None, 255, 255, 32) 0           batch_normalization_1[0][0]
__________________________________________________________________________________________________
conv2d_2 (Conv2D)               (None, 253, 253, 32) 9216        activation_1[0][0]
__________________________________________________________________________________________________
batch_normalization_2 (BatchNor (None, 253, 253, 32) 96          conv2d_2[0][0]
__________________________________________________________________________________________________
activation_2 (Activation)       (None, 253, 253, 32) 0           batch_normalization_2[0][0]
__________________________________________________________________________________________________
conv2d_3 (Conv2D)               (None, 253, 253, 64) 18432       activation_2[0][0]
__________________________________________________________________________________________________
batch_normalization_3 (BatchNor (None, 253, 253, 64) 192         conv2d_3[0][0]
__________________________________________________________________________________________________
activation_3 (Activation)       (None, 253, 253, 64) 0           batch_normalization_3[0][0]
__________________________________________________________________________________________________
conv2d_4 (Conv2D)               (None, 126, 126, 96) 55296       activation_3[0][0]
__________________________________________________________________________________________________
batch_normalization_4 (BatchNor (None, 126, 126, 96) 288         conv2d_4[0][0]
__________________________________________________________________________________________________
max_pooling2d_1 (MaxPooling2D)  (None, 126, 126, 64) 0           activation_3[0][0]
__________________________________________________________________________________________________
activation_4 (Activation)       (None, 126, 126, 96) 0           batch_normalization_4[0][0]
__________________________________________________________________________________________________
concatenate_1 (Concatenate)     (None, 126, 126, 160 0           max_pooling2d_1[0][0]
                                                                 activation_4[0][0]
__________________________________________________________________________________________________
conv2d_7 (Conv2D)               (None, 126, 126, 64) 10240       concatenate_1[0][0]
__________________________________________________________________________________________________
batch_normalization_7 (BatchNor (None, 126, 126, 64) 192         conv2d_7[0][0]
__________________________________________________________________________________________________
activation_7 (Activation)       (None, 126, 126, 64) 0           batch_normalization_7[0][0]
__________________________________________________________________________________________________
conv2d_8 (Conv2D)               (None, 126, 126, 64) 28672       activation_7[0][0]
__________________________________________________________________________________________________
.
.
.
and many more lines
  

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

РЕДАКТИРОВАТЬ: я обнаружил, что реализация InceptionResnetV2 из Keras не следует за базовым блоком для InceptionResnetV2, а вместо этого реализует InceptionResnetV1 (рисунок 14 из их статьи, прилагаемый ниже). После базового блока он, похоже, хорошо следует за другими блоками InceptionResnetV2.

InceptionResnetV1 работает не так хорошо, как InceptionResnetV2 (рисунок 25), поэтому я скептически отношусь к использованию блоков из V1 вместо полного V2 из keras. Я попытаюсь вырезать стержень из InceptionV4, который я нашел, и поместить продолжение InceptionResnetV2.

Тот же вопрос был закрыт без объяснения причин в tf-models github. Я оставляю это здесь, если кому-то интересно: https://github.com/tensorflow/models/issues/1235

РЕДАКТИРОВАТЬ 2: По какой-то причине GoogleAI (создатели Inception architecture) показывают изображение в своем блоге, когда они выпустили код «inception-resnet-v2». Но STEM-блок — это блок из InceptionV3, а не InceptionV4, как указано в документе. Итак, либо статья неверна, либо код по какой-то причине не соответствует статье.

Рисунок 3 оригинальной статьи. Схема для stem сетей Pure Inception-v4 и Inception-ResNet-v2. [...]

Рисунок 14 оригинальной статьи. Основа сети InceptionResnetV2 ResNet-v1.

Рисунок 25. Топ-5 ошибок всех четырех моделей (одна модель, один кадр). Показаны улучшения из-за увеличения размера модели.Хотя остаточная версия сходится быстрее, конечная точность, по-видимому, в основном зависит от размера модели

Ответ №1:

Он достигает аналогичных результатов.

Я только что получил электронное письмо с подтверждением ошибки от Алекса Алеми, старшего научного сотрудника Google и первоначального издателя сообщения в блоге о выпуске кода для InceptionResnetV2. Похоже, что во время внутренних экспериментов блоки STEM были переключены, и релиз просто остался таким.

Цитировать:

Дани Аземар,

Похоже, вы правы. Не совсем уверен, что произошло, но код, очевидно, является источником истины в том смысле, что выпущенная контрольная точка предназначена для кода, который также выпущен. Когда мы разрабатывали архитектуру, мы провели целый ряд внутренних экспериментов, и я полагаю, что в какой-то момент основы были переключены. Не уверен, что у меня есть время копать глубже в данный момент, но, как я уже сказал, выпущенная контрольная точка является контрольной точкой для выпущенного кода, поскольку вы можете убедиться сами, запустив конвейер оценки. Я согласен с вами, что похоже, что здесь используется оригинальный stem Inception V1. С наилучшими пожеланиями,

Алекс Алеми

Я обновлю этот пост с изменениями, касающимися этой темы.

ОБНОВЛЕНИЕ: Кристиан Сегеди, также издатель оригинальной статьи, только что написал мне в твиттере:

Оригинальные эксперименты и модель были созданы в DistBelief, совершенно другой структуре, предшествующей Tensorflow.

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

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