Давайте дополним вашу модель плотным слоем со 128 единицами и посмотрим сводку для двух моделей.
Conv Model
from tensorflow.keras.layers import *
from tensorflow.keras.models import Model, Sequential
n_features = 1000 # your sequence length
model = Sequential()
model.add(Conv1D(128, kernel_size=1, activation="relu", input_shape=(n_features,1)))
model.add(Flatten())
model.add(Dense(100, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(1, activation='linear'))
model.summary()
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv1d_1 (Conv1D) (None, 1000, 128) 256
_________________________________________________________________
flatten_1 (Flatten) (None, 128000) 0
_________________________________________________________________
dense_8 (Dense) (None, 100) 12800100
_________________________________________________________________
dense_9 (Dense) (None, 1) 101
=================================================================
Total params: 12,800,457
Trainable params: 12,800,457
Non-trainable params: 0
F C Модель
from tensorflow.keras.layers import *
from tensorflow.keras.models import Model, Sequential
n_features = 1000 # your sequence length
model = Sequential()
model.add(Dense(128, activation="relu", input_shape=(n_features,1)))
model.add(Flatten())
model.add(Dense(100, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(1, activation='linear'))
model.summary()
Model: "sequential_2"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_10 (Dense) (None, 1000, 128) 256
_________________________________________________________________
flatten_2 (Flatten) (None, 128000) 0
_________________________________________________________________
dense_11 (Dense) (None, 100) 12800100
_________________________________________________________________
dense_12 (Dense) (None, 1) 101
=================================================================
Total params: 12,800,457
Trainable params: 12,800,457
Non-trainable params: 0
_____________________________
Как видите, обе модели имеют одинаковое количество параметров в каждом слое. Но по сути они совершенно разные.
![enter image description here](https://i.stack.imgur.com/2NKtS.png)
Допустим, у нас есть входы только длиной 4. 1 свертка с 3 фильтрами будет использовать 3 отдельных ядра на этих 4 входах, каждое ядро будет работать с одним элементом ввода за раз, так как мы выбрали kernel_size = 1. Таким образом, каждое ядро - это всего лишь одно скалярное значение, которое будет умножается на входной массив по одному элементу за раз (смещение будет добавлено). Дело в том, что свёртка 1 нигде не выглядит, кроме текущего ввода, означающего , она не имеет пространственной свободы, она только смотрит на текущую точку ввода за раз. (это станет полезным для дальнейшего использования объяснение)
Теперь с плотным слоем / f c каждый нейрон подключен к каждому входу, то есть слой f c имеет полную пространственную свободу, он выглядит везде. Эквивалентным слоем Conv будет что-то с kernel_size = 1000 (фактическая длина ввода).
Итак, почему свертка Conv1D 1 может работать лучше?
- Ну, это трудно сказать, не изучая свойства данных. Но можно предположить, что вы используете объекты, которые не имеют пространственной зависимости.
Вы выбрали объекты случайным образом и, вероятно, смешали их (просмотр сразу нескольких входных объектов не помогает но узнает немного лишнего шума). Это может быть причиной того, что вы получаете лучшую производительность со слоем Conv, который просматривает только один объект за раз, вместо слоя F C, который просматривает все их и смешивает их.