Входной слой Keras Sequential Dense - и MNIST: почему изображения должны быть изменены? - PullRequest
0 голосов
/ 05 сентября 2018

Я спрашиваю об этом, потому что чувствую, что упускаю что-то фундаментальное.

В настоящее время большинство знает, что изображения MNIST имеют размер 28X28 пикселей. Документация keras говорит мне о Dense:

Входной тензор nD формы с формой: (batch_size, ..., input_dim). Наиболее распространенная ситуация - это двумерный ввод с формой (batch_size, input_dim).

Таким образом, такой новичок, как я, предположил бы, что изображения можно подавать на модель в виде матрицы 28 * 28. Тем не менее, каждый учебник, который я нашел, проходит через различные гимнастики, чтобы преобразовать изображения в одну функцию длиной 784 *.

Иногда

num_pixels = X_train.shape[1] * X_train.shape[2]
model.add(Dense(num_pixels, input_dim=num_pixels, activation='...'))

или

num_pixels = np.prod(X_train.shape[1:])
model.add(Dense(512, activation='...', input_shape=(num_pixels,)))

или

model.add(Dense(units=10, input_dim=28*28, activation='...'))
history = model.fit(X_train.reshape((-1,28*28)), ...)

или даже:

model = Sequential([Dense(32, input_shape=(784,)), ...),])

Так что мой вопрос просто - почему? Разве Dense не может просто принять изображение как есть или, если необходимо, просто обработать его «за кадром», как это было? И если, как я подозреваю, эта обработка должна быть выполнена, является ли какой-либо из этих (или других) по своей природе предпочтительным?

1 Ответ

0 голосов
/ 05 сентября 2018

В соответствии с просьбой ОП (то есть оригинального плаката), я упомяну ответ, который я дал в своем комментарии, и уточню подробнее.

Can't Dense, просто принять изображение как есть или, если необходимо, просто обработать это как бы "за кадром"?

Просто нет! Это потому, что в настоящее время плотный слой наносится на последнюю ось . Следовательно, если вы передадите ему изображение формы (height, width) или (height, width, channels), плотный слой будет применен только к последней оси (то есть к ширине или каналам). Однако, когда изображение сглажено, все единицы в слое «Плотность» будут применены ко всему изображению, и каждая единица будет подключена ко всем пикселям с разным весом. Для дальнейшего уточнения рассмотрим эту модель:

model = models.Sequential()
model.add(layers.Dense(10, input_shape=(28*28,)))
model.summary()

Краткое описание модели:

Layer (type)                 Output Shape              Param #   
=================================================================
dense_2 (Dense)              (None, 10)                7850      
=================================================================
Total params: 7,850
Trainable params: 7,850
Non-trainable params: 0
_________________________________________________________________

Как видите, в плотном слое 7850 параметров: каждый блок связан со всеми пикселями (28 * 28 * 10 + 10 параметров смещения = 7850). Теперь рассмотрим эту модель:

model = models.Sequential()
model.add(layers.Dense(10, input_shape=(28,28)))
model.summary()

Сводка модели:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_3 (Dense)              (None, 28, 10)            290       
=================================================================
Total params: 290
Trainable params: 290
Non-trainable params: 0
_________________________________________________________________

В этом случае в плотном слое есть только 290 параметров. Здесь каждая единица в плотном слое также подключена ко всем пикселям, но разница в том, что веса распределяются по первой оси (28 * 10 + 10 параметров смещения = 290). Похоже, что элементы извлекаются из каждой строки изображения по сравнению с предыдущей моделью, которая извлекала элементы по всему изображению. И поэтому это (т.е. распределение веса) может или не может быть полезным для вашего приложения.

...