Автофильтр для временных рядов в Python / Keras с использованием Conv1d - PullRequest
3 голосов
/ 24 мая 2019

Может выглядеть много кода, но большая часть кода - комментарии или форматирование, чтобы сделать его более читабельным.

Дано:
Если я определю свою переменную интереса, «последовательность», следующим образом:

# define input sequence
np.random.seed(988) 

#make numbers 1 to 100
sequence = np.arange(0,10, dtype=np.float16)

#shuffle the numbers
sequence = sequence[np.random.permutation(len(sequence))]

#augment the sequence with itself
sequence = np.tile(sequence,[15]).flatten().transpose()

#scale for Relu
sequence = (sequence - sequence.min()) / (sequence.max()-sequence.min())

sequence

# reshape input into [samples, timesteps, features]
n_in = len(sequence)
sequence = sequence.reshape((1, n_in, 1))

Вопрос:
Как использовать conv1d в автоэнкодере в Keras, чтобы оценить эту последовательность с разумным уровнем точности?

Если conv1d не подходит для этой проблемы, вы можете сказать мне, какой может быть более подходящий тип слоя для кодера-декодера?

Дополнительная информация:
Очки о данных:

  • это повторяющаяся последовательность из 10 различных значений
  • единственное отставание в 10 шагов должно идеально предсказать последовательность
  • словарь из 10 элементов должен давать "предсказывать следующее, данное"

Я пытался предсказать другие слои частей кодера и декодера (LSTM, Dense, многослойная плотность), и они продолжали сталкиваться с "стеной" около mse 0,0833 ... что представляет собой дисперсию равномерного распределения в диапазоне между 0 и 1. Для меня хороший автоэнкодер в этой простой задаче должен иметь точность не менее 99,9%, поэтому значение mse значительно ниже 1%.

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

Ссылки:

1 Ответ

5 голосов
/ 07 июня 2019

Создав набор данных из 1000 выборок, используя ваш метод, я смог получить довольно хорошую модель автоэнкодера, используя Conv1d:

LEN_SEQ = 10

x = Input(shape=(n_in, 1), name="input")
h = Conv1D(filters=50, kernel_size=LEN_SEQ, activation="relu", padding='same', name='Conv1')(x)
h = MaxPooling1D(pool_size=2, name='Maxpool1')(h)
h = Conv1D(filters=150, kernel_size=LEN_SEQ, activation="relu", padding='same', name='Conv2')(h)
h = MaxPooling1D(pool_size=2,  name="Maxpool2")(h)
y = Conv1D(filters=150, kernel_size=LEN_SEQ, activation="relu", padding='same', name='conv-decode1')(h)
y = UpSampling1D(size=2, name='upsampling1')(y)
y = Conv1D(filters=50, kernel_size=LEN_SEQ, activation="relu", padding='same', name='conv-decode2')(y)
y = UpSampling1D(size=2, name='upsampling2')(y)
y = Conv1D(filters=1, kernel_size=LEN_SEQ, activation="relu", padding='same', name='conv-decode3')(y)

AutoEncoder = Model(inputs=x, outputs=y, name='AutoEncoder')

AutoEncoder.compile(optimizer='adadelta', loss='mse')

AutoEncoder.fit(sequence, sequence, batch_size=32, epochs=50)

Вывод последней эпохи:

Epoch 50/50
1000/1000 [==============================] - 4s 4ms/step - loss: 0.0104

Тест нановые данные:

array([[[0.5557],
        [0.8887],
        [0.778 ],
        [0.    ],
        [0.4443],
        [1.    ],
        [0.3333],
        [0.2222],
        [0.1111],
        [0.6665],
        [...]

Прогнозы:

array([[[0.56822747],
        [0.8906583 ],
        [0.89267206],
        [0.        ],
        [0.5023574 ],
        [1.0665314 ],
        [0.37099048],
        [0.28558862],
        [0.05782872],
        [0.6886021 ],
        [...]

Некоторые проблемы с округлением, но довольно близко!

Это то, что вы искали?

...