TimeseriesGenerator и DenseLayer - Keras / Tensorflow - PullRequest
0 голосов
/ 08 января 2020

У меня есть некоторые проблемы с измерениями, когда я использую DenseLayer в сочетании с TimeseriesGenerator.

Мои данные тренировок выглядят так:

X = (1 000 000, 6)

y = (1 000 000, 2)

Я поместил все это в TimeseriesGenerator:

train_gen = TimeseriesGenerator(X, y, length=4, batch_size=32, stride=1)

, и я получил:

train_gen[0][0].shape
(32, 4, 6)

train_gen[0][1].shape
(32, 2)

Впоследствии я создал простую модель:

optimizer = keras.optimizers.RMSprop()

model = Sequential()
model.add(Dense(12, input_shape=(4,6), activation='tanh'))
model.add(Dense(40, activation='tanh'))
model.add(Dense(2, activation='tanh'))

model.compile(loss='mean_absolute_error', optimizer= optimizer, metrics=['mean_absolute_error', 'accuracy'])

и последний шаг «примерка»:

mw = model.fit_generator(generator=train_gen, epochs=1, verbose=1)

Теперь я получаю ошибку. Последний слой имеет проблему измерения:

InvalidArgumentError: Incompatible shapes: [32,4,2] vs. [32,2] [Op:Sub] name: loss/dense_44_loss/sub/

Я полагаю, что модель хочет сравнить [32,4,2] размерный вывод модели с данными [32,2] размерных тренингов.

Я пока не нашел решения. Я думаю, что я определенно нуждаюсь в TimeseriesGenerator из-за моего исходного набора данных, который имеет 160 миллиардов выборок, и у меня недостаточно ОЗУ;) Кто-нибудь может мне помочь?

Ответы [ 2 ]

1 голос
/ 08 января 2020

Ваш последний слой имеет ошибку размерности, которую вы можете просто исправить, добавив слой Flatten () следующим образом:

import numpy as np
from keras.preprocessing.sequence import TimeseriesGenerator
from keras.models import Sequential
from keras.layers import Dense, Flatten
from keras.optimizers import RMSprop

X = np.random.rand(996, 6)
y = np.random.rand(996, 2)

t_gen = TimeseriesGenerator(X, y, length=4, batch_size=32, stride=1)

optimizer = RMSprop()

model = Sequential()
model.add(Dense(12, input_shape=(4,6), activation='tanh'))
model.add(Dense(40, activation='tanh'))
model.add(Flatten())
model.add(Dense(2, activation='tanh'))

model.compile(loss='mean_absolute_error', 
    optimizer= optimizer, 
    metrics=['mean_absolute_error', 'accuracy'])


mw = model.fit_generator(generator=t_gen, epochs=1, verbose=1)

Результат будет таким:

Epoch 1/1
31/31 [==============================] - 0s 12ms/step - loss: 0.2817 - mean_absolute_error: 0.2817 - accuracy: 0.4748

Ваша новая модель выглядит так:

enter image description here

0 голосов
/ 08 января 2020

Обычно TimeseriesGenerator используется для создания 3D-данных для приложений временных рядов, а затем вы используете LSTM для обработки этих 3D-данных.

Вы все еще можете использовать TimeseriesGenerator вместе со Dense слоями с некоторыми хаки.

Измените length из TimeseriesGenerator на 1.

train_gen = TimeseriesGenerator(X, y, length=1, batch_size=32, stride=1)
#shapes : train_gen[0][0] : (32,1,6)

Теперь ваши данные по сути являются двумерными данными, а это среднее измерение просто бесполезно. Так что просто создайте Lambda layer, который отбрасывает это среднее измерение в вашей модели как первый слой.

import keras.backend as K
from keras.layers import Lambda


optimizer = keras.optimizers.RMSprop()

model = Sequential()
model.add(Lambda(lambda inp: K.squeeze(inp, axis=1),input_shape=(1,6)))
model.add(Dense(12, activation='tanh'))
model.add(Dense(40, activation='tanh'))
model.add(Dense(2, activation='tanh'))
model.compile(loss='mean_absolute_error', optimizer= optimizer, metrics=['mean_absolute_error', 'accuracy'])

print(model.output_shape) #(None,2)

Выходная форма вашей модели должна соответствовать форме ваших ярлыков.

mw = model.fit_generator(generator=train_gen, epochs=1, verbose=1) #runs
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...