【猜测】-双注意LSTM自动编码器记载

打印 上一主题 下一主题

主题 1001|帖子 1001|积分 3003

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1 猜测-双注意LSTM自动编码器

复现github链接:https://github.com/JulesBelveze/time-series-autoencoder.git
论文:A Dual-Stage Attention-Based Recurrent Neural Network for Time Series Prediction:https://arxiv.org/abs/1704.02971
1.1 复现环境设置

python版本:python3.8.20
cuda版本:cuda111
包版本环境参考:
  1. Package              Version      Editable project location
  2. -------------------- ------------ ---------------------------
  3. build                1.2.2.post1
  4. CacheControl         0.14.2
  5. certifi              2025.1.31
  6. charset-normalizer   3.4.1
  7. cleo                 2.1.0
  8. colorama             0.4.6
  9. contourpy            1.1.1
  10. crashtest            0.4.1
  11. cycler               0.10.0
  12. distlib              0.3.9
  13. dulwich              0.21.7
  14. fastjsonschema       2.21.1
  15. filelock             3.16.1
  16. fonttools            4.56.0
  17. future               0.18.2
  18. idna                 3.10
  19. importlib_metadata   8.5.0
  20. importlib_resources  6.4.5
  21. installer            0.7.0
  22. jaraco.classes       3.4.0
  23. joblib               0.15.1
  24. keyring              24.3.1
  25. kiwisolver           1.2.0
  26. matplotlib           3.2.1
  27. more-itertools       10.5.0
  28. msgpack              1.1.0
  29. numpy                1.21.0
  30. packaging            24.2
  31. pandas               1.1.5
  32. pexpect              4.9.0
  33. pillow               10.4.0
  34. pip                  24.3.1
  35. pkginfo              1.12.1.2
  36. platformdirs         4.3.6
  37. poetry               1.8.5
  38. poetry-core          1.9.1
  39. poetry-plugin-export 1.8.0
  40. protobuf             5.29.3
  41. ptyprocess           0.7.0
  42. pyparsing            2.4.7
  43. pyproject_hooks      1.2.0
  44. python-dateutil      2.8.1
  45. pytz                 2025.1
  46. pywin32-ctypes       0.2.3
  47. rapidfuzz            3.9.7
  48. requests             2.32.3
  49. requests-toolbelt    1.0.0
  50. scikit-learn         0.23.1
  51. scipy                1.4.1
  52. setuptools           75.3.0
  53. shellingham          1.5.4
  54. six                  1.15.0
  55. sklearn              0.0
  56. tensorboardX         2.6.2.2
  57. threadpoolctl        2.1.0
  58. tomli                2.2.1
  59. tomlkit              0.13.2
  60. torch                1.9.1+cu111
  61. torchaudio           0.9.1
  62. torchvision          0.10.1+cu111
  63. tqdm                 4.46.1
  64. trove-classifiers    2025.2.18.16
  65. tsa                  0.1.0        D:\temp\Pytorch双注意LSTM自动编码器
  66. typing_extensions    4.12.2
  67. urllib3              2.2.3
  68. virtualenv           20.29.2
  69. wheel                0.45.1
  70. zipp                 3.20.2
复制代码
注:
vscode设置:
  1. {
  2.     // Use IntelliSense to learn about possible attributes.
  3.     // Hover to view descriptions of existing attributes.
  4.     // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  5.     "version": "0.2.0",
  6.     "configurations": [
  7.         {
  8.             "name": "Python Debugger: Current File with Arguments",
  9.             "type": "debugpy",
  10.             "request": "launch",
  11.             "program": "${file}",
  12.             "cwd":"${fileDirname}",
  13.             "console": "integratedTerminal",
  14.             // "args": [
  15.             //     "--ckpt", "output/checkpoint-5000.ckpt"  // 添加 --ckpt 参数及其值
  16.             // ]
  17.         }
  18.     ]
  19. }
复制代码
1.2 数据流记载

源代码所用数据字段:
  1. | 列名          | 含义               | 单位     |
  2. | ------------- | ------------------ | -------- |
  3. | Date_Time     | 日期和时间         | -        |
  4. | CO(GT)        | 一氧化碳浓度       | mg/m³    |
  5. | PT08.S1(CO)   | 一氧化碳传感器响应值 | 无量纲  |
  6. | NMHC(GT)      | 非甲烷烃浓度       | µg/m³   |
  7. | C6H6(GT)      | 苯浓度             | µg/m³   |
  8. | PT08.S2(NMHC) | 非甲烷烃传感器响应值 | 无量纲 |
  9. | NOx(GT)       | 氮氧化物浓度       | µg/m³   |
  10. | PT08.S3(NOx)  | 氮氧化物传感器响应值 | 无量纲 |
  11. | NO2(GT)       | 二氧化氮浓度       | µg/m³   |
  12. | PT08.S4(NO2)  | 二氧化氮传感器响应值 | 无量纲 |
  13. | PT08.S5(O3)   | 臭氧传感器响应值    | 无量纲  |
  14. | T             | 温度               | °C      |
  15. | RH            | 相对湿度           | %       |
  16. | AH            | 绝对湿度           | g/m³    |
