Выполнение прогноза с RNN на последовательных данных в кератах - PullRequest
6 голосов
/ 29 февраля 2020

Я новичок в ML, и я следовал этому учебнику , который учит, как делать предсказания криптовалюты на основе некоторых фьючерсов.

Мой код для прогнозирования:

model = load_model("Path//myModel.model")

ready_x = preprocess_df(main_df) # the function returns array of price sequences and targets (0-buy,1-sells): return np.array(X), y 
predictions = []

for x in ready_x:
 l_p = model.predict_classes(x) #error occurs on this line
 predictions.append(l_p[0])
plot_prediction(main_df, predictions)

Но я получил следующую ошибку:

ValueError: Ошибка при проверке ввода: ожидается, что lstm_input имеет 3 размеры, но получил массив с формой (69188, 1)

Я действительно не понимаю эту ошибку, это буквально мой второй проект по ML после классификации известных кошек и собак. Так что у меня нет большого опыта в отладке, я сначала изучил теорию о нейронах и отношениях между ними, но все же действительно трудно применить эти знания в реальном проекте. Таким образом, идея этого проекта состоит в том, чтобы предсказать будущую цену на 3 минуты в будущем, основываясь на последних 60-минутных ценах (обученных этому).
Модель выглядит следующим образом:

model = Sequential()
model.add(LSTM(128, input_shape=(train_x.shape[1:]),return_sequences=True))
model.add(Dropout(0.2))
model.add(BatchNormalization())

model.add(LSTM(128, return_sequences=True))
model.add(Dropout(0.1))
model.add(BatchNormalization())

model.add(LSTM(128))
model.add(Dropout(0.2))
model.add(BatchNormalization())

model.add(Dense(32, activation="relu"))
model.add(Dropout(0.2))

model.add(Dense(2, activation="softmax"))

opt = tf.keras.optimizers.Adam(lr=0.001, decay=1e-6)  

model.summary()

main_df - это фрейм данных и состоит из:

enter image description here
Мой вопрос, как я я должен кормить модель с правильным вводом данных, чтобы сделать этот прогноз?

РЕДАКТИРОВАТЬ:
preprocess Функция:

def preprocess_df(df):
    #scalling
    df = df.drop('future', 1)

    for col in df.columns:
        if col!= "target":
            df[col] = df[col].pct_change() # normalizes the data
            df.dropna(inplace=True)
            df[col] = preprocessing.scale(df[col].values) #scale the data between 0-1

    df.dropna(inplace=True)

    sequential_data = []
    prev_days = deque(maxlen=SEQ_LEN)

    for i in df.values:
        prev_days.append([n for n in i[:-1]]) # append each column and not taking a target
        if len(prev_days) == SEQ_LEN:
            sequential_data.append([np.array(prev_days), i[-1]])

    random.shuffle(sequential_data)

    # BALANCING THE DATA
    buys = []
    sells = []

    for seq, target in sequential_data:
        if target == 0:
            sells.append([seq, target])
        elif target == 1:
            buys.append([seq, target])

    random.shuffle(buys)
    random.shuffle(sells)

    lower = min(len(buys), len(sells))

    buys = buys[:lower]
    sells = sells[:lower]

    sequential_data = buys + sells
    random.shuffle(sequential_data)

    X = []
    y = []

    for seq, target in sequential_data:
        X.append(seq)
        y.append(target)

    return np.array(X), y

1 Ответ

5 голосов
/ 03 марта 2020

LSTM ожидает входные данные в форме (batch_size, timesteps, channels); в вашем случае timesteps=60 и channels=128. batch_size - это количество выборок, которые вы подаете за один подход / прогноз.

Ваша ошибка указывает на предварительную обработку fl aws:

  • Строки вашего фрейма данных на основе имя индекса time, заполняет dim 1 из x -> timesteps
  • Обычно столбцы являются элементами, и заполняет dim 2 из x -> channels
  • dim 0 - размерность выборки; «образец» является независимым наблюдением - в зависимости от того, как отформатированы ваши данные, один файл может быть одним образцом или содержать несколько

После учета выше:

  • print(x.shape) должно читаться (N, 60, 128), где N - количество сэмплов, >= 1
  • Поскольку вы выполняете итерацию по ready_x, x будет срезать ready_x вдоль его dim 0 - так print(ready_x.shape) должно читаться (M, N, 60, 128), где M >= 1; это «пакетное» измерение, каждый срез - 1 партия.

В качестве базовой c отладки: вставьте print(item.shape) во весь код предварительной обработки, где item - массив, DataFrame, et c. - чтобы увидеть, как формы меняются на разных этапах. Убедитесь, что есть шаг, который дает 128 для последнего измерения и 60 для второго до последнего.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...