Подтвердить что ты не робот

Почему я получаю ошибку KERS LSTM RNN input_shape?

Я продолжаю получать ошибку input_shape из следующего кода.

from keras.models import Sequential
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.recurrent import LSTM

def _load_data(data):
    """
    data should be pd.DataFrame()
    """
    n_prev = 10
    docX, docY = [], []
    for i in range(len(data)-n_prev):
        docX.append(data.iloc[i:i+n_prev].as_matrix())
        docY.append(data.iloc[i+n_prev].as_matrix())
    if not docX:
        pass
    else:
        alsX = np.array(docX)
        alsY = np.array(docY)
        return alsX, alsY

X, y = _load_data(dframe)
poi = int(len(X) * .8)
X_train = X[:poi]
X_test = X[poi:]
y_train = y[:poi]
y_test = y[poi:]

input_dim = 3

Все вышеперечисленное работает плавно. Здесь все идет не так.

in_out_neurons = 2
hidden_neurons = 300
model = Sequential()
#model.add(Masking(mask_value=0, input_shape=(input_dim,)))
model.add(LSTM(in_out_neurons, hidden_neurons, return_sequences=False, input_shape=(len(full_data),)))
model.add(Dense(hidden_neurons, in_out_neurons))
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")
model.fit(X_train, y_train, nb_epoch=10, validation_split=0.05)

Он возвращает эту ошибку.

Exception: Invalid input shape - Layer expects input ndim=3, was provided with input shape (None, 10320)

Когда я проверяю веб-сайт, он говорит, чтобы указать кортеж" (например, (100) для 100-мерных входов).

Как сказано, мой набор данных состоит из одного столбца с длиной 10320. Я предполагаю, что это означает, что я должен помещать (10320,) в качестве input_shape, но я все равно получаю ошибку. У кого-нибудь есть решение?

4b9b3361

Ответ 1

Мое понимание заключается в том, что и ваш вход, и ваш выход - это одномерные векторы. Хитрость заключается в том, чтобы изменить их в соответствии с требованиями Keras:

from keras.models import Sequential
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.recurrent import LSTM
import numpy as np

X= np.random.rand(1000)
y = 2*X

poi = int(len(X) * .8)
X_train = X[:poi]
y_train = y[:poi]

X_test = X[poi:]
y_test = y[poi:]

# you have to change your input shape (nb_samples, timesteps, input_dim)
X_train = X_train.reshape(len(X_train), 1, 1)
# and also the output shape (note that the output *shape* is 2 dimensional)
y_train = y_train.reshape(len(y_train), 1)


#in_out_neurons = 2 
in_out_neurons = 1

hidden_neurons = 300
model = Sequential()
#model.add(Masking(mask_value=0, input_shape=(input_dim,)))
model.add(LSTM(hidden_neurons, return_sequences=False, batch_input_shape=X_train.shape))
# only specify the output dimension
model.add(Dense(in_out_neurons))
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")
model.fit(X_train, y_train, nb_epoch=10, validation_split=0.05)

# calculate test set MSE
preds = model.predict(X_test).reshape(len(y_test))
MSE = np.mean((preds-y_test)**2)

Вот ключевые моменты:

  • При добавлении первого слоя вам необходимо указать количество скрытых узлов и форму ввода. Последующие слои не требуют ввода формы, поскольку они могут вывести ее из скрытых узлов предыдущего слоя.
  • Аналогично, для вашего выходного уровня вы указываете только количество выходных узлов

Надеюсь, что это поможет.

Ответ 2

Дополнительная информация: при использовании RNN (например, LSTM) с последовательностями переменной длины вам нужно взять формат ваших данных.

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

Существует несколько возможных решений:

  • тренируйте свою сеть с использованием выборок один за другим (например, с помощью fit_generator)
  • выполните все ваши последовательности, чтобы они имели одинаковый размер.
  • группировать последовательности по размеру (в конечном счете, дополнять их) и обучать вашу сетевую группу по группам (снова используя подгонку на основе генератора)

Третье решение соответствует самой общей стратегии с переменным размером. И если вы набиваете последовательности (второе или третье решение), вы можете добавить слой маскирования в качестве входных данных.

Если вы не уверены, попробуйте распечатать форму ваших данных (используя атрибут shape массива numpy.)

Вам может потребоваться посмотреть: https://keras.io/preprocessing/sequence/ (pad_sequences) и https://keras.io/layers/core/#masking

Ответ 3

Попробуйте использовать слой LSTM без указания формы ввода. Пусть Keras сделает для вас работу. Я думаю, вы тоже прокомментировали маскировку, потому что у вас такая же проблема. Я столкнулся с этим раньше, и оказывается, что input_shape = (time_steps, input_dim). Я думаю, что это происходит из-за нового автоматического вывода формы в Keras.

Ответ 4

Ниже приведена рабочая версия с Keras 2.0.0, измененным кодом счисления

from keras.models import Sequential
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.recurrent import LSTM
import numpy as np

X= np.random.rand(1000)
y = 2 * X

poi = int(len(X) * .8)
X_train = X[:poi]
y_train = y[:poi]

X_test = X[poi:]
y_test = y[poi:]

# you have to change your input shape (nb_samples, timesteps, input_dim)
X_train = X_train.reshape(len(X_train), 1, 1)
# and also the output shape (note that the output *shape* is 2 dimensional)
y_train = y_train.reshape(len(y_train), 1)

# Change test data dimension also.
X_test = X_test.reshape(len(X_test),1,1)
y_test = y_test.reshape(len(y_test),1)


#in_out_neurons = 2
in_out_neurons = 1

hidden_neurons = 300
model = Sequential()
# model.add(Masking(mask_value=0, input_shape=(input_dim,)))
# Remove batch_input_shape and add input_shape = (1,1) - Imp change for Keras 2.0.0
model.add(LSTM(hidden_neurons, return_sequences=False, input_shape=(X_train.shape[1],X_train.shape[2])))
# only specify the output dimension
model.add(Dense(in_out_neurons))
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")
model.summary()
model.fit(X_train, y_train, epochs=10, validation_split=0.05)

# calculate test set MSE
preds = model.predict(X_test).reshape(len(y_test))
print(preds)
MSE = np.mean((preds-y_test)**2)
print('MSE ', MSE)