复制代码
将时间序列数据转换为适合时间序列猜测的格式,详细来说,它通过滑动窗口的方式从输入数据 X 和标签 y 中提取特性和标签,并天生一个 TensorDataset。提取特性和标签,猜测的是后面的猜测窗口长度的标签。下面我将详细表明 X、y 和 target 的取数逻辑,并指出 y 取数可能存在的问题。

1.2.1 构建Dataset

(1) X 的取数



  • X 是输入特性数据,形状为 (nb_obs, nb_features),其中 nb_obs 是样本数目,nb_features 是特性数目。
  • 通过滑动窗口的方式,从 X 中提取长度为 seq_length 的序列:
    1. features.append(torch.FloatTensor(X[i:i + self.seq_length, :]).unsqueeze(0))
    复制代码

    • 比方,假如 seq_length = 10,则每次提取 X[i:i+10, :],即从第 i 个时间步开始的 10 个时间步的特性数据。
    • unsqueeze(0) 是为了增加一个批次维度。

(2) y 的取数



  • y 是目标值(标签),通常是与 X 对应的输出值。
  • 代码中从 y 中提取的是滞后一期的汗青值(y[i-1:i+self.seq_length-1]):
    1. y_hist.append(torch.FloatTensor(y[i - 1:i + self.seq_length - 1]).unsqueeze(0))
    复制代码

    • 比方,假如 seq_length = 10,则提取的是 y[i-1:i+9],即从第 i-1 个时间步开始的 10 个时间步的标签值。
    • 这里 y[i-1] 的使用可能有问题,因为 y[i-1] 是前一个时间步的值,而不是当前时间步的值。假如 y 是当前时间步的标签,那么这里应该直接使用 y[i:i+self.seq_length]。

(3) target 的取数



  • target 是猜测的目标值,即将来 prediction_window 个时间步的标签值:
    1. target.append(torch.FloatTensor(y[i + self.seq_length:i + self.seq_length + self.prediction_window]))
    复制代码

    • 比方,假如 seq_length = 10 且 prediction_window = 5,则提取的是 y[i+10:i+15],即从第 i+10 个时间步开始的 5 个时间步的标签值。


1.2.2 举例说明

假设有以下数据:


  • X 和 y 的长度为 20。
  • seq_length = 3,prediction_window = 2。
(1)X 的取数



  • 当 i = 1 时,提取 X[1:4, :]。
  • 当 i = 2 时,提取 X[2:5, :]。
  • 以此类推。
(2)y 的取数



  • 当 i = 1 时,提取 y[0:3](即 y[i-1:i+seq_length-1])。
  • 当 i = 2 时,提取 y[1:4]。
  • 以此类推。
(3)target 的取数



  • 当 i = 1 时,提取 y[4:6](即 y[i+seq_length:i+seq_length+prediction_window])。
  • 当 i = 2 时,提取 y[5:7]。
  • 以此类推。

1.2.3 y 取数的问题

在代码中,y 的取数逻辑是:
  1. y_hist.append(torch.FloatTensor(y[i - 1:i + self.seq_length - 1]).unsqueeze(0))
复制代码
这里使用了 y[i-1],即前一个时间步的值。假如 y 是当前时间步的标签,那么这里应该直接使用 y[i:i+self.seq_length],而不是 y[i-1:i+self.seq_length-1]。修正后的代码应该是:
  1. y_hist.append(torch.FloatTensor(y[i:i + self.seq_length]).unsqueeze(0))
复制代码

修正后的代码

  1. def frame_series(self, X, y=None):    '''    Function used to prepare the data for time series prediction    :param X: set of features    :param y: targeted value to predict    :return: TensorDataset    '''    nb_obs, nb_features = X.shape    features, target, y_hist = [], [], []    for i in range(1, nb_obs - self.seq_length - self.prediction_window):        features.append(torch.FloatTensor(X[i:i + self.seq_length, :]).unsqueeze(0))
  2.         # 修正后的 y 取数逻辑        y_hist.append(torch.FloatTensor(y[i:i + self.seq_length]).unsqueeze(0))
  3.     features_var, y_hist_var = torch.cat(features), torch.cat(y_hist)    if y is not None:        for i in range(1, nb_obs - self.seq_length - self.prediction_window):            target.append(                torch.FloatTensor(y[i + self.seq_length:i + self.seq_length + self.prediction_window]))        target_var = torch.cat(target)        return TensorDataset(features_var, y_hist_var, target_var)    return TensorDataset(features_var)
复制代码

1.2.4 总结



  • X 的取数是滑动窗口提取特性序列。
  • y 的取数逻辑存在问题,不应使用 y[i-1],而应直接使用 y[i:i+self.seq_length]。
  • target 的取数是提取将来 prediction_window 个时间步的标签值。

