#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, как указано в документе. Итак, либо статья неверна, либо код по какой-то причине не соответствует статье.
Ответ №1:
Он достигает аналогичных результатов.
Я только что получил электронное письмо с подтверждением ошибки от Алекса Алеми, старшего научного сотрудника Google и первоначального издателя сообщения в блоге о выпуске кода для InceptionResnetV2. Похоже, что во время внутренних экспериментов блоки STEM были переключены, и релиз просто остался таким.
Цитировать:
Дани Аземар,
Похоже, вы правы. Не совсем уверен, что произошло, но код, очевидно, является источником истины в том смысле, что выпущенная контрольная точка предназначена для кода, который также выпущен. Когда мы разрабатывали архитектуру, мы провели целый ряд внутренних экспериментов, и я полагаю, что в какой-то момент основы были переключены. Не уверен, что у меня есть время копать глубже в данный момент, но, как я уже сказал, выпущенная контрольная точка является контрольной точкой для выпущенного кода, поскольку вы можете убедиться сами, запустив конвейер оценки. Я согласен с вами, что похоже, что здесь используется оригинальный stem Inception V1. С наилучшими пожеланиями,
Алекс Алеми
Я обновлю этот пост с изменениями, касающимися этой темы.
ОБНОВЛЕНИЕ: Кристиан Сегеди, также издатель оригинальной статьи, только что написал мне в твиттере:
Оригинальные эксперименты и модель были созданы в DistBelief, совершенно другой структуре, предшествующей Tensorflow.
Версия TF была добавлена годом позже и, возможно, имела расхождения с исходной моделью, однако она была уверена в достижении аналогичных результатов.
Итак, поскольку он дает аналогичные результаты, ваши эксперименты будут примерно такими же.