第R2周:Tensorflow2实现:LSTM-火警温度预测

怀念夏天  金牌会员 | 2024-8-8 10:15:28 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 672|帖子 672|积分 2016


  • 本文为365天深度学习训练营 中的学习记录博客
  • 原作者:K同学啊
  任务说明:数据集中提供了火警温度(Tem1)、一氧化碳浓度(CO 1)、烟雾浓度(Soot 1)随着时间变化数据,我们需要根据这些数据对未来某一时候的火警温度做出预测
   要求:
1.了解LSTM是什么,并使用其构建一个完整的步调
2.R2到达0.83
  拔高:
1.使用第1 ~ 8个时候的数据预测第9 ~ 10个时候的温度数据
  我的环境:
●语言环境:Python3.8
●编译器:Jupyter Lab
●深度学习框架:TensorFlow2.4.1
●数据:火警温度数据集
一、理论知识底子
相关知识可以先看看上一篇文章《第R2周:LSTM-火警温度预测:一文搞懂LSTM(是非期影象网络)》
1.LSTM原理
一句话介绍LSTM,它是RNN的进阶版,如果说RNN的最大限度是理解一句话,那么LSTM的最大限度则是理解一段话,详细介绍如下:
LSTM,全称为是非期影象网络(Long Short Term Memory networks),是一种特殊的RNN,能够学习到恒久依赖关系。LSTM由Hochreiter & Schmidhuber (1997)提出,许多研究者举行了一系列的工作对其改进并使之发扬光大。LSTM在许多问题上效果非常好,现在被广泛使用。
全部的循环神经网络都有偏重复的神经网络模块形成链的形式。在平凡的RNN中,重复模块结构非常简朴,其结构如下:

LSTM制止了恒久依赖的问题。可以记住恒久信息!LSTM内部有较为复杂的结构。能通过门控状态来选择调解传输的信息,记住需要长时间影象的信息,忘记不紧张的信息,其结构如下:



  • LSTM的数据处理流程
为了更好的理解LSTM输入数据的结构,将时序数据(LSTM输入数据)以可视化的形式出现。



根据输入的数据结构、预测输出,我们的步调可以大抵分为以下六类:


  • 关于代码实现
    3.1. 单输入单输出(单输出时间步)

    ●输入:单个特征,多个时间步
    ●输出:单个特征,单个时间步
数据案例
  1. 训练集:
  2. X                         y
  3. [10, 20, 30, 40, 50]      [60]
  4. [20, 30, 40, 50, 60]      [70]
  5. [30, 40, 50, 60, 70]      [80]
  6. 预测输入:
  7. X
  8. [70, 80, 90, 100 ,110]
  9. 期待输出:
  10. y
  11. [120]
复制代码
TensorFlow2代码实现
  1. model = Sequential()
  2. model.add( LSTM(50,  activation='relu',  input_shape = (n_steps, n_features)) )
  3. model.add( Dense(1) )
  4. model.compile(optimizer='adam', loss='mse')
  5. n_steps = 5
  6. n_features = 1
复制代码
3.2. 多输入单输出(单输出时间步)

●输入:多个特征,多个时间步
●输出:单个特征,单个时间步
数据案例
  1. 训练集:
  2. X                       y
  3. [[10,11],
  4. [20,21],
  5. [30,31],
  6. [40,41],
  7. [50,51]]               60
  8. [[20,21],
  9. [30,31],
  10. [40,41],
  11. [50,51],
  12. [60,61]]               70
  13. 预测输入:
  14. X
  15. [[30,31],
  16. [40,41],
  17. [50,51],
  18. [60,61],
  19. [70,71]]
  20. 期待输出:
  21. y
  22. 80
复制代码
TensorFlow2代码实现
  1. model = Sequential()
  2. model.add(LSTM(50, activation='relu', input_shape=(n_steps, n_features)))
  3. model.add(Dense(1))
  4. model.compile(optimizer='adam', loss='mse')
  5. n_steps = 5
  6. # 此例中 n_features = 2,因为输入有两个并行序列
  7. n_features = X.shape[2]
复制代码
3.3. 多输入多输出(单输出时间步)

●输入:多个特征,多个时间步
●输出:多个特征,单个时间步
数据案例
  1. 训练集:
  2. X                       y
  3. [[10,11],
  4. [20,21],
  5. [30,31],
  6. [40,41],
  7. [50,51]]               [60,61]
  8. [[20,21],
  9. [30,31],
  10. [40,41],
  11. [50,51],
  12. [60,61]]               [70,71]
  13. 预测输入:
  14. X
  15. [[30,31],
  16. [40,41],
  17. [50,51],
  18. [60,61],
  19. [70,71]]
  20. 期待输出:
  21. y
  22. [80,81]