这段代码的数据流可以分为以下几个步调:

  • 数据预处置处罚

    • 调用 self.preprocess_data() 方法,天生训练集和测试集的特性和标签:X_train, X_test, y_train, y_test。
    • 从 X_train 中获取特性的数目 nb_features。

  • 数据集封装

    • 调用 self.frame_series(X_train, y_train) 方法,将训练集的特性和标签封装成一个 train_dataset 对象。
    • 调用 self.frame_series(X_test, y_test) 方法,将测试集的特性和标签封装成一个 test_dataset 对象。

  • DataLoader 创建

    • 使用 DataLoader 类创建 train_iter,用于加载训练数据集。参数包括 batch_size(批次巨细)、shuffle=False(不打乱数据)、drop_last=True(丢弃末了一个不完整的批次)。
    • 使用 DataLoader 类创建 test_iter,用于加载测试数据集。参数与 train_iter 相同。

  • 返回效果

    • 返回 train_iter(训练数据加载器)、test_iter(测试数据加载器)和 nb_features(特性数目)。

1.2.5 数据流总结:



  • 输入:原始数据通过 self.preprocess_data() 进行预处置处罚,天生特性和标签。
  • 处置处罚:特性和标签被封装成 Dataset 对象,然后通过 DataLoader 进行批次加载。
  • 输出:返回训练和测试的 DataLoader 对象,以及特性数目。
1.2.6 数据流图示:

  1. 原始数据 → preprocess_data() → (X_train, X_test, y_train, y_test) → frame_series() → (train_dataset, test_dataset) → DataLoader() → (train_iter, test_iter)
复制代码
1.2.7 参考:



  • DataLoader 是 PyTorch 中用于批量加载数据的工具,支持多线程加载、数据打乱等功能。
  • Dataset 是 PyTorch 中用于封装数据集的基类,通常需要实现 __len__ 和 __getitem__ 方法。

为了更好地明确数据维度的变化情况,我们可以通过一个详细的例子来渐渐分析代码中的数据维度变化。假设我们有一个时间序列数据集,包罗以下列:


  • date: 时间戳
  • feature1: 数值特性
  • feature2: 数值特性
  • category: 种别特性
  • target: 目标值
2 数据维度变化流程


  • 原始数据 (data):

    • 假设数据集有 1000 行,5 列(date, feature1, feature2, category, target)。
    • 维度:(1000, 5)

  • 预处置处罚 (preprocess_data):

    • X = data.drop('target', axis=1):去掉目标列,剩下 4 列。

      • 维度:(1000, 4)

    • y = data['target']:目标列。

      • 维度:(1000,)

    • X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8, shuffle=False):

      • X_train 维度:(800, 4)
      • X_test 维度:(200, 4)
      • y_train 维度:(800,)
      • y_test 维度:(200,)

    • X_train = preprocessor.fit_transform(X_train):颠末 ColumnTransformer 处置处罚,假设 category 列被编码为 3 个新列。

      • 维度:(800, 5)(feature1, feature2, category_encoded_1, category_encoded_2, category_encoded_3)

    • X_test = preprocessor.transform(X_test):

      • 维度:(200, 5)


  • 时间序列帧化 (frame_series):

    • 假设 seq_length = 10,prediction_window = 1。
    • nb_obs, nb_features = X_train.shape:

      • nb_obs = 800, nb_features = 5

    • features 和 y_hist 的天生:

      • 对于 i 从 1 到 800 - 10 - 1 = 789,每次取 10 个时间步的数据。
      • features 维度:(789, 10, 5)
      • y_hist 维度:(789, 10)

    • target 的天生:

      • 对于 i 从 1 到 789,每次取 1 个时间步的目标值。
      • target 维度:(789, 1)

    • TensorDataset 的天生:

      • features_var 维度:(789, 10, 5)
      • y_hist_var 维度:(789, 10)
      • target_var 维度:(789, 1)


  • DataLoader (get_loaders):

    • train_iter = DataLoader(train_dataset, batch_size=32, shuffle=False, drop_last=True):

      • 每个 batch 的维度:(32, 10, 5)(特性),(32, 10)(汗青目标),(32, 1)(目标)

    • test_iter = DataLoader(test_dataset, batch_size=32, shuffle=False, drop_last=True):

      • 每个 batch 的维度:(32, 10, 5)(特性),(32, 10)(汗青目标),(32, 1)(目标)


2.1 流程图

  1. 原始数据 (1000, 5)
  2.        |
  3.        v
  4. 预处理 (X_train: 800, 5, y_train: 800)
  5.        |
  6.        v
  7. 时间序列帧化 (features: 789, 10, 5, y_hist: 789, 10, target: 789, 1)
  8.        |
  9.        v
  10. DataLoader (batch_size=32, features: 32, 10, 5, y_hist: 32, 10, target: 32, 1)
复制代码
2.2 总结

通过上述步调,可以看到数据从原始形式渐渐转换为适合时间序列模型训练的格式。每个步调中的数据维度变化如下:

  • 原始数据:(1000, 5)
  • 预处置处罚后:(800, 5)(训练集特性),(800,)(训练集目标)
  • 时间序列帧化后:(789, 10, 5)(特性),(789, 10)(汗青目标),(789, 1)(目标)
  • DataLoader 中:(32, 10, 5)(特性),(32, 10)(汗青目标),(32, 1)(目标)

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

半亩花草

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表