├── FLSL ├── _Part │ └── part_evaluate.py ├── support_SSA.py ├── Center.py ├── L_SSA1.py ├── L_SSA2.py ├── L_SSA4.py ├── L_SSA5.py └── L_SSA3.py └── README.md /FLSL/_Part/part_evaluate.py: -------------------------------------------------------------------------------- 1 | 2 | import math 3 | from sklearn.metrics import mean_squared_error 4 | from sklearn.metrics import mean_absolute_error 5 | from sklearn.metrics import r2_score 6 | 7 | 8 | def MAPE1(true,predict): 9 | 10 | L1 = int(len(true)) 11 | L2 = int(len(predict)) 12 | 13 | if L1 == L2: 14 | 15 | SUM = 0.0 16 | for i in range(L1): 17 | if true[i] == 0: 18 | SUM = abs(predict[i]) + SUM 19 | else: 20 | SUM = abs((true[i] - predict[i]) / true[i]) + SUM 21 | per_SUM = SUM * 100.0 22 | mape = per_SUM / L1 23 | return mape 24 | else: 25 | print("error") 26 | 27 | 28 | def RMSE1(true_data, predict_data): 29 | testY = true_data 30 | testPredict = predict_data 31 | rmse = math.sqrt( mean_squared_error(testY[:], testPredict[:])) 32 | return rmse 33 | 34 | 35 | def MAE1(true_data, predict_data): 36 | testY = true_data 37 | testPredict = predict_data 38 | mae=mean_absolute_error(testY[:], testPredict[:]) 39 | return mae 40 | 41 | 42 | def R2(y_true, y_predict): 43 | score = r2_score(y_true, y_predict) 44 | return score 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /FLSL/support_SSA.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | # import matplotlib.pyplot as plt 3 | 4 | #data:(9608,1) 5 | def SSA(series, level): 6 | # series = 0 7 | # series = series - np.mean(series) 8 | original_mean = np.mean(series) 9 | series = series - original_mean 10 | 11 | 12 | windowLen = level 13 | seriesLen = len(series) 14 | K = seriesLen - windowLen + 1 15 | series = series.flatten() 16 | X = np.zeros((windowLen, K)) 17 | for i in range(K): 18 | X[:, i] = series[i:i + windowLen] 19 | 20 | U, sigma, VT = np.linalg.svd(X, full_matrices=False) 21 | 22 | for i in range(VT.shape[0]): 23 | VT[i, :] *= sigma[i] 24 | A = VT 25 | 26 | 27 | rec = np.zeros((windowLen, seriesLen)) 28 | for i in range(windowLen): 29 | for j in range(windowLen - 1): 30 | for m in range(j + 1): 31 | rec[i, j] += A[i, j - m] * U[m, i] 32 | rec[i, j] /= (j + 1) 33 | for j in range(windowLen - 1, seriesLen - windowLen + 1): 34 | for m in range(windowLen): 35 | rec[i, j] += A[i, j - m] * U[m, i] 36 | rec[i, j] /= windowLen 37 | for j in range(seriesLen - windowLen + 1, seriesLen): 38 | for m in range(j - seriesLen + windowLen, windowLen): 39 | rec[i, j] += A[i, j - m] * U[m, i] 40 | rec[i, j] /= (seriesLen - j) 41 | # for i in range(windowLen): 42 | # rec[i, :] += original_mean 43 | return rec 44 | 45 | 46 | # rrr = np.sum(rec, axis=0) 47 | # 48 | # plt.figure() 49 | # for i in range(10): 50 | # ax = plt.subplot(5, 2, i + 1) 51 | # ax.plot(rec[i, :]) 52 | # 53 | # plt.figure(2) 54 | # plt.plot(series) 55 | # plt.show() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🔥 FLSL 2 | A method combined federated learning, representation learning and traditional deep learning for household energy consumption forecasting. 3 | 4 | # 📚 Requirements 5 | Dependent libraries are placed in a file named 'requirements.txt'. 6 | Requirements(Briefly): 7 | python==3.7.8 8 | torch==1.7.1 9 | torchvision==0.8.2 10 | torchaudio==0.7.2 11 | pandas 12 | matplotlib 13 | scikit-learn 14 | 15 | # 🌟 Citation 16 | 17 | If you find our repo useful for your research, please consider giving a 🌟 and citing our work below. 18 | 19 | ``` 20 | @article{JIN2022101442, 21 | title = {Highly accurate energy consumption forecasting model based on parallel LSTM neural networks}, 22 | journal = {Advanced Engineering Informatics}, 23 | volume = {51}, 24 | pages = {101442}, 25 | year = {2022}, 26 | issn = {1474-0346}, 27 | doi = {https://doi.org/10.1016/j.aei.2021.101442}, 28 | url = {https://www.sciencedirect.com/science/article/pii/S1474034621001944}, 29 | author = {Ning Jin and Fan Yang and Yuchang Mo and Yongkang Zeng and Xiaokang Zhou and Ke Yan and Xiang Ma} 30 | } 31 | 32 | @article{YANG2023101846, 33 | title = {Multiple households energy consumption forecasting using consistent modeling with privacy preservation}, 34 | journal = {Advanced Engineering Informatics}, 35 | volume = {55}, 36 | pages = {101846}, 37 | year = {2023}, 38 | issn = {1474-0346}, 39 | doi = {https://doi.org/10.1016/j.aei.2022.101846}, 40 | url = {https://www.sciencedirect.com/science/article/pii/S1474034622003044}, 41 | author = {Fan Yang and Ke Yan and Ning Jin and Yang Du} 42 | } 43 | ``` 44 | 45 | # 🔐 License 46 | The source code is free for research and education use only. Any commercial use should get formal permission first. 47 | -------------------------------------------------------------------------------- /FLSL/Center.py: -------------------------------------------------------------------------------- 1 | 2 | import pickle 3 | import socket 4 | import time 5 | import struct 6 | 7 | def log(info): 8 | print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + ' ' + str(info)) 9 | 10 | Epoch = 16 11 | 12 | def m1(*args): 13 | import copy 14 | result = copy.deepcopy(args[0]) 15 | for i in range(1, len(args)): 16 | for j in range(len(result)): 17 | result[j] += args[i][j] 18 | 19 | for i in range(len(args)): 20 | for j in range(len(args[0])): 21 | args[i][j] = result[j] / len(args) 22 | 23 | def m2(*args): 24 | import copy 25 | result = copy.deepcopy(args[0]) 26 | for i in range(1, len(args)): 27 | # print(args[i]) 28 | for j in range(len(result)): 29 | for k in range(len(result[0])): 30 | result[j][k] += args[i][j][k] 31 | 32 | for i in range(len(args)): 33 | for j in range(len(result)): 34 | for k in range(len(result[0])): 35 | args[i][j][k] = result[j][k] / len(args) 36 | 37 | 38 | def socket_udp_server(): 39 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 40 | host = '127.0.0.1' 41 | port = 7002 42 | s.bind((host, port)) 43 | s.listen(5) 44 | print('waiting for connecting') 45 | 46 | for cnt in range(1, Epoch + 1): 47 | log(f"第{cnt}轮开始接收并计时") 48 | connected_socks = [] 49 | res = [] 50 | 51 | while len(connected_socks) < 5: 52 | try: 53 | s.settimeout(3000) 54 | sock, addr = s.accept() 55 | log(f'Connection accepted from {addr}') 56 | 57 | data_length_bytes = sock.recv(4) 58 | if not data_length_bytes: 59 | raise ValueError("未接收到数据长度信息") 60 | data_length = int.from_bytes(data_length_bytes, byteorder='big') 61 | 62 | received_data = b'' 63 | while len(received_data) < data_length: 64 | packet = sock.recv(data_length - len(received_data)) 65 | if not packet: 66 | raise ConnectionError("连接中断") 67 | received_data += packet 68 | 69 | tmp = pickle.loads(received_data) 70 | log('Received data: ...') 71 | if tmp['num'] == cnt: 72 | connected_socks.append(sock) 73 | res.append(tmp['model']) 74 | 75 | except socket.timeout: 76 | log("接收数据超时。") 77 | break 78 | except Exception as e: 79 | log(f"接收数据时发生异常: {e}") 80 | 81 | if res: 82 | log(f"第{cnt}轮接收完毕,接收来自{len(res)}个节点的参数") 83 | 84 | log("开始融合处理操作......") 85 | 86 | for m, n in zip(res[0].values(), res[1].values()): 87 | if len(m.size()) == 1: 88 | m1(m, n) 89 | elif len(m.size()) == 2: 90 | m2(m, n) 91 | 92 | data = {} 93 | data['num'] = cnt 94 | data['model'] = res[0] 95 | log('第%d轮融合完毕,下发......' % cnt) 96 | data = pickle.dumps(data) 97 | 98 | 99 | 100 | for sock in connected_socks: 101 | try: 102 | # ack_message = 'ACK'.encode() 103 | # sock.sendall(ack_message) 104 | 105 | data_length = len(data) 106 | packed_length = struct.pack('!I', data_length) 107 | sock.sendall(packed_length) 108 | 109 | sock.sendall(data) 110 | except Exception as e: 111 | log(f"发送数据时出错: {e}") 112 | finally: 113 | sock.close() 114 | log('Data sent and connections closed.') 115 | 116 | 117 | connected_socks.clear() 118 | 119 | s.close() 120 | log('All epochs completed, server shutdown.') 121 | 122 | def main(): 123 | socket_udp_server() 124 | 125 | if __name__ == '__main__': 126 | main() 127 | -------------------------------------------------------------------------------- /FLSL/L_SSA1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | 3 | import pickle 4 | # import re 5 | import socket 6 | import time 7 | import torch 8 | # from matplotlib.animation import FuncAnimation 9 | from torch import nn 10 | import pandas as pd 11 | import matplotlib.pyplot as plt 12 | from pandas import read_csv 13 | from sklearn.preprocessing import MinMaxScaler 14 | # from sklearn.preprocessing import StandardScaler 15 | # from sklearn import metrics 16 | # import numpy as np 17 | from support_SSA import SSA 18 | import numpy as np 19 | # from torch.utils.data import TensorDataset, DataLoader 20 | # from sklearn import tree 21 | # from sklearn import ensemble 22 | # from sklearn.neural_network import MLPRegressor 23 | # from sklearn import svm 24 | from sklearn.metrics import mean_squared_error as MSE1 25 | from sklearn.metrics import mean_absolute_error as MAE1 26 | from sklearn import metrics 27 | # import struct 28 | 29 | 30 | class LSTM(nn.Module): 31 | def __init__(self, input_size=1, hidden_size=4, output_size=1, num_layer=1,bidirectional=True): 32 | super(LSTM, self).__init__() 33 | self.layer1 = nn.LSTM(input_size, hidden_size, num_layer,bidirectional=bidirectional) 34 | self.layer2 = nn.Linear(hidden_size * 2 if bidirectional else hidden_size, output_size) 35 | 36 | 37 | def forward(self, x): 38 | x, _ = self.layer1(x) 39 | x = torch.relu(x) 40 | s, b, h = x.size() 41 | x = x.view(s * b, h) 42 | x = self.layer2(x) 43 | x = x.view(s, b, -1) 44 | return x[:,-1,:] 45 | 46 | 47 | look_back = 10 48 | EPOCH = 16 49 | head = [None for i in range(look_back)] 50 | SIZE = 8500 51 | original_mean = 0 52 | 53 | plt.rcParams['font.sans-serif'] = ['SimHei'] 54 | plt.rcParams['axes.unicode_minus'] = False 55 | scaler = MinMaxScaler(feature_range=(0, 1)) 56 | #scaler_target = StandardScaler(copy=True, with_mean=True, with_std=True) 57 | 58 | def log(info): 59 | print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + ' ' + str(info)) 60 | def add_noise(parameters): 61 | parameters = parameters.to(device) 62 | noise = torch.randn(parameters.shape, device=device).normal_(0, 0.01) 63 | return parameters.add_(noise) 64 | def MAPE1(y_true, y_pred): 65 | y_true, y_pred = np.array(y_true), np.array(y_pred) 66 | return np.mean(np.abs((y_true - y_pred) / y_true)) * 100 67 | 68 | def create_dataset(dataset): 69 | dataX, dataY = [], [] 70 | for i in range(len(dataset) - look_back): 71 | dataX.append(dataset[i:(i + look_back), 0]) 72 | dataY.append(dataset[i + look_back, 0]) 73 | 74 | data_X = np.array(dataX) 75 | data_Y = np.array(dataY) 76 | train_X = data_X[:7000] 77 | train_Y = data_Y[:7000] 78 | val_X = data_X[7000:8000] 79 | val_Y = data_Y[7000:8000] 80 | test_X = data_X[8000:10000] 81 | test_Y = data_Y[8000:10000] 82 | 83 | train_X = train_X.reshape(train_X.shape[0], train_X.shape[1], 1) 84 | train_Y = train_Y.reshape(-1, 1, 1) 85 | val_X = val_X.reshape(val_X.shape[0], val_X.shape[1], 1) 86 | val_Y = val_Y.reshape(-1, 1, 1) 87 | test_X = test_X.reshape(test_X.shape[0], test_X.shape[1], 1) 88 | test_Y = test_Y.reshape(-1, 1, 1) 89 | 90 | return train_X, train_Y, val_X, val_Y, test_X, test_Y 91 | 92 | 93 | def __coeffs_to_list(coeffs, devicce): 94 | level_list = [] 95 | for level in range(len(coeffs)): 96 | var_x, var_y, var_valX, val_Y,var_testX, test_Y = create_dataset(coeffs[level]) 97 | 98 | level_part = [torch.from_numpy(var).float().to(device) for var in [var_x, var_y, var_valX, val_Y, var_testX, test_Y]] 99 | level_list.append(level_part) 100 | return level_list 101 | 102 | def __preprocessing_SSA(data, device): 103 | result_ssa = SSA(data.reshape(-1, ), 4) 104 | result_ssa = result_ssa.tolist() 105 | for i in range(len(result_ssa)): 106 | result_ssa[i] = np.array(result_ssa[i]).reshape(-1, 1) 107 | result_ssa = __coeffs_to_list(result_ssa,device) 108 | 109 | return result_ssa 110 | 111 | def fl_data_load(path, device): 112 | dataframe = read_csv(path, engine='python') 113 | 114 | dataset = dataframe[0:10000].values 115 | dataset = dataset.reshape(-1, 1) 116 | dataset = dataset.astype('float32') 117 | np.random.seed(7) 118 | 119 | dataset = scaler.fit_transform(dataset) 120 | 121 | original_mean = np.mean(dataset) 122 | 123 | data_SSA = __preprocessing_SSA(dataset, device) 124 | 125 | return data_SSA, original_mean 126 | 127 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 128 | print("Using device:", device) 129 | 130 | path = r"../../Dataset/house1_5min_KWh.csv" 131 | data_SSA, original_mean = fl_data_load(path, device) 132 | 133 | time_steps, input_dim, output_dim = 10, 1, 1 134 | test_size = 1000 135 | 136 | 137 | model = LSTM(1, 4, 1, 2) 138 | model.to(device) 139 | print(model) 140 | loss_fun = nn.MSELoss() 141 | optimizer = torch.optim.Adam(model.parameters(), lr=0.05) 142 | 143 | 144 | losses = list() 145 | steps = list() 146 | 147 | 148 | for epoch in range(1, EPOCH + 1): 149 | log("\033[1;31;40m第\033[1;31;40m%s\033[1;31;40m轮开始训练!\033[1;31;40m" % str(epoch)) 150 | 151 | for subSignal_index in range(len(data_SSA)): 152 | print(str(subSignal_index+1) + '_level SSA data Start.') 153 | 154 | for t in range(10): 155 | loss_t = list() 156 | out = model(data_SSA[subSignal_index][0]) 157 | loss = loss_fun(out, data_SSA[subSignal_index][1].squeeze(-1)) 158 | print(loss) 159 | loss_t.append(loss.item()) 160 | optimizer.zero_grad() 161 | loss.backward() 162 | optimizer.step() 163 | 164 | losses.append(sum(loss_t)/len(loss_t)) 165 | steps.append(epoch) 166 | print(str(subSignal_index + 1) + '_level SSA data Complete!!\n') 167 | 168 | log("建立连接并上传......") 169 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 170 | 171 | host = '127.0.0.1' 172 | port = 7002 173 | 174 | s.connect((host, port)) 175 | 176 | data = {} 177 | data['num'] = epoch 178 | data['model'] = model.state_dict() 179 | 180 | torch.save(model.state_dict(), 'model.pth') 181 | 182 | keys = model.state_dict().keys() 183 | data = pickle.dumps(data) 184 | 185 | data_length = len(data) 186 | s.sendall(data_length.to_bytes(4, byteorder='big')) 187 | 188 | s.sendall(data) 189 | 190 | log("等待接收......") 191 | try: 192 | s.settimeout(1000) 193 | data_length_bytes = s.recv(4) 194 | if not data_length_bytes: 195 | raise ValueError("未接收到数据长度信息") 196 | data_length = int.from_bytes(data_length_bytes, 'big') 197 | 198 | received_data = b'' 199 | while len(received_data) < data_length: 200 | packet = s.recv(data_length - len(received_data)) 201 | if not packet: 202 | raise ConnectionError("连接中断") 203 | received_data += packet 204 | 205 | data = pickle.loads(received_data) 206 | print(data['num'], epoch) 207 | if data['num'] == epoch: 208 | global_state_dict = data['model'] 209 | else: 210 | global_state_dict = model.state_dict() 211 | except Exception as e: 212 | print(e) 213 | # s.sendto(data, (host, port)) 214 | log("没有在规定时间收到正确的包, 利用本地参数更新") 215 | global_state_dict = model.state_dict() 216 | 217 | model.load_state_dict(global_state_dict) 218 | s.close() 219 | log("训练完毕,关闭连接") 220 | s.close() 221 | 222 | plt.plot(steps, losses, "o-") 223 | plt.xlabel("epoch") 224 | plt.ylabel("loss") 225 | plt.title('Training and Validation Loss') 226 | plt.legend() 227 | plt.draw() 228 | plt.pause(0.1) 229 | plt.savefig('loss_curve1.png') 230 | 231 | plt.close() 232 | 233 | predict_list = [] 234 | test_y_list = [] 235 | for subSignal_index in range(len(data_SSA)): 236 | print('No.' + str( subSignal_index+1) + 'Prediction Start.') 237 | 238 | with torch.no_grad(): 239 | model.eval() 240 | 241 | predictions_pytorch_forecast = model(data_SSA[subSignal_index][4]).cpu() 242 | predict = predictions_pytorch_forecast 243 | predict_list.append(predict) 244 | test_y_list.append(data_SSA[subSignal_index][5].cpu()) 245 | print('No.' + str( subSignal_index+1) + 'Prediction Complete.') 246 | 247 | 248 | predict_array = np.stack([tensor.numpy() for tensor in predict_list]) 249 | summed_predictions = np.sum(predict_array, axis=0) 250 | predict = summed_predictions.squeeze() 251 | predict = predict + original_mean 252 | 253 | test_y_array = np.stack([tensor.numpy() for tensor in test_y_list]) 254 | summed_test_y = np.sum(test_y_array, axis=0) 255 | test_y = summed_test_y.squeeze() 256 | test_y = test_y + original_mean 257 | 258 | pred_testY_origin = scaler.inverse_transform(predict.reshape(-1, 1)) 259 | test_Y_origin = scaler.inverse_transform(test_y.reshape(-1, 1)) 260 | ############################### 261 | 262 | 263 | Dict_Prediction_data = {} 264 | data_test = pd.DataFrame(test_Y_origin) 265 | data_test.to_csv(r"./myresult/test1.csv", index=False, header=False) 266 | data_pre = pd.DataFrame(pred_testY_origin) 267 | data_pre.to_csv(r"./myresult/pre1.csv", index=False, header=False) 268 | 269 | plt.figure() 270 | plt.plot(test_Y_origin, label='Actual', color='blue') 271 | plt.plot(pred_testY_origin, label='Predicted', color='red') 272 | plt.legend() 273 | plt.title('Actual vs Predicted') 274 | plt.xlabel('Index') 275 | plt.ylabel('Value') 276 | plt.savefig('./myresult/res1.png') 277 | 278 | MAPE = MAPE1(test_Y_origin,pred_testY_origin) 279 | MSE = MSE1(test_Y_origin,pred_testY_origin) 280 | RMSE = np.sqrt(MSE1(test_Y_origin,pred_testY_origin)) 281 | MAE = MAE1(test_Y_origin,pred_testY_origin) 282 | R2 = metrics.r2_score(test_Y_origin, pred_testY_origin) 283 | 284 | print("MAPE:{:.6f}".format(MAPE)) 285 | print("MAE:{:.6f}".format(MAE)) 286 | print("MSE:{:.6f}".format(MSE)) 287 | print("RMSE:{:.6f}".format(RMSE)) 288 | print("R2:{:.6f}".format(R2)) 289 | 290 | data = pd.DataFrame({'time': range(0, len(test_Y_origin)), 291 | 'r': test_Y_origin[:, 0], 292 | 'p': pred_testY_origin[:, 0]}) 293 | fig, ax = plt.subplots() 294 | 295 | 296 | 297 | 298 | 299 | -------------------------------------------------------------------------------- /FLSL/L_SSA2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | import pickle 3 | import re 4 | import socket 5 | import time 6 | import torch 7 | from matplotlib.animation import FuncAnimation 8 | from torch import nn 9 | import pandas as pd 10 | import matplotlib.pyplot as plt 11 | from pandas import read_csv 12 | from sklearn.preprocessing import MinMaxScaler 13 | from sklearn.preprocessing import StandardScaler 14 | from sklearn import metrics 15 | import numpy as np 16 | from support_SSA import SSA 17 | import numpy as np 18 | from torch.utils.data import TensorDataset, DataLoader 19 | from sklearn import tree 20 | from sklearn import ensemble 21 | from sklearn.neural_network import MLPRegressor 22 | from sklearn import svm 23 | from sklearn.metrics import mean_squared_error as MSE1 24 | from sklearn.metrics import mean_absolute_error as MAE1 25 | from sklearn import metrics 26 | import struct 27 | 28 | class LSTM(nn.Module): 29 | def __init__(self, input_size=1, hidden_size=4, output_size=1, num_layer=1,bidirectional=True): 30 | super(LSTM, self).__init__() 31 | self.layer1 = nn.LSTM(input_size, hidden_size, num_layer,bidirectional=bidirectional) 32 | self.layer2 = nn.Linear(hidden_size * 2 if bidirectional else hidden_size, output_size) 33 | 34 | def forward(self, x): 35 | x, _ = self.layer1(x) 36 | x = torch.relu(x) 37 | s, b, h = x.size() 38 | x = x.view(s * b, h) 39 | x = self.layer2(x) 40 | x = x.view(s, b, -1) 41 | return x[:,-1,:] 42 | 43 | 44 | look_back = 10 45 | EPOCH = 16 46 | head = [None for i in range(look_back)] 47 | SIZE = 8500 48 | original_mean = 0 49 | 50 | plt.rcParams['font.sans-serif'] = ['SimHei'] 51 | plt.rcParams['axes.unicode_minus'] = False 52 | scaler = MinMaxScaler(feature_range=(0, 1)) 53 | #scaler_target = StandardScaler(copy=True, with_mean=True, with_std=True) 54 | 55 | def log(info): 56 | print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + ' ' + str(info)) 57 | def add_noise(parameters): 58 | parameters = parameters.to(device) 59 | noise = torch.randn(parameters.shape, device=device).normal_(0, 0.01) 60 | return parameters.add_(noise) 61 | def MAPE1(y_true, y_pred): 62 | y_true, y_pred = np.array(y_true), np.array(y_pred) 63 | return np.mean(np.abs((y_true - y_pred) / y_true)) * 100 64 | 65 | 66 | def create_dataset(dataset): 67 | dataX, dataY = [], [] 68 | for i in range(len(dataset) - look_back): 69 | dataX.append(dataset[i:(i + look_back), 0]) 70 | dataY.append(dataset[i + look_back, 0]) 71 | 72 | data_X = np.array(dataX) 73 | data_Y = np.array(dataY) 74 | train_X = data_X[:7000] 75 | train_Y = data_Y[:7000] 76 | val_X = data_X[7000:8000] 77 | val_Y = data_Y[7000:8000] 78 | test_X = data_X[8000:10000] 79 | test_Y = data_Y[8000:10000] 80 | 81 | train_X = train_X.reshape(train_X.shape[0], train_X.shape[1], 1) 82 | train_Y = train_Y.reshape(-1, 1, 1) 83 | val_X = val_X.reshape(val_X.shape[0], val_X.shape[1], 1) 84 | val_Y = val_Y.reshape(-1, 1, 1) 85 | test_X = test_X.reshape(test_X.shape[0], test_X.shape[1], 1) 86 | test_Y = test_Y.reshape(-1, 1, 1) 87 | 88 | return train_X, train_Y, val_X, val_Y, test_X, test_Y 89 | 90 | 91 | def __coeffs_to_list(coeffs, devicce): 92 | level_list = [] 93 | for level in range(len(coeffs)): 94 | var_x, var_y, var_valX, val_Y,var_testX, test_Y = create_dataset(coeffs[level]) 95 | level_part = [torch.from_numpy(var).float().to(device) for var in [var_x, var_y, var_valX, val_Y, var_testX, test_Y]] 96 | level_list.append(level_part) 97 | return level_list 98 | 99 | ## SSA preprocessing 100 | def __preprocessing_SSA(data, device): 101 | result_ssa = SSA(data.reshape(-1, ), 4) 102 | result_ssa = result_ssa.tolist() 103 | for i in range(len(result_ssa)): 104 | result_ssa[i] = np.array(result_ssa[i]).reshape(-1, 1) 105 | result_ssa = __coeffs_to_list(result_ssa,device) 106 | return result_ssa 107 | 108 | # load the dataset 109 | def fl_data_load(path, device): 110 | dataframe = read_csv(path, engine='python') 111 | 112 | dataset = dataframe[0:10000].values 113 | dataset = dataset.reshape(-1, 1) 114 | dataset = dataset.astype('float32') 115 | np.random.seed(7) 116 | 117 | dataset = scaler.fit_transform(dataset) 118 | 119 | original_mean = np.mean(dataset) 120 | 121 | data_SSA = __preprocessing_SSA(dataset, device) 122 | 123 | return data_SSA, original_mean 124 | 125 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 126 | print("Using device:", device) 127 | 128 | path = r"../../Dataset/house2_5min_KWh.csv" 129 | data_SSA, original_mean = fl_data_load(path, device) 130 | 131 | time_steps, input_dim, output_dim = 10, 1, 1 132 | test_size = 1000 133 | 134 | model = LSTM(1, 4, 1, 2) 135 | model.to(device) 136 | print(model) 137 | loss_fun = nn.MSELoss() 138 | optimizer = torch.optim.Adam(model.parameters(), lr=0.05) 139 | 140 | losses = list() 141 | steps = list() 142 | 143 | for epoch in range(1, EPOCH + 1): 144 | log("\033[1;31;40m第\033[1;31;40m%s\033[1;31;40m轮开始训练!\033[1;31;40m" % str(epoch)) 145 | 146 | ############################### 147 | for subSignal_index in range(len(data_SSA)): 148 | print(str(subSignal_index+1) + '_level SSA data Start.') 149 | ######### 150 | 151 | for t in range(10): 152 | loss_t = list() 153 | out = model(data_SSA[subSignal_index][0]) 154 | loss = loss_fun(out, data_SSA[subSignal_index][1].squeeze(-1)) 155 | print(loss) 156 | loss_t.append(loss.item()) 157 | optimizer.zero_grad() 158 | loss.backward() 159 | optimizer.step() 160 | 161 | losses.append(sum(loss_t)/len(loss_t)) 162 | steps.append(epoch) 163 | print(str(subSignal_index + 1) + '_level SSA data Complete!!\n') 164 | 165 | 166 | log("建立连接并上传......") 167 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 168 | 169 | host = '127.0.0.1' 170 | port = 7002 171 | s.connect((host, port)) 172 | 173 | data = {} 174 | data['num'] = epoch 175 | data['model'] = model.state_dict() 176 | 177 | torch.save(model.state_dict(), 'model.pth') 178 | 179 | keys = model.state_dict().keys() 180 | data = pickle.dumps(data) 181 | 182 | data_length = len(data) 183 | s.sendall(data_length.to_bytes(4, byteorder='big')) 184 | 185 | s.sendall(data) 186 | 187 | 188 | log("等待接收......") 189 | try: 190 | s.settimeout(1000) 191 | data_length_bytes = s.recv(4) 192 | if not data_length_bytes: 193 | raise ValueError("未接收到数据长度信息") 194 | data_length = int.from_bytes(data_length_bytes, 'big') 195 | 196 | received_data = b'' 197 | while len(received_data) < data_length: 198 | packet = s.recv(data_length - len(received_data)) 199 | if not packet: 200 | raise ConnectionError("连接中断") 201 | received_data += packet 202 | 203 | data = pickle.loads(received_data) 204 | print(data['num'], epoch) 205 | if data['num'] == epoch: 206 | global_state_dict = data['model'] 207 | else: 208 | global_state_dict = model.state_dict() 209 | except Exception as e: 210 | print(e) 211 | # s.sendto(data, (host, port)) 212 | log("没有在规定时间收到正确的包, 利用本地参数更新") 213 | global_state_dict = model.state_dict() 214 | 215 | # global_state_dict = model.state_dict() 216 | model.load_state_dict(global_state_dict) 217 | s.close() 218 | log("训练完毕,关闭连接") 219 | s.close() 220 | 221 | plt.plot(steps, losses, "o-") 222 | plt.xlabel("epoch") 223 | plt.ylabel("loss") 224 | plt.title('Training and Validation Loss') 225 | plt.legend() 226 | plt.draw() 227 | plt.pause(0.1) 228 | plt.savefig('loss_curve2.png') 229 | plt.close() 230 | 231 | ################################# #-# ###################################### 232 | 233 | 234 | predict_list = [] 235 | test_y_list = [] 236 | for subSignal_index in range(len(data_SSA)): 237 | print('No.' + str( subSignal_index+1) + 'Prediction Start.') 238 | with torch.no_grad(): 239 | model.eval() 240 | 241 | predictions_pytorch_forecast = model(data_SSA[subSignal_index][4]).cpu() 242 | predict = predictions_pytorch_forecast 243 | predict_list.append(predict) 244 | test_y_list.append(data_SSA[subSignal_index][5].cpu()) 245 | print('No.' + str( subSignal_index+1) + 'Prediction Complete.') 246 | 247 | 248 | predict_array = np.stack([tensor.numpy() for tensor in predict_list]) 249 | summed_predictions = np.sum(predict_array, axis=0) 250 | predict = summed_predictions.squeeze() 251 | predict = predict + original_mean 252 | 253 | test_y_array = np.stack([tensor.numpy() for tensor in test_y_list]) 254 | summed_test_y = np.sum(test_y_array, axis=0) 255 | test_y = summed_test_y.squeeze() 256 | test_y = test_y + original_mean 257 | 258 | pred_testY_origin = scaler.inverse_transform(predict.reshape(-1, 1)) 259 | test_Y_origin = scaler.inverse_transform(test_y.reshape(-1, 1)) 260 | ############################### 261 | 262 | 263 | Dict_Prediction_data = {} 264 | data_test = pd.DataFrame(test_Y_origin) 265 | data_test.to_csv(r"./myresult/test2.csv", index=False, header=False) 266 | data_pre = pd.DataFrame(pred_testY_origin) 267 | data_pre.to_csv(r"./myresult/pre2.csv", index=False, header=False) 268 | 269 | plt.figure() 270 | plt.plot(test_Y_origin, label='Actual', color='blue') 271 | plt.plot(pred_testY_origin, label='Predicted', color='red') 272 | plt.legend() 273 | plt.title('Actual vs Predicted') 274 | plt.xlabel('Index') 275 | plt.ylabel('Value') 276 | plt.savefig('./myresult/res2.png') 277 | 278 | MAPE = MAPE1(test_Y_origin,pred_testY_origin) 279 | MSE = MSE1(test_Y_origin,pred_testY_origin) 280 | RMSE = np.sqrt(MSE1(test_Y_origin,pred_testY_origin)) 281 | MAE = MAE1(test_Y_origin,pred_testY_origin) 282 | R2 = metrics.r2_score(test_Y_origin, pred_testY_origin) 283 | 284 | print("MAPE:{:.6f}".format(MAPE)) 285 | print("MAE:{:.6f}".format(MAE)) 286 | print("MSE:{:.6f}".format(MSE)) 287 | print("RMSE:{:.6f}".format(RMSE)) 288 | print("R2:{:.6f}".format(R2)) 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | -------------------------------------------------------------------------------- /FLSL/L_SSA4.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | 3 | import pickle 4 | import re 5 | import socket 6 | import time 7 | import torch 8 | from matplotlib.animation import FuncAnimation 9 | from torch import nn 10 | import pandas as pd 11 | import matplotlib.pyplot as plt 12 | from pandas import read_csv 13 | from sklearn.preprocessing import MinMaxScaler 14 | from sklearn.preprocessing import StandardScaler 15 | from sklearn import metrics 16 | import numpy as np 17 | from support_SSA import SSA 18 | import numpy as np 19 | from torch.utils.data import TensorDataset, DataLoader 20 | from sklearn import tree 21 | from sklearn import ensemble 22 | from sklearn.neural_network import MLPRegressor 23 | from sklearn import svm 24 | from sklearn.metrics import mean_squared_error as MSE1 25 | from sklearn.metrics import mean_absolute_error as MAE1 26 | from sklearn import metrics 27 | import struct 28 | 29 | class LSTM(nn.Module): 30 | def __init__(self, input_size=1, hidden_size=4, output_size=1, num_layer=1,bidirectional=True): 31 | super(LSTM, self).__init__() 32 | self.layer1 = nn.LSTM(input_size, hidden_size, num_layer,bidirectional=bidirectional) 33 | self.layer2 = nn.Linear(hidden_size * 2 if bidirectional else hidden_size, output_size) 34 | 35 | def forward(self, x): 36 | x, _ = self.layer1(x) 37 | x = torch.relu(x) 38 | s, b, h = x.size() 39 | x = x.view(s * b, h) 40 | x = self.layer2(x) 41 | x = x.view(s, b, -1) 42 | return x[:,-1,:] 43 | 44 | 45 | look_back = 10 46 | EPOCH = 16 ## 47 | head = [None for i in range(look_back)] 48 | SIZE = 8500 49 | original_mean = 0 50 | 51 | plt.rcParams['font.sans-serif'] = ['SimHei'] 52 | plt.rcParams['axes.unicode_minus'] = False 53 | scaler = MinMaxScaler(feature_range=(0, 1)) 54 | #scaler_target = StandardScaler(copy=True, with_mean=True, with_std=True) 55 | 56 | def log(info): 57 | print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + ' ' + str(info)) 58 | def add_noise(parameters): 59 | parameters = parameters.to(device) 60 | noise = torch.randn(parameters.shape, device=device).normal_(0, 0.01) 61 | return parameters.add_(noise) 62 | def MAPE1(y_true, y_pred): 63 | y_true, y_pred = np.array(y_true), np.array(y_pred) 64 | return np.mean(np.abs((y_true - y_pred) / y_true)) * 100 65 | 66 | 67 | def create_dataset(dataset): 68 | 69 | dataX, dataY = [], [] 70 | for i in range(len(dataset) - look_back): 71 | dataX.append(dataset[i:(i + look_back), 0]) 72 | dataY.append(dataset[i + look_back, 0]) 73 | 74 | data_X = np.array(dataX) 75 | data_Y = np.array(dataY) 76 | train_X = data_X[:7000] 77 | train_Y = data_Y[:7000] 78 | val_X = data_X[7000:8000] 79 | val_Y = data_Y[7000:8000] 80 | test_X = data_X[8000:10000] 81 | test_Y = data_Y[8000:10000] 82 | 83 | train_X = train_X.reshape(train_X.shape[0], train_X.shape[1], 1) 84 | train_Y = train_Y.reshape(-1, 1, 1) 85 | val_X = val_X.reshape(val_X.shape[0], val_X.shape[1], 1) 86 | val_Y = val_Y.reshape(-1, 1, 1) 87 | test_X = test_X.reshape(test_X.shape[0], test_X.shape[1], 1) 88 | test_Y = test_Y.reshape(-1, 1, 1) 89 | 90 | return train_X, train_Y, val_X, val_Y, test_X, test_Y 91 | 92 | 93 | def __coeffs_to_list(coeffs, devicce): 94 | level_list = [] 95 | for level in range(len(coeffs)): 96 | var_x, var_y, var_valX, val_Y,var_testX, test_Y = create_dataset(coeffs[level]) 97 | level_part = [torch.from_numpy(var).float().to(device) for var in [var_x, var_y, var_valX, val_Y, var_testX, test_Y]] 98 | level_list.append(level_part) 99 | return level_list 100 | 101 | 102 | def __preprocessing_SSA(data, device): 103 | result_ssa = SSA(data.reshape(-1, ), 4) 104 | result_ssa = result_ssa.tolist() 105 | for i in range(len(result_ssa)): 106 | result_ssa[i] = np.array(result_ssa[i]).reshape(-1, 1) 107 | result_ssa = __coeffs_to_list(result_ssa,device) 108 | 109 | return result_ssa 110 | 111 | 112 | def fl_data_load(path, device): 113 | dataframe = read_csv(path, engine='python') 114 | 115 | dataset = dataframe[0:10000].values 116 | dataset = dataset.reshape(-1, 1) 117 | dataset = dataset.astype('float32') 118 | np.random.seed(7) 119 | 120 | 121 | dataset = scaler.fit_transform(dataset) 122 | 123 | original_mean = np.mean(dataset) 124 | 125 | data_SSA = __preprocessing_SSA(dataset, device) 126 | 127 | return data_SSA, original_mean 128 | 129 | ################################################################################################## 130 | 131 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 132 | print("Using device:", device) 133 | 134 | path = r"../../Dataset/house4_5min_KWh.csv" 135 | data_SSA, original_mean = fl_data_load(path, device) 136 | 137 | time_steps, input_dim, output_dim = 10, 1, 1 138 | test_size = 1000 139 | 140 | 141 | model = LSTM(1, 4, 1, 2) 142 | model.to(device) 143 | print(model) 144 | loss_fun = nn.MSELoss() 145 | optimizer = torch.optim.Adam(model.parameters(), lr=0.05) 146 | 147 | 148 | losses = list() 149 | steps = list() 150 | 151 | ################################# #-# ###################################### 152 | for epoch in range(1, EPOCH + 1): 153 | log("\033[1;31;40m第\033[1;31;40m%s\033[1;31;40m轮开始训练!\033[1;31;40m" % str(epoch)) 154 | 155 | for subSignal_index in range(len(data_SSA)): 156 | print(str(subSignal_index+1) + '_level SSA data Start.') 157 | ######### 158 | 159 | for t in range(10): 160 | loss_t = list() 161 | out = model(data_SSA[subSignal_index][0]) 162 | loss = loss_fun(out, data_SSA[subSignal_index][1].squeeze(-1)) 163 | print(loss) 164 | loss_t.append(loss.item()) 165 | optimizer.zero_grad() 166 | loss.backward() 167 | optimizer.step() 168 | 169 | losses.append(sum(loss_t)/len(loss_t)) 170 | steps.append(epoch) 171 | print(str(subSignal_index + 1) + '_level SSA data Complete!!\n') 172 | 173 | log("建立连接并上传......") 174 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 175 | 176 | host = '127.0.0.1' 177 | port = 7002 178 | 179 | s.connect((host, port)) 180 | 181 | data = {} 182 | data['num'] = epoch 183 | data['model'] = model.state_dict() 184 | 185 | torch.save(model.state_dict(), 'model.pth') 186 | 187 | keys = model.state_dict().keys() 188 | data = pickle.dumps(data) 189 | 190 | data_length = len(data) 191 | s.sendall(data_length.to_bytes(4, byteorder='big')) 192 | 193 | s.sendall(data) 194 | 195 | log("等待接收......") 196 | try: 197 | s.settimeout(1000) 198 | data_length_bytes = s.recv(4) 199 | if not data_length_bytes: 200 | raise ValueError("未接收到数据长度信息") 201 | data_length = int.from_bytes(data_length_bytes, 'big') 202 | 203 | received_data = b'' 204 | while len(received_data) < data_length: 205 | packet = s.recv(data_length - len(received_data)) 206 | if not packet: 207 | raise ConnectionError("连接中断") 208 | received_data += packet 209 | 210 | data = pickle.loads(received_data) 211 | print(data['num'], epoch) 212 | if data['num'] == epoch: 213 | global_state_dict = data['model'] 214 | else: 215 | global_state_dict = model.state_dict() 216 | except Exception as e: 217 | print(e) 218 | # s.sendto(data, (host, port)) 219 | log("没有在规定时间收到正确的包, 利用本地参数更新") 220 | global_state_dict = model.state_dict() 221 | 222 | model.load_state_dict(global_state_dict) 223 | s.close() 224 | log("训练完毕,关闭连接") 225 | s.close() 226 | 227 | plt.plot(steps, losses, "o-") 228 | plt.xlabel("epoch") 229 | plt.ylabel("loss") 230 | plt.title('Training and Validation Loss') 231 | plt.legend() 232 | plt.draw() 233 | plt.pause(0.1) 234 | plt.savefig('loss_curve4.png') 235 | plt.close() 236 | 237 | ################################# #-# ###################################### 238 | 239 | predict_list = [] 240 | test_y_list = [] 241 | for subSignal_index in range(len(data_SSA)): 242 | print('No.' + str( subSignal_index+1) + 'Prediction Start.') 243 | with torch.no_grad(): 244 | model.eval() 245 | 246 | predictions_pytorch_forecast = model(data_SSA[subSignal_index][4]).cpu() 247 | predict = predictions_pytorch_forecast 248 | predict_list.append(predict) 249 | test_y_list.append(data_SSA[subSignal_index][5].cpu()) 250 | print('No.' + str( subSignal_index+1) + 'Prediction Complete.') 251 | 252 | 253 | predict_array = np.stack([tensor.numpy() for tensor in predict_list]) 254 | summed_predictions = np.sum(predict_array, axis=0) 255 | predict = summed_predictions.squeeze() 256 | predict = predict + original_mean 257 | 258 | test_y_array = np.stack([tensor.numpy() for tensor in test_y_list]) 259 | summed_test_y = np.sum(test_y_array, axis=0) 260 | test_y = summed_test_y.squeeze() 261 | test_y = test_y + original_mean 262 | 263 | pred_testY_origin = scaler.inverse_transform(predict.reshape(-1, 1)) 264 | test_Y_origin = scaler.inverse_transform(test_y.reshape(-1, 1)) 265 | ############################### 266 | 267 | 268 | Dict_Prediction_data = {} 269 | data_test = pd.DataFrame(test_Y_origin) 270 | data_test.to_csv(r"./myresult/test4.csv", index=False, header=False) 271 | data_pre = pd.DataFrame(pred_testY_origin) 272 | data_pre.to_csv(r"./myresult/pre4.csv", index=False, header=False) 273 | 274 | plt.figure() 275 | plt.plot(test_Y_origin, label='Actual', color='blue') 276 | plt.plot(pred_testY_origin, label='Predicted', color='red') 277 | plt.legend() 278 | plt.title('Actual vs Predicted') 279 | plt.xlabel('Index') 280 | plt.ylabel('Value') 281 | plt.savefig('./myresult/res4.png') 282 | 283 | MAPE = MAPE1(test_Y_origin,pred_testY_origin) 284 | MSE = MSE1(test_Y_origin,pred_testY_origin) 285 | RMSE = np.sqrt(MSE1(test_Y_origin,pred_testY_origin)) 286 | MAE = MAE1(test_Y_origin,pred_testY_origin) 287 | R2 = metrics.r2_score(test_Y_origin, pred_testY_origin) 288 | 289 | print("MAPE:{:.6f}".format(MAPE)) 290 | print("MAE:{:.6f}".format(MAE)) 291 | print("MSE:{:.6f}".format(MSE)) 292 | print("RMSE:{:.6f}".format(RMSE)) 293 | print("R2:{:.6f}".format(R2)) 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | -------------------------------------------------------------------------------- /FLSL/L_SSA5.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | 3 | import pickle 4 | import re 5 | import socket 6 | import time 7 | import torch 8 | from matplotlib.animation import FuncAnimation 9 | from torch import nn 10 | import pandas as pd 11 | import matplotlib.pyplot as plt 12 | from pandas import read_csv 13 | from sklearn.preprocessing import MinMaxScaler 14 | from sklearn.preprocessing import StandardScaler 15 | from sklearn import metrics 16 | import numpy as np 17 | from support_SSA import SSA 18 | import numpy as np 19 | from torch.utils.data import TensorDataset, DataLoader 20 | from sklearn import tree 21 | from sklearn import ensemble 22 | from sklearn.neural_network import MLPRegressor 23 | from sklearn import svm 24 | from sklearn.metrics import mean_squared_error as MSE1 25 | from sklearn.metrics import mean_absolute_error as MAE1 26 | from sklearn import metrics 27 | import struct 28 | 29 | class LSTM(nn.Module): 30 | def __init__(self, input_size=1, hidden_size=4, output_size=1, num_layer=1,bidirectional=True): 31 | super(LSTM, self).__init__() 32 | self.layer1 = nn.LSTM(input_size, hidden_size, num_layer,bidirectional=bidirectional) 33 | self.layer2 = nn.Linear(hidden_size * 2 if bidirectional else hidden_size, output_size) 34 | 35 | def forward(self, x): 36 | x, _ = self.layer1(x) 37 | x = torch.relu(x) 38 | s, b, h = x.size() 39 | x = x.view(s * b, h) 40 | x = self.layer2(x) 41 | x = x.view(s, b, -1) 42 | return x[:,-1,:] 43 | 44 | 45 | look_back = 10 46 | EPOCH = 16 47 | head = [None for i in range(look_back)] 48 | SIZE = 8500 49 | original_mean = 0 50 | 51 | plt.rcParams['font.sans-serif'] = ['SimHei'] 52 | plt.rcParams['axes.unicode_minus'] = False 53 | scaler = MinMaxScaler(feature_range=(0, 1)) 54 | #scaler_target = StandardScaler(copy=True, with_mean=True, with_std=True) 55 | 56 | def log(info): 57 | print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + ' ' + str(info)) 58 | def add_noise(parameters): 59 | parameters = parameters.to(device) 60 | noise = torch.randn(parameters.shape, device=device).normal_(0, 0.01) 61 | return parameters.add_(noise) 62 | def MAPE1(y_true, y_pred): 63 | y_true, y_pred = np.array(y_true), np.array(y_pred) 64 | return np.mean(np.abs((y_true - y_pred) / y_true)) * 100 65 | 66 | def create_dataset(dataset): 67 | 68 | dataX, dataY = [], [] 69 | for i in range(len(dataset) - look_back): 70 | dataX.append(dataset[i:(i + look_back), 0]) 71 | dataY.append(dataset[i + look_back, 0]) 72 | 73 | data_X = np.array(dataX) 74 | data_Y = np.array(dataY) 75 | train_X = data_X[:7000] 76 | train_Y = data_Y[:7000] 77 | val_X = data_X[7000:8000] 78 | val_Y = data_Y[7000:8000] 79 | test_X = data_X[8000:10000] 80 | test_Y = data_Y[8000:10000] 81 | 82 | train_X = train_X.reshape(train_X.shape[0], train_X.shape[1], 1) 83 | train_Y = train_Y.reshape(-1, 1, 1) 84 | val_X = val_X.reshape(val_X.shape[0], val_X.shape[1], 1) 85 | val_Y = val_Y.reshape(-1, 1, 1) 86 | test_X = test_X.reshape(test_X.shape[0], test_X.shape[1], 1) 87 | test_Y = test_Y.reshape(-1, 1, 1) 88 | 89 | return train_X, train_Y, val_X, val_Y, test_X, test_Y 90 | 91 | def __coeffs_to_list(coeffs, devicce): 92 | level_list = [] 93 | for level in range(len(coeffs)): 94 | var_x, var_y, var_valX, val_Y,var_testX, test_Y = create_dataset(coeffs[level]) 95 | level_part = [torch.from_numpy(var).float().to(device) for var in [var_x, var_y, var_valX, val_Y, var_testX, test_Y]] 96 | level_list.append(level_part) 97 | return level_list 98 | 99 | def __preprocessing_SSA(data, device): 100 | result_ssa = SSA(data.reshape(-1, ), 4) 101 | result_ssa = result_ssa.tolist() 102 | for i in range(len(result_ssa)): 103 | result_ssa[i] = np.array(result_ssa[i]).reshape(-1, 1) 104 | result_ssa = __coeffs_to_list(result_ssa,device) 105 | 106 | return result_ssa 107 | 108 | # load the dataset 109 | def fl_data_load(path, device): 110 | dataframe = read_csv(path, engine='python') 111 | 112 | dataset = dataframe[0:10000].values 113 | dataset = dataset.reshape(-1, 1) 114 | dataset = dataset.astype('float32') 115 | np.random.seed(7) 116 | 117 | dataset = scaler.fit_transform(dataset) 118 | 119 | original_mean = np.mean(dataset) 120 | 121 | data_SSA = __preprocessing_SSA(dataset, device) 122 | 123 | return data_SSA, original_mean 124 | 125 | ################################################################################################## 126 | 127 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 128 | print("Using device:", device) 129 | 130 | path = r"../../Dataset/house5_5min_KWh.csv" 131 | data_SSA, original_mean = fl_data_load(path, device) 132 | 133 | time_steps, input_dim, output_dim = 10, 1, 1 134 | test_size = 1000 135 | 136 | 137 | model = LSTM(1, 4, 1, 2) 138 | model.to(device) 139 | print(model) 140 | loss_fun = nn.MSELoss() 141 | optimizer = torch.optim.Adam(model.parameters(), lr=0.05) 142 | 143 | 144 | losses = list() 145 | steps = list() 146 | 147 | ################################# #-# ###################################### 148 | for epoch in range(1, EPOCH + 1): 149 | log("\033[1;31;40m第\033[1;31;40m%s\033[1;31;40m轮开始训练!\033[1;31;40m" % str(epoch)) 150 | 151 | for subSignal_index in range(len(data_SSA)): 152 | print(str(subSignal_index+1) + '_level SSA data Start.') 153 | 154 | for t in range(10): 155 | loss_t = list() 156 | out = model(data_SSA[subSignal_index][0]) 157 | loss = loss_fun(out, data_SSA[subSignal_index][1].squeeze(-1)) 158 | print(loss) 159 | loss_t.append(loss.item()) 160 | optimizer.zero_grad() 161 | loss.backward() 162 | optimizer.step() 163 | 164 | losses.append(sum(loss_t)/len(loss_t)) 165 | steps.append(epoch) 166 | print(str(subSignal_index + 1) + '_level SSA data Complete!!\n') 167 | 168 | 169 | log("建立连接并上传......") 170 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 171 | host = '127.0.0.1' 172 | port = 7002 173 | s.connect((host, port)) 174 | data = {} 175 | data['num'] = epoch 176 | data['model'] = model.state_dict() 177 | 178 | torch.save(model.state_dict(), 'model.pth') 179 | 180 | keys = model.state_dict().keys() 181 | data = pickle.dumps(data) 182 | 183 | data_length = len(data) 184 | s.sendall(data_length.to_bytes(4, byteorder='big')) 185 | 186 | s.sendall(data) 187 | 188 | log("等待接收......") 189 | try: 190 | s.settimeout(1000) 191 | data_length_bytes = s.recv(4) 192 | if not data_length_bytes: 193 | raise ValueError("未接收到数据长度信息") 194 | data_length = int.from_bytes(data_length_bytes, 'big') 195 | 196 | received_data = b'' 197 | while len(received_data) < data_length: 198 | packet = s.recv(data_length - len(received_data)) 199 | if not packet: 200 | raise ConnectionError("连接中断") 201 | received_data += packet 202 | 203 | data = pickle.loads(received_data) 204 | print(data['num'], epoch) 205 | if data['num'] == epoch: 206 | global_state_dict = data['model'] 207 | else: 208 | global_state_dict = model.state_dict() 209 | except Exception as e: 210 | print(e) 211 | # s.sendto(data, (host, port)) 212 | log("没有在规定时间收到正确的包, 利用本地参数更新") 213 | global_state_dict = model.state_dict() 214 | 215 | # global_state_dict = model.state_dict() 216 | model.load_state_dict(global_state_dict) 217 | s.close() 218 | log("训练完毕,关闭连接") 219 | s.close() 220 | 221 | plt.plot(steps, losses, "o-") 222 | plt.xlabel("epoch") 223 | plt.ylabel("loss") 224 | plt.title('Training and Validation Loss') 225 | plt.legend() 226 | plt.draw() 227 | plt.pause(0.1) 228 | plt.savefig('loss_curve5.png') 229 | plt.close() 230 | 231 | ################################# #-# ###################################### 232 | 233 | predict_list = [] 234 | test_y_list = [] 235 | for subSignal_index in range(len(data_SSA)): 236 | print('No.' + str( subSignal_index+1) + 'Prediction Start.') 237 | with torch.no_grad(): 238 | model.eval() 239 | 240 | predictions_pytorch_forecast = model(data_SSA[subSignal_index][4]).cpu() 241 | predict = predictions_pytorch_forecast 242 | predict_list.append(predict) 243 | test_y_list.append(data_SSA[subSignal_index][5].cpu()) 244 | print('No.' + str( subSignal_index+1) + 'Prediction Complete.') 245 | 246 | 247 | predict_array = np.stack([tensor.numpy() for tensor in predict_list]) 248 | summed_predictions = np.sum(predict_array, axis=0) 249 | predict = summed_predictions.squeeze() 250 | predict = predict + original_mean 251 | 252 | test_y_array = np.stack([tensor.numpy() for tensor in test_y_list]) 253 | summed_test_y = np.sum(test_y_array, axis=0) 254 | test_y = summed_test_y.squeeze() 255 | test_y = test_y + original_mean 256 | 257 | pred_testY_origin = scaler.inverse_transform(predict.reshape(-1, 1)) 258 | test_Y_origin = scaler.inverse_transform(test_y.reshape(-1, 1)) 259 | ############################### 260 | 261 | 262 | Dict_Prediction_data = {} 263 | data_test = pd.DataFrame(test_Y_origin) 264 | data_test.to_csv(r"./myresult/test5.csv", index=False, header=False) 265 | data_pre = pd.DataFrame(pred_testY_origin) 266 | data_pre.to_csv(r"./myresult/pre5.csv", index=False, header=False) 267 | 268 | plt.figure() 269 | plt.plot(test_Y_origin, label='Actual', color='blue') 270 | plt.plot(pred_testY_origin, label='Predicted', color='red') 271 | plt.legend() 272 | plt.title('Actual vs Predicted') 273 | plt.xlabel('Index') 274 | plt.ylabel('Value') 275 | plt.savefig('./myresult/res5.png') 276 | 277 | MAPE = MAPE1(test_Y_origin,pred_testY_origin) 278 | MSE = MSE1(test_Y_origin,pred_testY_origin) 279 | RMSE = np.sqrt(MSE1(test_Y_origin,pred_testY_origin)) 280 | MAE = MAE1(test_Y_origin,pred_testY_origin) 281 | R2 = metrics.r2_score(test_Y_origin, pred_testY_origin) 282 | 283 | 284 | print("MAPE:{:.6f}".format(MAPE)) 285 | print("MAE:{:.6f}".format(MAE)) 286 | print("MSE:{:.6f}".format(MSE)) 287 | print("RMSE:{:.6f}".format(RMSE)) 288 | print("R2:{:.6f}".format(R2)) 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | -------------------------------------------------------------------------------- /FLSL/L_SSA3.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | import pickle 3 | import re 4 | import socket 5 | import time 6 | import torch 7 | from matplotlib.animation import FuncAnimation 8 | from torch import nn 9 | import pandas as pd 10 | import matplotlib.pyplot as plt 11 | from pandas import read_csv 12 | from sklearn.preprocessing import MinMaxScaler 13 | from sklearn.preprocessing import StandardScaler 14 | from sklearn import metrics 15 | import numpy as np 16 | from support_SSA import SSA 17 | import numpy as np 18 | from torch.utils.data import TensorDataset, DataLoader 19 | from sklearn import tree 20 | from sklearn import ensemble 21 | from sklearn.neural_network import MLPRegressor 22 | from sklearn import svm 23 | from sklearn.metrics import mean_squared_error as MSE1 24 | from sklearn.metrics import mean_absolute_error as MAE1 25 | from sklearn import metrics 26 | import struct 27 | 28 | class LSTM(nn.Module): 29 | # def __init__(self, input_size=2, hidden_size=4, output_size=1, num_layer=1): 30 | def __init__(self, input_size=1, hidden_size=4, output_size=1, num_layer=1,bidirectional=True): 31 | super(LSTM, self).__init__() 32 | self.layer1 = nn.LSTM(input_size, hidden_size, num_layer,bidirectional=bidirectional) 33 | self.layer2 = nn.Linear(hidden_size * 2 if bidirectional else hidden_size, output_size) 34 | 35 | def forward(self, x): 36 | x, _ = self.layer1(x) 37 | x = torch.relu(x) 38 | s, b, h = x.size() 39 | x = x.view(s * b, h) 40 | x = self.layer2(x) 41 | x = x.view(s, b, -1) 42 | return x[:,-1,:] 43 | 44 | 45 | look_back = 10 46 | EPOCH = 16 47 | head = [None for i in range(look_back)] 48 | SIZE = 8500 49 | original_mean = 0 50 | 51 | plt.rcParams['font.sans-serif'] = ['SimHei'] 52 | plt.rcParams['axes.unicode_minus'] = False 53 | scaler = MinMaxScaler(feature_range=(0, 1)) 54 | #scaler_target = StandardScaler(copy=True, with_mean=True, with_std=True) 55 | 56 | def log(info): 57 | print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + ' ' + str(info)) 58 | def add_noise(parameters): 59 | parameters = parameters.to(device) 60 | noise = torch.randn(parameters.shape, device=device).normal_(0, 0.01) 61 | return parameters.add_(noise) 62 | def MAPE1(y_true, y_pred): 63 | y_true, y_pred = np.array(y_true), np.array(y_pred) 64 | return np.mean(np.abs((y_true - y_pred) / y_true)) * 100 65 | 66 | def create_dataset(dataset): 67 | 68 | dataX, dataY = [], [] 69 | for i in range(len(dataset) - look_back): 70 | dataX.append(dataset[i:(i + look_back), 0]) 71 | dataY.append(dataset[i + look_back, 0]) 72 | 73 | 74 | data_X = np.array(dataX) 75 | data_Y = np.array(dataY) 76 | train_X = data_X[:7000] 77 | train_Y = data_Y[:7000] 78 | val_X = data_X[7000:8000] 79 | val_Y = data_Y[7000:8000] 80 | test_X = data_X[8000:10000] 81 | test_Y = data_Y[8000:10000] 82 | 83 | train_X = train_X.reshape(train_X.shape[0], train_X.shape[1], 1) 84 | train_Y = train_Y.reshape(-1, 1, 1) 85 | val_X = val_X.reshape(val_X.shape[0], val_X.shape[1], 1) 86 | val_Y = val_Y.reshape(-1, 1, 1) 87 | test_X = test_X.reshape(test_X.shape[0], test_X.shape[1], 1) 88 | test_Y = test_Y.reshape(-1, 1, 1) 89 | 90 | return train_X, train_Y, val_X, val_Y, test_X, test_Y 91 | 92 | def __coeffs_to_list(coeffs, devicce): 93 | level_list = [] 94 | for level in range(len(coeffs)): 95 | var_x, var_y, var_valX, val_Y,var_testX, test_Y = create_dataset(coeffs[level]) 96 | level_part = [torch.from_numpy(var).float().to(device) for var in [var_x, var_y, var_valX, val_Y, var_testX, test_Y]] 97 | level_list.append(level_part) 98 | return level_list 99 | 100 | def __preprocessing_SSA(data, device): 101 | result_ssa = SSA(data.reshape(-1, ), 4) 102 | result_ssa = result_ssa.tolist() 103 | for i in range(len(result_ssa)): 104 | result_ssa[i] = np.array(result_ssa[i]).reshape(-1, 1) 105 | result_ssa = __coeffs_to_list(result_ssa,device) 106 | 107 | return result_ssa 108 | 109 | def fl_data_load(path, device): 110 | dataframe = read_csv(path, engine='python') 111 | 112 | dataset = dataframe[0:10000].values 113 | dataset = dataset.reshape(-1, 1) 114 | dataset = dataset.astype('float32') 115 | np.random.seed(7) 116 | 117 | 118 | dataset = scaler.fit_transform(dataset) 119 | 120 | original_mean = np.mean(dataset) 121 | 122 | data_SSA = __preprocessing_SSA(dataset, device) 123 | 124 | return data_SSA, original_mean 125 | 126 | ################################################################################################## 127 | 128 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 129 | print("Using device:", device) 130 | 131 | path = r"../../Dataset/house3_5min_KWh.csv" 132 | data_SSA, original_mean = fl_data_load(path, device) 133 | 134 | time_steps, input_dim, output_dim = 10, 1, 1 135 | test_size = 1000 136 | 137 | 138 | model = LSTM(1, 4, 1, 2) 139 | model.to(device) 140 | print(model) 141 | loss_fun = nn.MSELoss() 142 | optimizer = torch.optim.Adam(model.parameters(), lr=0.05) 143 | 144 | 145 | losses = list() 146 | steps = list() 147 | 148 | ################################# #-# ###################################### 149 | for epoch in range(1, EPOCH + 1): 150 | log("\033[1;31;40m第\033[1;31;40m%s\033[1;31;40m轮开始训练!\033[1;31;40m" % str(epoch)) 151 | 152 | for subSignal_index in range(len(data_SSA)): 153 | print(str(subSignal_index+1) + '_level SSA data Start.') 154 | 155 | for t in range(10): 156 | loss_t = list() 157 | out = model(data_SSA[subSignal_index][0]) 158 | loss = loss_fun(out, data_SSA[subSignal_index][1].squeeze(-1)) 159 | print(loss) 160 | loss_t.append(loss.item()) 161 | optimizer.zero_grad() 162 | loss.backward() 163 | optimizer.step() 164 | 165 | losses.append(sum(loss_t)/len(loss_t)) 166 | steps.append(epoch) 167 | print(str(subSignal_index + 1) + '_level SSA data Complete!!\n') 168 | 169 | 170 | log("建立连接并上传......") 171 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 172 | host = '127.0.0.1' 173 | port = 7002 174 | s.connect((host, port)) 175 | data = {} 176 | data['num'] = epoch 177 | data['model'] = model.state_dict() 178 | 179 | torch.save(model.state_dict(), 'model.pth') 180 | 181 | keys = model.state_dict().keys() 182 | data = pickle.dumps(data) 183 | 184 | data_length = len(data) 185 | s.sendall(data_length.to_bytes(4, byteorder='big')) 186 | 187 | s.sendall(data) 188 | 189 | log("等待接收......") 190 | try: 191 | s.settimeout(1000) 192 | data_length_bytes = s.recv(4) 193 | if not data_length_bytes: 194 | raise ValueError("未接收到数据长度信息") 195 | data_length = int.from_bytes(data_length_bytes, 'big') 196 | 197 | received_data = b'' 198 | while len(received_data) < data_length: 199 | packet = s.recv(data_length - len(received_data)) 200 | if not packet: 201 | raise ConnectionError("连接中断") 202 | received_data += packet 203 | 204 | data = pickle.loads(received_data) 205 | print(data['num'], epoch) 206 | if data['num'] == epoch: 207 | global_state_dict = data['model'] 208 | else: 209 | global_state_dict = model.state_dict() 210 | except Exception as e: 211 | print(e) 212 | # s.sendto(data, (host, port)) 213 | log("没有在规定时间收到正确的包, 利用本地参数更新") 214 | global_state_dict = model.state_dict() 215 | 216 | model.load_state_dict(global_state_dict) 217 | s.close() 218 | log("训练完毕,关闭连接") 219 | s.close() 220 | 221 | plt.plot(steps, losses, "o-") 222 | plt.xlabel("epoch") 223 | plt.ylabel("loss") 224 | plt.title('Training and Validation Loss') 225 | plt.legend() 226 | plt.draw() 227 | plt.pause(0.1) 228 | plt.savefig('loss_curve3.png') 229 | plt.close() 230 | 231 | ################################# #-# ###################################### 232 | 233 | predict_list = [] 234 | test_y_list = [] 235 | for subSignal_index in range(len(data_SSA)): 236 | print('No.' + str( subSignal_index+1) + 'Prediction Start.') 237 | with torch.no_grad(): 238 | model.eval() 239 | 240 | predictions_pytorch_forecast = model(data_SSA[subSignal_index][4]).cpu() 241 | predict = predictions_pytorch_forecast 242 | predict_list.append(predict) 243 | test_y_list.append(data_SSA[subSignal_index][5].cpu()) 244 | print('No.' + str( subSignal_index+1) + 'Prediction Complete.') 245 | 246 | 247 | predict_array = np.stack([tensor.numpy() for tensor in predict_list]) 248 | summed_predictions = np.sum(predict_array, axis=0) 249 | predict = summed_predictions.squeeze() 250 | predict = predict + original_mean 251 | 252 | test_y_array = np.stack([tensor.numpy() for tensor in test_y_list]) 253 | summed_test_y = np.sum(test_y_array, axis=0) 254 | test_y = summed_test_y.squeeze() 255 | test_y = test_y + original_mean 256 | 257 | pred_testY_origin = scaler.inverse_transform(predict.reshape(-1, 1)) 258 | test_Y_origin = scaler.inverse_transform(test_y.reshape(-1, 1)) 259 | ############################### 260 | 261 | Dict_Prediction_data = {} 262 | data_test = pd.DataFrame(test_Y_origin) 263 | data_test.to_csv(r"./myresult/test3.csv", index=False, header=False) 264 | data_pre = pd.DataFrame(pred_testY_origin) 265 | data_pre.to_csv(r"./myresult/pre3.csv", index=False, header=False) 266 | 267 | plt.figure() 268 | plt.plot(test_Y_origin, label='Actual', color='blue') 269 | plt.plot(pred_testY_origin, label='Predicted', color='red') 270 | plt.legend() 271 | plt.title('Actual vs Predicted') 272 | plt.xlabel('Index') 273 | plt.ylabel('Value') 274 | plt.savefig('./myresult/res3.png') 275 | 276 | MAPE = MAPE1(test_Y_origin,pred_testY_origin) 277 | MSE = MSE1(test_Y_origin,pred_testY_origin) 278 | RMSE = np.sqrt(MSE1(test_Y_origin,pred_testY_origin)) 279 | MAE = MAE1(test_Y_origin,pred_testY_origin) 280 | R2 = metrics.r2_score(test_Y_origin, pred_testY_origin) 281 | 282 | print("MAPE:{:.6f}".format(MAPE)) 283 | print("MAE:{:.6f}".format(MAE)) 284 | print("MSE:{:.6f}".format(MSE)) 285 | print("RMSE:{:.6f}".format(RMSE)) 286 | print("R2:{:.6f}".format(R2)) 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | --------------------------------------------------------------------------------