复制代码
TensorFlow2代码实现
  1. model = Sequential()
  2. model.add(LSTM(100, activation='relu', return_sequences=True, input_shape=(n_steps, n_features)))
  3. model.add(Dense(n_features))
  4. model.compile(optimizer='adam', loss='mse')
  5. n_steps = 5
  6. # 此例中 n_features = 2,因为输入有2个并行序列
  7. n_features = X.shape[2]
复制代码
3.4. 单输入单输出(多输出时间步)

●输入:单个特征,多个时间步
●输出:单个特征,多个时间步
数据案例
  1. 训练集:
  2. X                       y
  3. [10,20,30,40,50]       [60,70]
  4. [20,30,40,50,60]       [70,80]
  5. 预测输入:
  6. X
  7. [30,40,50,60,70]
  8. 期待输出:
  9. y
  10. [80,90]
复制代码
TensorFlow2代码实现
  1. model = Sequential()
  2. model.add(LSTM(100, activation='relu', return_sequences=True, input_shape=(n_steps, n_features)))
  3. model.add(Dense(n_steps_out))
  4. model.compile(optimizer='adam', loss='mse')
  5. n_steps = 5
  6. n_steps_out = 2
  7. n_features = 1
复制代码
多输入单输出(多输出时间步)与多输入多输出(多输出时间步)同理,这里就不赘述了

二、前期准备工作

  • 导入数据
  1. import tensorflow as tf
  2. import pandas     as pd
  3. import numpy      as np
  4. gpus = tf.config.list_physical_devices("GPU")
  5. if gpus:
  6.     tf.config.experimental.set_memory_growth(gpus[0], True)  #设置GPU显存用量按需使用
  7.     tf.config.set_visible_devices([gpus[0]],"GPU")
  8.     print("GPU: ",gpus)
  9. else:
  10.     print('CPU:')
  11. # 确认当前可见的设备列表
  12. print(tf.config.list_physical_devices())
  13. df_1 = pd.read_csv("./R2/woodpine2.csv")
复制代码
代码输出
  1. CPU:
  2. [PhysicalDevice(name='/physical_device:CPU:0', device_type='CPU')]
复制代码

  • 数据可视化
  1. import matplotlib.pyplot as plt
  2. import seaborn as sns
  3. plt.rcParams['savefig.dpi'] = 500 #图片像素
  4. plt.rcParams['figure.dpi']  = 500 #分辨率
  5. fig, ax =plt.subplots(1,3,constrained_layout=True, figsize=(14, 3))
  6. sns.lineplot(data=df_1["Tem1"], ax=ax[0])
  7. sns.lineplot(data=df_1["CO 1"], ax=ax[1])
  8. sns.lineplot(data=df_1["Soot 1"], ax=ax[2])
  9. plt.show()
复制代码
代码输出

三、构建数据集
  1. dataFrame = df_1.iloc[:,1:]
  2. dataFrame
复制代码
代码输出
   Tem1CO 1Soot 1025.00.0000000.000000125.00.0000000.000000225.00.0000000.000000325.00.0000000.000000425.00.0000000.000000............5943295.00.0000770.0004965944294.00.0000770.0004945945292.00.0000770.0004915946291.00.0000760.0004895947290.00.0000760.000487 5948 rows × 3 columns

  • 设置X、y
  1. width_X = 8
  2. width_y = 1
复制代码
取前8个时间段的Tem1、CO 1、Soot 1为X,第9个时间段的Tem1为y。
  1. X = []
  2. y = []
  3. in_start = 0
  4. for _, _ in df_1.iterrows():
  5.     in_end  = in_start + width_X
  6.     out_end = in_end   + width_y
  7.    
  8.     if out_end < len(dataFrame):
  9.         X_ = np.array(dataFrame.iloc[in_start:in_end , ])
  10.         X_ = X_.reshape((len(X_)*3))
  11.         y_ = np.array(dataFrame.iloc[in_end  :out_end, 0])
  12.         X.append(X_)
  13.         y.append(y_)
  14.    
  15.     in_start += 1
  16. X = np.array(X)
  17. y = np.array(y)
  18. X.shape, y.shape
复制代码
代码输出
  1. ((5939, 24)
  2. , (5939, 1))
复制代码

  • 归一化
  1. from sklearn.preprocessing import MinMaxScaler
  2. #将数据归一化,范围是0到1
  3. sc       = MinMaxScaler(feature_range=(0, 1))
  4. X_scaled = sc.fit_transform(X)
  5. X_scaled.shape
复制代码
代码输出
  1. (5939, 24)
复制代码
  1. X_scaled = X_scaled.reshape(len(X_scaled),width_X,3)
  2. X_scaled.shape
