Я пытаюсь понять роль Flatten
функции в Керасе. Ниже мой код, который представляет собой простую двухуровневую сеть. Он принимает двумерные данные формы (3, 2) и выводит одномерные данные формы (1, 4):
model = Sequential()
model.add(Dense(16, input_shape=(3, 2)))
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(4))
model.compile(loss='mean_squared_error', optimizer='SGD')
x = np.array([[[1, 2], [3, 4], [5, 6]]])
y = model.predict(x)
print y.shape
Это распечатает, что y
имеет форму (1, 4). Однако, если я удалю Flatten
линию, она распечатает y
форму (1, 3, 4).
Я этого не понимаю. Насколько я понимаю нейронные сети, model.add(Dense(16, input_shape=(3, 2)))
функция создает скрытый полносвязный слой с 16 узлами. Каждый из этих узлов подключен к каждому из входных элементов 3x2. Следовательно, 16 узлов на выходе этого первого слоя уже являются «плоскими». Итак, форма вывода первого слоя должна быть (1, 16). Затем второй уровень принимает это как входные данные и выводит данные формы (1, 4).
Итак, если результат первого слоя уже «плоский» и имеет форму (1, 16), зачем мне его еще больше сглаживать?
Dense(16, input_shape=(5,3)
будет ли каждый выходной нейрон из набора из 16 (и для всех 5 наборов этих нейронов) соединяться со всеми (3 x 5 = 15) входными нейронами? Или каждый нейрон в первом наборе из 16 будет связан только с 3 нейронами в первом наборе из 5 входных нейронов, а затем каждый нейрон во втором наборе из 16 будет подключен только к 3 нейронам во втором наборе из 5 входов. нейроны и т.д .... Я не понимаю, что это такое!input_shape=(5,3)
означает, что есть 5 пикселей, и каждый пиксель имеет три канала (R, G, B). Но согласно тому, что вы говорите, каждый канал будет обрабатываться индивидуально, тогда как я хочу, чтобы все три канала обрабатывались всеми нейронами первого слоя. Так может ли нанесениеFlatten
слоя сразу в начале дать мне то, что я хочу?Flatten
может помочь понять.Вот как работает Flatten, преобразуя матрицу в единый массив.
источник
краткое чтение:
долгое чтение:
Если мы возьмем исходную модель (со слоем Flatten), созданную, мы можем получить следующую сводку модели:
Надеюсь, что для этого резюме следующее изображение даст немного больше смысла о размерах ввода и вывода для каждого слоя.
Форма вывода для слоя Flatten, как вы можете прочитать, выглядит так
(None, 48)
. Вот подсказка. Вы должны это прочитать(1, 48)
или(2, 48)
или ... или(16, 48)
... или(32, 48)
, ...Фактически
None
на этой позиции подразумевается любой размер партии. Чтобы вспомнить входные данные, первое измерение означает размер партии, а второе - количество входных функций.Роль слоя Flatten в Keras очень проста:
Операция сглаживания тензора изменяет форму тензора, чтобы он имел форму, равную количеству элементов, содержащихся в тензоре, без учета размера партии .
Примечание: я использовал этот
model.summary()
метод, чтобы предоставить информацию о форме вывода и параметрах.источник
Flatten явно укажет, как вы сериализуете многомерный тензор (типично входной). Это позволяет сопоставить (сглаженный) входной тензор и первый скрытый слой. Если первый скрытый слой "плотный", каждый элемент (сериализованного) входного тензора будет связан с каждым элементом скрытого массива. Если вы не используете Flatten, способ сопоставления входного тензора с первым скрытым слоем будет неоднозначным.
источник
Я недавно столкнулся с этим, это, безусловно, помогло мне понять: https://www.cs.ryerson.ca/~aharley/vis/conv/
Итак, есть вход, Conv2D, MaxPooling2D и т. Д., Слои Flatten находятся в конце и показывают, как именно они сформированы и как они продолжают определять окончательные классификации (0-9).
источник