Не воспроизводится прогноз TensorFlow

Адаптировал код из следующей статьи: https://habr.com/ru/articles/495884/

Создаю код для динамического прогнозирования временного ряда с OPC сервера. На данный момент столкунлся с проблемой - мой код не хочет давать адекватный прогноз при использовании самых новых данных. На примере объяснить проще:

  1. У меня есть набор данных в 419 строк, обучаю нейросеть на 250 строках.

  2. У модели есть параметры past_history - это количество значений, которое поступает в нейросеть, основываясь на которых она и делает прогноз. У меня PS=10. Прогноз на 5 шагов вперед

  3. Затем я отсекаю из набора данных нужный мне кусочек, на этом моменте и начинаются проблемы. Логично, что мне нужны последние 10 значений, но т.к. прогнозный код выполняет валидацию, беру 15 значений и... ничего не происходит. При 15 строках данных код завершается, не выдавая графиков и ошибок.

  4. При 16 строках прогнозирование начинает работать, но результаты ужасные: Прогноз при 16 строках Причем этот результат (красная линия) ВСЕГДА одинаковый.

  5. При 30 строках результат лучше, но все равно далек от идеала. И только при количестве строк от 50 результат такой, какой он и должен быть:Прогноз при 50 строках

Мне нужно, чтобы код мог принимать данные в размере past_history и давал адекватный прогноз. Можно и без валидации, чтобы не включать валидационные значения. Это вообще возможно реализовать?

Вот мой код:

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

# Параметры (из config.py)
from OPCUA_Config import (BATCH_SIZE, past_history, selected_parameter,
                          future_target, STEP, multivariate_data, features_considered)

# Загрузка данных для прогноза
df = pd.read_csv('Server/Data.csv').tail(16)  # Только последние строки
features = df[features_considered]
features.index = df['Timestamp']

# Стандартизация
dataset = features.values
data_mean = dataset.mean(axis=0)
data_std = dataset.std(axis=0)
dataset = (dataset - data_mean) / data_std

# Подготовка данных для прогноза
x_test_multi, y_test_multi = multivariate_data(dataset, dataset[:, selected_parameter],
                                               0, None, past_history,
                                               future_target, STEP)

test_data_multi = tf.data.Dataset.from_tensor_slices((x_test_multi, y_test_multi))
test_data_multi = test_data_multi.batch(BATCH_SIZE).repeat()

# Загрузка сохраненной модели
multi_step_model = tf.keras.models.load_model('Server/OPCUA.h5')

# Функция графика для отображения последних past_history данных
def plot_last_values(dataset):
    plt.figure(figsize=(10, 6))
    for i, feature in enumerate(features_considered):
        plt.plot(dataset[:, i], label=f'{feature}')  # Отображаем каждый признак
    plt.title(f'Последние {past_history} данных')
    plt.legend(loc='upper left')
    plt.show()

# Функция графика для прогноза
def create_time_steps(length):
    return list(range(-length, 0))

def multi_step_plot(history, true_future, prediction):
    plt.figure(figsize=(10, 6))
    num_in = create_time_steps(len(history))
    num_out = len(true_future)

    plt.plot(num_in, np.array(history[:, selected_parameter]), label='История')
    plt.plot(np.arange(num_out)/STEP, np.array(true_future), color='green', label='Истинное значение')
    if prediction.any():
        plt.plot(np.arange(num_out)/STEP, np.array(prediction), 'r', label='Предсказанное значение')
    plt.legend(loc='upper left')
    plt.show()

# Отображение последних значений перед прогнозом
plot_last_values(dataset)

# Выполнение интервального прогноза
for x, y in test_data_multi.take(1):
    multi_step_plot(x[0], y[0], multi_step_model.predict(x)[0])

Вот конфигурация:

# Параметры проекта
TRAIN_SPLIT = 250
BATCH_SIZE = 128
BUFFER_SIZE = 10000
past_history = 10
future_target = 5
STEP = 1
EVALUATION_INTERVAL = 250
EPOCHS = 10

И функция прогнозирования:

def multivariate_data(dataset, target, start_index, end_index, history_size,
                      target_size, step, single_step=False):
    
    data = []
    labels = []

    start_index = start_index + history_size
    if end_index is None:
        end_index = len(dataset) - target_size

    for i in range(start_index, end_index):
        indices = range(i-history_size, i, step)
        data.append(dataset[indices])
        if single_step:
            labels.append(target[i+target_size])
        else:
            labels.append(target[i:i+target_size])

    return np.array(data), np.array(labels)

P.S. Вообще, в итоге моей работы должен получиться график, который в реальном времени обновляется, получая данные с OPC-сервера. Прогноз также будет обновляться в реальном времени при помощи единажды обученной модели. Без валидации. Код, описанный выше - это лишь один из этапов моих попыток разобраться с tensorflow. Если у вас есть предложения/идеи - я с радостью их выслушаю.

P.P.S. Я надеюсь, что понятно объяснил проблему. Я далеко не эксперт и пишу код чатом и при помощи интернета.


Ответы (0 шт):