复制代码
代码输出
  1. (5939, 8, 3)
复制代码

  • 分别数据集
    取5000之前的数据为训练集,5000之后的为验证集
  1. X_train = np.array(X_scaled[:5000]).astype('float64')
  2. y_train = np.array(y[:5000]).astype('float64')
  3. X_test  = np.array(X_scaled[5000:]).astype('float64')
  4. y_test  = np.array(y[5000:]).astype('float64')
复制代码
  1. X_train.shape
复制代码
代码输出
  1. (5000, 8, 3)
复制代码
四、构建模型
  1. from tensorflow.keras.models import Sequentialfrom tensorflow.keras.layers import Dense,LSTM,Bidirectionalfrom tensorflow.keras        import Input# 多层 LSTMmodel_lstm = Sequential()model_lstm.add(LSTM(units=64, activation='relu', return_sequences=True,               input_shape=(X_train.shape
  2. [1], 3)))model_lstm.add(LSTM(units=64, activation='relu'))model_lstm.add(Dense(width_y))
复制代码
五、模型训练

  • 编译
  1. # 只观测loss数值,不观测准确率,所以删去metrics选项
  2. model_lstm.compile(optimizer=tf.keras.optimizers.Adam(1e-3),
  3.                    loss='mean_squared_error')  # 损失函数用均方误差
复制代码

  • 训练
  1. X_train.shape
  2. , y_train.shape
复制代码
代码输出
  1. ((5000, 8, 3)
  2. , (5000, 1))
复制代码
  1. history_lstm = model_lstm.fit(X_train, y_train,
  2.                          batch_size=64,
  3.                          epochs=40,
  4.                          validation_data=(X_test, y_test),
  5.                          validation_freq=1)
复制代码
代码输出
  1. Epoch 1/40
  2. 79/79 [==============================] - 3s 13ms/step - loss: 17642.7640 - val_loss: 5843.1167
  3. Epoch 2/40
  4. 79/79 [==============================] - 1s 9ms/step - loss: 421.8025 - val_loss: 863.2029
  5. Epoch 3/40
  6. 79/79 [==============================] - 1s 9ms/step - loss: 68.0383 - val_loss: 443.3524
  7. Epoch 4/40
  8. 79/79 [==============================] - 1s 11ms/step - loss: 63.1070 - val_loss: 630.0569
  9. Epoch 5/40
  10. 79/79 [==============================] - 1s 9ms/step - loss: 60.8359 - val_loss: 429.6816
  11. Epoch 6/40
  12. 79/79 [==============================] - 1s 9ms/step - loss: 55.2357 - val_loss: 332.5534
  13. Epoch 7/40
  14. 79/79 [==============================] - 1s 9ms/step - loss: 52.6763 - val_loss: 225.5500
  15. Epoch 8/40
  16. 79/79 [==============================] - 1s 9ms/step - loss: 50.2085 - val_loss: 233.0096
  17. Epoch 9/40
  18. 79/79 [==============================] - 1s 9ms/step - loss: 48.3704 - val_loss: 200.6572
  19. Epoch 10/40
  20. 79/79 [==============================] - 1s 9ms/step - loss: 43.5778 - val_loss: 255.6778
  21. Epoch 11/40
  22. 79/79 [==============================] - 1s 9ms/step - loss: 41.6273 - val_loss: 187.6802
  23. Epoch 12/40
  24. 79/79 [==============================] - 1s 9ms/step - loss: 37.9668 - val_loss: 152.1306
  25. Epoch 13/40
  26. 79/79 [==============================] - 1s 9ms/step - loss: 33.7161 - val_loss: 126.5226
  27. Epoch 14/40
  28. 79/79 [==============================] - 1s 9ms/step - loss: 29.3218 - val_loss: 99.1449
  29. Epoch 15/40
  30. 79/79 [==============================] - 1s 9ms/step - loss: 27.9880 - val_loss: 91.9206
  31. Epoch 16/40
  32. 79/79 [==============================] - 1s 9ms/step - loss: 25.1793 - val_loss: 104.4199
  33. Epoch 17/40
  34. 79/79 [==============================] - 1s 9ms/step - loss: 23.2140 - val_loss: 68.4278
  35. Epoch 18/40
  36. 79/79 [==============================] - 1s 9ms/step - loss: 20.5209 - val_loss: 58.7139
  37. Epoch 19/40
  38. 79/79 [==============================] - 1s 9ms/step - loss: 18.9439 - val_loss: 57.1808
  39. Epoch 20/40
  40. 79/79 [==============================] - 1s 9ms/step - loss: 18.0535 - val_loss: 65.7030
  41. Epoch 21/40
  42. 79/79 [==============================] - 1s 9ms/step - loss: 16.9911 - val_loss: 50.8789
  43. Epoch 22/40
  44. 79/79 [==============================] - 1s 9ms/step - loss: 15.8952 - val_loss: 62.8621
  45. Epoch 23/40
  46. 79/79 [==============================] - 1s 9ms/step - loss: 15.9065 - val_loss: 71.4229
  47. Epoch 24/40
  48. 79/79 [==============================] - 1s 9ms/step - loss: 9.7059 - val_loss: 60.4816
  49. Epoch 25/40
  50. 79/79 [==============================] - 1s 11ms/step - loss: 8.4736 - val_loss: 55.1349
  51. Epoch 26/40
  52. 79/79 [==============================] - 1s 9ms/step - loss: 8.2527 - val_loss: 47.9371
  53. Epoch 27/40
  54. 79/79 [==============================] - 1s 9ms/step - loss: 8.6649 - val_loss: 78.6073
  55. Epoch 28/40
  56. 79/79 [==============================] - 1s 9ms/step - loss: 8.9457 - val_loss: 95.0485
  57. Epoch 29/40
  58. 79/79 [==============================] - 1s 9ms/step - loss: 8.2558 - val_loss: 73.9929
  59. Epoch 30/40
  60. 79/79 [==============================] - 1s 9ms/step - loss: 8.6800 - val_loss: 46.4249
  61. Epoch 31/40
  62. 79/79 [==============================] - 1s 9ms/step - loss: 7.4052 - val_loss: 51.3766
  63. Epoch 32/40
  64. 79/79 [==============================] - 1s 11ms/step - loss: 8.3682 - val_loss: 47.5709
  65. Epoch 33/40
  66. 79/79 [==============================] - 1s 10ms/step - loss: 9.4248 - val_loss: 47.8780
  67. Epoch 34/40
  68. 79/79 [==============================] - 1s 11ms/step - loss: 9.0760 - val_loss: 61.7005
  69. Epoch 35/40
  70. 79/79 [==============================] - 1s 10ms/step - loss: 6.7884 - val_loss: 71.0755
  71. Epoch 36/40
  72. 79/79 [==============================] - 1s 10ms/step - loss: 7.3383 - val_loss: 47.5915
  73. Epoch 37/40
  74. 79/79 [==============================] - 1s 11ms/step - loss: 7.7409 - val_loss: 63.6706
  75. Epoch 38/40
  76. 79/79 [==============================] - 1s 12ms/step - loss: 6.7351 - val_loss: 44.5680
  77. Epoch 39/40
  78. 79/79 [==============================] - 1s 12ms/step - loss: 6.0092 - val_loss: 59.0267
  79. Epoch 40/40
  80. 79/79 [==============================] - 1s 11ms/step - loss: 7.3467 - val_loss: 50.5237
