zhuchangshuo 1 week ago
parent
commit
98bb137da6

+ 6 - 0
TrajTrans/StateOnly/AutoEncoder/.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
+  </component>
+</project>

+ 1 - 1
TrajTrans/StateOnly/AutoEncoder/HyperParamSearch.py

@@ -25,7 +25,7 @@ X_temp, X_train, Y_temp, Y_train = train_test_split(DataX, DataY, test_size=1 -
 X_test, X_val, Y_test, Y_val = train_test_split(X_temp, Y_temp, test_size=test_size / (test_size + val_size),
                                                 random_state=42)
 
-hidden_dim_lib = [128]
+hidden_dim_lib = [256]
 latent_dim_lib = [100]
 # num_layer_lib = [3]
 lr_lib = [1E-3]

+ 1 - 1
TrajTrans/StateOnly/DeepKoopMan/DeepKoopmanModel.py

@@ -71,7 +71,7 @@ class DeepKoopMan(nn.Module):
         ae_loss = mseloss(state, state_pre)
         pre_loss = mseloss(state_next, state_next_pre)
 
-        total_loss = pre_loss * self.lambda1 + ae_loss
+        total_loss = pre_loss + ae_loss * self.lambda1
         return total_loss
 
     def deepkoopman_train(self, batch_size, epochs, lr, data_train, data_val):

BIN
TrajTrans/StateOnly/DeepKoopMan/__pycache__/DeepKoopmanModel.cpython-311.pyc


+ 20 - 0
TrajTrans/StateOnly/ESN/AutoEncoderTest.py

@@ -0,0 +1,20 @@
+from DeepKoopmanModel import DeepKoopMan, DeepKoopManConfig
+import torch
+import numpy as np
+import matplotlib.pyplot as plt
+
+Model = torch.load('./ModelLib/DeepKoopmanModel.pt', map_location="cpu")
+encoder = Model.encoder
+decoder = Model.decoder
+
+Data = np.loadtxt('./DataLib/DataNor.csv', delimiter=',')
+Latent = encoder(torch.from_numpy(Data).float())
+DataPre = decoder(Latent).detach().numpy()
+
+MSE = np.linalg.norm(Data - DataPre, ord='fro') ** 2 / np.prod(Data.shape)
+print(MSE)
+for fea in np.arange(13):
+    plt.figure(fea)
+    plt.plot(Data[:, fea])
+    plt.plot(DataPre[:, fea])
+    plt.show()

+ 27 - 1
TrajTrans/StateOnly/ESN/DeepKoopmanModel.py

@@ -10,6 +10,7 @@ class DeepKoopManConfig:
     state_dim: int
     latent_dim: int
     hidden_dim: int
+    # seq_len: int
 
 
 class DeepKoopMan(nn.Module):
@@ -24,18 +25,43 @@ class DeepKoopMan(nn.Module):
 
         self.state_dim = state_dim
         self.latent_dim = latent_dim
+        # self.seq_len = seq_len
 
         self.encoder = encoder
         self.decoder = decoder
 
         self.lambda1 = 0.6
 
+        # for param in self.encoder.parameters():
+        #     param.requires_grad = False
+        # for param in self.decoder.parameters():
+        #     param.requires_grad = False
+
+        # # 编码器 Encoder
+        # self.encoder = nn.Sequential(
+        #     nn.Linear(state_dim, hidden_dim),
+        #     nn.ReLU(),
+        #     nn.Linear(hidden_dim, hidden_dim),
+        #     nn.ReLU(),
+        #     nn.Linear(hidden_dim, latent_dim)
+        # )
+        #
+        # # 解码器 Decoder
+        # self.decoder = nn.Sequential(
+        #     nn.Linear(latent_dim, hidden_dim),
+        #     nn.ReLU(),
+        #     nn.Linear(hidden_dim, hidden_dim),
+        #     nn.ReLU(),
+        #     nn.Linear(hidden_dim, state_dim)
+        # )
+
         # Koopman算子A
         self.A = nn.Parameter(torch.randn(latent_dim, latent_dim))
 
     def forward(self, state):
         latent = self.encoder(state)
-        latent_next_pre = torch.matmul(latent, self.A)
+        dlatent_plus_dt = torch.matmul(latent, self.A)
+        latent_next_pre = latent + dlatent_plus_dt
         state_next_pre = self.decoder(latent_next_pre)
         state_pre = self.decoder(latent)
         return state_pre, state_next_pre

+ 75 - 0
TrajTrans/StateOnly/ESN/ESNTest.py

@@ -0,0 +1,75 @@
+import torch
+from KoopmanESNModel import KoopmanESNConfig, KoopmanESN
+from BaseModel.ESNModel import ESN
+from DataProcess import DataLoad
+import numpy as np
+import matplotlib.pyplot as plt
+
+KoopmanModel = torch.load('./ModelLib/DeepKoopmanModel.pt', map_location="cpu")
+encoder = KoopmanModel.encoder
+decoder = KoopmanModel.decoder
+A = KoopmanModel.A.detach().numpy()
+state_dim = KoopmanModel.state_dim
+latent_dim = KoopmanModel.latent_dim
+
+lr = 0.5
+sr = 0.9
+sp = 0.1
+ridge = 1e-7
+train_start = 15000
+train_len = 5000
+train_warmup = 100
+predict_warmup = 100
+predict_len = 1000
+
+ESNconfig = KoopmanESNConfig(
+    units=100,
+    lr=lr,
+    sr=sr,
+    sp=sp,
+    ridge=ridge,
+    train_start=train_start,
+    train_len=train_len,
+    train_warmup=train_warmup,
+    predict_warmup=predict_warmup,
+    predict_len=predict_len,
+    state_dim=state_dim
+)
+
+ESNModel = ESN(
+    config=ESNconfig
+)
+_, DataTrain, DataWarm, DataVal = DataLoad('./DataLib/DataNor.csv', ESNconfig)
+# _, DataTrain, DataWarm = DataLoad('./DataLib/DataNor.csv', config)
+
+# ESN
+ESNModel.esn_train(DataTrain)
+DataPreESN = ESNModel.predict(DataWarm)
+
+DataPreESN_Ten = torch.from_numpy(DataPreESN).float()
+DataVal_Ten = torch.from_numpy(DataVal).float()
+DataWarm_Ten = torch.from_numpy(DataWarm).float()
+
+StatePreESN_Ten = DataPreESN_Ten
+StateVal_Ten = DataVal_Ten
+StateWarm_Ten = DataWarm_Ten
+
+StatePreESN = StatePreESN_Ten.detach().numpy()
+StateVal = StateVal_Ten.detach().numpy()
+StateWarm = StateWarm_Ten.detach().numpy()
+
+ESNMSE = np.linalg.norm(StatePreESN - StateVal, ord='fro') ** 2 / np.prod(StateVal.shape)
+print(ESNMSE)
+
+t = np.arange(ESNconfig.predict_warmup + ESNconfig.predict_len)
+
+for fea in np.arange(state_dim):
+    plt.figure(fea)
+    plt.plot(t[:ESNconfig.predict_warmup], StateWarm[:, fea],
+             linestyle="-", color='black', label='StateWarm')
+    plt.plot(t[-ESNconfig.predict_len:], StatePreESN[:, fea],
+             linestyle="--", color='green', label='ESNPre')
+    plt.plot(t[-ESNconfig.predict_len:], StateVal[:, fea],
+             linestyle="-", color='blue', label='StateReal')
+    plt.legend()
+    plt.show()

+ 23 - 29
TrajTrans/StateOnly/ESN/KoopmanESNMain.py

@@ -20,7 +20,7 @@ train_start = 15000
 train_len = 5000
 train_warmup = 100
 predict_warmup = 100
-predict_len = 500
+predict_len = 5000
 
 Koopmanconfig = KoopmanESNConfig(
     units=latent_dim,
@@ -37,7 +37,7 @@ Koopmanconfig = KoopmanESNConfig(
 )
 
 ESNconfig = KoopmanESNConfig(
-    units=1000,
+    units=500,
     lr=lr,
     sr=sr,
     sp=sp,
@@ -47,7 +47,7 @@ ESNconfig = KoopmanESNConfig(
     train_warmup=train_warmup,
     predict_warmup=predict_warmup,
     predict_len=predict_len,
-    state_dim=latent_dim
+    state_dim=state_dim
 )
 
 KoopESNModel = KoopmanESN(
@@ -57,48 +57,42 @@ KoopESNModel = KoopmanESN(
 ESNModel = ESN(
     config=ESNconfig
 )
-_, DataTrain, DataWarm, DataVal = DataLoad('./DataLib/LatentNor.csv', Koopmanconfig)
-# _, DataTrain, DataWarm = DataLoad('./DataLib/DataNor.csv', config)
-
+_, DataTrainKoop, DataWarmKoop, DataValKoop = DataLoad('./DataLib/LatentNor.csv', Koopmanconfig)
 # KoopmanESN
-KoopESNModel.koopmanesn_train(DataTrain)
-DataPreKoop = KoopESNModel.predict(DataWarm)
-
-# ESN
-ESNModel.esn_train(DataTrain)
-DataPreESN = ESNModel.predict(DataWarm)
+KoopESNModel.koopmanesn_train(DataTrainKoop)
+DataPreKoop = KoopESNModel.predict(DataWarmKoop)
 
 DataPreKoop_Ten = torch.from_numpy(DataPreKoop).float()
-DataPreESN_Ten = torch.from_numpy(DataPreESN).float()
-DataVal_Ten = torch.from_numpy(DataVal).float()
-DataWarm_Ten = torch.from_numpy(DataWarm).float()
+DataValKoop_Ten = torch.from_numpy(DataValKoop).float()
+DataWarmKoop_Ten = torch.from_numpy(DataWarmKoop).float()
 
 StatePreKoop_Ten = decoder(DataPreKoop_Ten)
-StatePreESN_Ten = decoder(DataPreESN_Ten)
-StateVal_Ten = decoder(DataVal_Ten)
-StateWarm_Ten = decoder(DataWarm_Ten)
+StateValKoop_Ten = decoder(DataValKoop_Ten)
+StateWarmKoop_Ten = decoder(DataWarmKoop_Ten)
 
 StatePreKoop = StatePreKoop_Ten.detach().numpy()
-StatePreESN = StatePreESN_Ten.detach().numpy()
-StateVal = StateVal_Ten.detach().numpy()
-StateWarm = StateWarm_Ten.detach().numpy()
+StateValKoop = StateValKoop_Ten.detach().numpy()
+StateWarmKoop = StateWarmKoop_Ten.detach().numpy()
 
-KoopMSE = np.linalg.norm(StatePreKoop - StateVal, ord='fro') ** 2 / np.prod(StateVal.shape)
-ESNMSE = np.linalg.norm(StatePreESN - StateVal, ord='fro') ** 2 / np.prod(StateVal.shape)
+KoopMSE = np.linalg.norm(StatePreKoop - StateValKoop, ord='fro') ** 2 / np.prod(StateValKoop.shape)
 print(KoopMSE)
-print(ESNMSE)
 
 t = np.arange(Koopmanconfig.predict_warmup + Koopmanconfig.predict_len)
 
+DataMaxMin = np.loadtxt('./DataLib/DataMaxMin.csv', delimiter=',')
+DataMax = DataMaxMin[0, :]
+DataMin = DataMaxMin[1, :]
+
+StateWarmKoop = (StateWarmKoop + 1) * (DataMax-DataMin) + DataMin
+StatePreKoop = (StatePreKoop + 1) * (DataMax-DataMin) + DataMin
+StateValKoop = (StateValKoop + 1) * (DataMax-DataMin) + DataMin
+
 for fea in np.arange(state_dim):
     plt.figure(fea)
-    plt.plot(t[:Koopmanconfig.predict_warmup], StateWarm[:, fea],
-             linestyle="-", color='black', label='StateWarm')
+    plt.plot(t[:Koopmanconfig.predict_warmup], StateWarmKoop[:, fea])
     plt.plot(t[-Koopmanconfig.predict_len:], StatePreKoop[:, fea],
              linestyle="--", color='red', label='KoopmanESNPre')
-    plt.plot(t[-Koopmanconfig.predict_len:], StatePreESN[:, fea],
-             linestyle="--", color='green', label='ESNPre')
-    plt.plot(t[-Koopmanconfig.predict_len:], StateVal[:, fea],
+    plt.plot(t[-Koopmanconfig.predict_len:], StateValKoop[:, fea],
              linestyle="-", color='blue', label='StateReal')
     plt.legend()
     plt.show()

+ 1 - 29
TrajTrans/StateOnly/ESN/KoopmanESNModel.py

@@ -27,38 +27,10 @@ class KoopmanESN:
 
         self.esn_model = None
         self.config = config
-        self.A = A
+        self.A = A/100
 
     def W_initial(self, A):
-        # W_res = np.random.randn(self.config.units, self.config.units)
-        # mask = np.random.rand(self.config.units, self.config.units) > self.config.sp
-        # W_res[mask] = 0
-        # W_res = self.config.sr * (W_res / np.max(np.abs(eigvals(W_res))))  # 归一化谱半径
-
-        # 2. 生成对齐矩阵U和V(通过SVD或随机投影)
-        # U = np.random.randn(self.config.units, self.config.state_dim)
-        # V = np.random.randn(self.config.units, self.config.state_dim)
-        #
-        # W_koop = U @ A @ V.T
-
         W_koop = A
-
-        # # SVD分解
-        # U, S, Vt = np.linalg.svd(A)
-        #
-        # # 生成随机投影矩阵,但与SVD的主方向对齐
-        # P = np.random.randn(self.config.units, U.shape[0])  # (100,5)
-        # Q = np.random.randn(self.config.units, Vt.shape[1])  # (100,5)
-        #
-        # U_aligned = P @ U  # 随机旋转后的U
-        # V_aligned = Q @ Vt.T  # 随机旋转后的V
-        #
-        # # 构造耦合项
-        # W_koop = U_aligned @ np.diag(S) @ V_aligned.T  # (100,100)
-
-        # 4. 耦合W_res和W_koop
-        # lambda_coupling = 0.1
-        # W = W_res + lambda_coupling * W_koop
         W = W_koop
 
         # 5. 调整谱半径

+ 1 - 1
TrajTrans/StateOnly/ESN/KoopmanESNTest.py

@@ -57,7 +57,7 @@ for train_start in StartList:
     )
 
     ESNconfig = KoopmanESNConfig(
-        units=1000,
+        units=100,
         lr=lr,
         sr=sr,
         sp=sp,

BIN
TrajTrans/StateOnly/ESN/ModelLib/DeepKoopmanModel.pt


BIN
TrajTrans/StateOnly/ESN/__pycache__/DeepKoopmanModel.cpython-311.pyc


BIN
TrajTrans/StateOnly/ESN/__pycache__/KoopmanESNModel.cpython-311.pyc