RNN, Keras, Python: нормализация данных Min Max Scaler. ValueError: найден массив с dim 3. Ожидается оценка <= 2 - PullRequest
1 голос
/ 18 июня 2020

Я подготовил простой набор данных и набор этикеток. Я хочу узнать, как реализовать простой RNN в Keras. Я подготовил свои данные. Когда я не использую нормализацию (MinMaxScaler), все компилируется без ошибок.

Однако, когда я пытаюсь использовать скейлер, я получал ValueError: Found array with dim 3. Estimator expected <= 2.. Это код:

# -*- coding: utf-8 -*- 
#!/usr/bin/env python3

import tensorflow as tf
from tensorflow import keras

from keras.models import Sequential
from keras.layers import Dense, SimpleRNN 
from keras.callbacks import ModelCheckpoint
from keras import backend as K

from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split


import numpy 
import matplotlib.pyplot as plt

def stagger(a, delay):
    num_of_rows = a.shape[0]  
    num_of_cols = a.shape[1] 
    data_in = numpy.zeros((num_of_rows + delay, num_of_cols * (1 + delay)))
    data_in[0:num_of_rows, 0:4] = a
    data_in[1:(num_of_rows + 1), 4:8] = a
    a = data_in[0:num_of_rows, :]
    return a

dataset = numpy.array([[0,   2,   0, 324],  [1, 2, 0,324],  [2, 2, 0, 324],  [3, 2, 0, 324], [4, 2, 0, 324],  [5, 2, 0, 324], [6, 2, 0, 324], 
                    [7, 2, 0, 324], [8, 2, 0, 324], [9, 2, 0, 324], [ 10, 2, 0, 324], [ 11, 2, 0, 324], [ 12, 2, 0, 324], [ 13, 2, 0, 324],
                    [ 14, 2, 0, 324], [ 15, 2, 0, 324], [ 16, 2, 0, 324], [ 17, 2, 0, 324],[ 18, 2, 0, 324], [ 19, 2, 0, 324], [ 20, 2, 0, 324],
                    [ 21, 2, 0, 324],[ 22, 2, 0, 324], [ 23, 2, 0, 324]])

labels = numpy.array([[0.82174763], [0.62098727], [0.45012733], [1.5912102 ],
                  [0.37570953], [0.2930966 ], [0.34982923], [0.72239097],
                  [1.37881947], [1.79550653], [1.88867237], [1.93567087],
                  [1.9771925 ], [2.10873853], [2.158302  ], [2.11018633],
                  [1.9714166 ], [2.2553416 ], [2.41161887], [2.41161887],
                  [2.30333453], [2.38390613], [2.21882553], [2.0707972 ]])

delay = 2
input_shape = (1, 4*(1+delay))
min_max_scaler = MinMaxScaler(feature_range=(0, 1))

# prepare dataset
dataset = stagger(dataset, delay)

# split dataset
x_train, x_test, y_train, y_test = train_test_split(dataset, labels, test_size=0.2, shuffle=False)
x_train, x_val, y_train, y_val = train_test_split(x_train, y_train, test_size=0.25, shuffle=False)

# normalize dataset
x_train = min_max_scaler.fit_transform(x_train)
x_test = min_max_scaler.transform(x_test)
x_val = min_max_scaler.transform(x_val)

# reshape dataset
x_train = numpy.reshape(x_train, (x_train.shape[0], 1, x_train.shape[1]))
x_test = numpy.reshape(x_test, (x_test.shape[0], 1, x_test.shape[1]))
x_val = numpy.reshape(x_val, (x_val.shape[0], 1, x_val.shape[1]))
y_train = numpy.reshape(y_train, (y_train.shape[0], 1, y_train.shape[1]))
y_test = numpy.reshape(y_test, (y_test.shape[0], 1, y_test.shape[1]))
y_val = numpy.reshape(y_val, (y_val.shape[0], 1, y_val.shape[1]))

# RNN model
model = Sequential()
model.add(SimpleRNN(64, activation="relu", kernel_initializer='random_uniform', input_shape=input_shape, return_sequences=True))
model.add(Dense(32, activation="relu", kernel_initializer= 'random_uniform')) 
model.add(Dense(1, activation="linear", kernel_initializer= 'random_uniform'))

# train and predict
callback = keras.callbacks.EarlyStopping(monitor='val_loss', min_delta=0, patience=2, verbose=0, mode='auto')
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy', tf.keras.metrics.MeanSquaredError()])
history = model.fit(x_train, y_train, epochs=100, batch_size=8, validation_data=(x_val, y_val), callbacks=[callback])
results = model.evaluate(x_test, y_test)

# plot
test_predictions = model.predict(x_test)
test_predictions = min_max_scaler.inverse_transform(test_predictions)
y_test = y_test[:,:,0]
test_predictions = test_predictions[:,:,0]
plt.plot(y_test)
plt.plot(test_predictions)
plt.legend(['y_test', 'predictions'], loc='upper left')
plt.show()

1 Ответ

1 голос
/ 18 июня 2020

это потому, что вы передаете 3d-последовательности в minmaxscaler. он принимает 2d последовательности. что вам нужно сделать, так это преобразовать ваш прогноз в 2d, а затем вернуться к 3d. это можно сделать одной строкой ...

test_predictions = min_max_scaler.inverse_transform(test_predictions.reshape(-1,1)).reshape(test_predictions.shape)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...