复制代码
六、评估

  • loss图
  1. # 支持中文
  2. plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
  3. plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
  4. plt.figure(figsize=(5, 3),dpi=120)
  5. plt.plot(history_lstm.history['loss']    , label='LSTM Training Loss')
  6. plt.plot(history_lstm.history['val_loss'], label='LSTM Validation Loss')
  7. plt.title('Training and Validation Loss')
  8. plt.legend()
  9. plt.show()
复制代码
代码输出


  • 调用模型举行预测
  1. predicted_y_lstm = model_lstm.predict(X_test)                        # 测试集输入模型进行预测
  2. y_test_one = [i[0] for i in y_test]
  3. predicted_y_lstm_one = [i[0] for i in predicted_y_lstm]
  4. plt.figure(figsize=(5, 3),dpi=120)
  5. # 画出真实数据和预测数据的对比曲线
  6. plt.plot(y_test_one[:1000], color='red', label='真实值')
  7. plt.plot(predicted_y_lstm_one[:1000], color='blue', label='预测值')
  8. plt.title('Title')
  9. plt.xlabel('X')
  10. plt.ylabel('Y')
  11. plt.legend()
  12. plt.show()
复制代码
代码输出

  1. from sklearn import metrics
  2. """
  3. RMSE :均方根误差  ----->  对均方误差开方
  4. R2   :决定系数,可以简单理解为反映模型拟合优度的重要的统计量
  5. """
  6. RMSE_lstm  = metrics.mean_squared_error(predicted_y_lstm, y_test)**0.5
  7. R2_lstm    = metrics.r2_score(predicted_y_lstm, y_test)
  8. print('均方根误差: %.5f' % RMSE_lstm)
  9. print('R2: %.5f' % R2_lstm)
复制代码
代码输出
  1. 均方根误差: 7.10801
  2. R2: 0.82670
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

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

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

怀念夏天

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表