Tensorflow LSTM custom l oop сильно не подходит для временных рядов - PullRequest
0 голосов
/ 23 марта 2020

Я делаю нейронную сеть LSTM для прогнозирования временных рядов, используя Tensorflow. Потеря уменьшается медленно и останавливается с очень высокой ошибкой. Я что-то пропустил?

import pandas as pd
import tensorflow as tf
from tensorflow.keras.layers import Dense, LSTM
from tensorflow.keras import Model
tf.keras.backend.set_floatx('float64')
import numpy as np

passengers = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seabo'
                      'rn-data/master/flights.csv')[['passengers']]

for i in range(1, 8):
    passengers.loc[:, f'VOL_T–%s' % i] = passengers.loc[:, 'passengers'].shift(i)

passengers = passengers.fillna(method='ffill', axis=1)

x = passengers.iloc[:, 1:].values
y = passengers['passengers'].values

x = x.reshape(len(x), 1, x.shape[-1])

xtrain, ytrain = x[:120], y[:120]
xtest, ytest = x[120:140], y[120:140]

train = tf.data.Dataset.from_tensor_slices((xtrain, ytrain)).batch(8)
test = tf.data.Dataset.from_tensor_slices((xtest, ytest)).batch(8)

class MyModel(Model):
    def __init__(self):
        super(MyModel, self).__init__()
        self.lstm1 = LSTM(16, return_sequences=True)
        self.dense1 = Dense(1)

    def __call__(self, x):
        x = self.lstm1(x)
        out = self.dense1(x)
        return out

model = MyModel()

optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3)

loss_obj_reg = tf.keras.losses.MeanAbsoluteError()

train_loss_reg = tf.keras.metrics.Mean(name='training regression loss')
test_loss_reg = tf.keras.metrics.Mean(name='testing regression loss')

@tf.function
def train_step(inputs, output):
    with tf.GradientTape() as tape:
        pred = model(inputs)
        train_loss = loss_obj_reg(output, pred)

    gradients = tape.gradient(train_loss, model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

    train_loss_reg(train_loss)

@tf.function
def test_step(inputs, output):
    pred = model(inputs)
    test_loss = loss_obj_reg(output, pred)
    test_loss_reg(test_loss)

for epoch in range(1, 1000 + 1):
    train_loss_reg.reset_states()
    test_loss_reg.reset_states()

    for inputs, outputs in train:
        train_step(inputs, outputs)

    for inputs, outputs in test:
        test_step(inputs, outputs)
    if epoch % 100 == 0:
        template = 'Epoch {:>3d}, Train Loss: {:>6.4f}, Test Loss: {:>6.4f}'

        print(template.format(epoch, train_loss_reg.result(), test_loss_reg.result()))
Epoch 100, Train Loss: 94.0170, Test Loss: 304.3173
Epoch 200, Train Loss: 92.1260, Test Loss: 300.7716
Epoch 300, Train Loss: 90.6222, Test Loss: 297.6245
Epoch 400, Train Loss: 89.2832, Test Loss: 294.6490
Epoch 500, Train Loss: 88.0102, Test Loss: 291.7477
Epoch 600, Train Loss: 86.9937, Test Loss: 289.1594
Epoch 700, Train Loss: 86.1356, Test Loss: 286.7755
Epoch 800, Train Loss: 85.3970, Test Loss: 284.5618
Epoch 900, Train Loss: 84.6737, Test Loss: 282.3737
Epoch 1000, Train Loss: 84.0051, Test Loss: 280.2625

1 Ответ

0 голосов
/ 27 марта 2020

Диапазон столбцов пассажир слишком широк , в сотнях. Вам нужно нормализовать его до меньшего диапазона , скажем, от 0 до 1 , прежде чем передавать его в текущую сеть. Для выполнения sh вы можете использовать скалер. Вот пример использования sklearn's MinMaxScaler :

Вот пример:

import pandas as pd
from sklearn.preprocessing import MinMaxScaler

data = pd.read_csv("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/flights.csv", header = 0, usecols = ["passengers"])

scaler = MinMaxScaler(feature_range = (0, 1))

scaler.fit(data) # computes the minimum and maximum to be used for later scaling.

print(scaler.transform(data))

Если вам нужно преобразовать масштабированный обратно в исходный диапазон, сделайте:

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