From d9631b01b80921abdd028d7507d3fb1936edd0fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BA=E9=A3=8E?= <12348188+tailwind_123@user.noreply.gitee.com> Date: Thu, 8 May 2025 08:50:37 +0000 Subject: [PATCH 1/3] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20subject1-4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- subject1-4/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 subject1-4/.keep diff --git a/subject1-4/.keep b/subject1-4/.keep new file mode 100644 index 0000000..e69de29 -- Gitee From bb23c2fd7e07880832e85569e0b6ef018d3ed872 Mon Sep 17 00:00:00 2001 From: Administrator <1223580141@qq.com> Date: Thu, 8 May 2025 17:03:22 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=AD=90=E8=AF=BE=E9=A2=981.4=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...oising_diffusion_pytorch_1d.cpython-38.pyc | Bin 0 -> 24787 bytes .../diffusion_module2.cpython-38.pyc | Bin 0 -> 4109 bytes .../__pycache__/models2.cpython-38.pyc | Bin 0 -> 7950 bytes .../train_diffusion_val.cpython-311.pyc | Bin 0 -> 23917 bytes .../train_diffusion_val.cpython-38.pyc | Bin 0 -> 10418 bytes .../AdaDiff/__pycache__/unet2.cpython-38.pyc | Bin 0 -> 10851 bytes subject1-4/AdaDiff/client.py | 203 ++ .../AdaDiff/data/preprocess_smap_msl.ipynb | 1261 +++++++++++ subject1-4/AdaDiff/data/preprocess_smd.ipynb | 263 +++ .../AdaDiff/data/preprocess_synthetic.ipynb | 850 ++++++++ subject1-4/AdaDiff/data/split_val_swat.ipynb | 1863 +++++++++++++++++ subject1-4/AdaDiff/data/split_val_wadi.ipynb | 1188 +++++++++++ .../AdaDiff/denoising_diffusion_pytorch_1d.py | 829 ++++++++ subject1-4/AdaDiff/diffusion_module2.py | 159 ++ subject1-4/AdaDiff/huigui.ipynb | 234 +++ subject1-4/AdaDiff/models2.py | 273 +++ subject1-4/AdaDiff/server.py | 151 ++ .../src/__pycache__/dlutils.cpython-38.pyc | Bin 0 -> 1418 bytes .../src/__pycache__/eval.cpython-311.pyc | Bin 0 -> 5172 bytes .../src/__pycache__/eval.cpython-38.pyc | Bin 0 -> 2539 bytes .../__pycache__/my_plotting.cpython-38.pyc | Bin 0 -> 3488 bytes .../src/__pycache__/parser.cpython-311.pyc | Bin 0 -> 3226 bytes .../src/__pycache__/parser.cpython-38.pyc | Bin 0 -> 1750 bytes subject1-4/AdaDiff/src/dlutils.py | 30 + subject1-4/AdaDiff/src/eval.py | 118 ++ subject1-4/AdaDiff/src/my_plotting.py | 164 ++ subject1-4/AdaDiff/src/parser.py | 125 ++ subject1-4/AdaDiff/train_diffusion_val.py | 535 +++++ subject1-4/AdaDiff/unet2.py | 399 ++++ 29 files changed, 8645 insertions(+) create mode 100644 subject1-4/AdaDiff/__pycache__/denoising_diffusion_pytorch_1d.cpython-38.pyc create mode 100644 subject1-4/AdaDiff/__pycache__/diffusion_module2.cpython-38.pyc create mode 100644 subject1-4/AdaDiff/__pycache__/models2.cpython-38.pyc create mode 100644 subject1-4/AdaDiff/__pycache__/train_diffusion_val.cpython-311.pyc create mode 100644 subject1-4/AdaDiff/__pycache__/train_diffusion_val.cpython-38.pyc create mode 100644 subject1-4/AdaDiff/__pycache__/unet2.cpython-38.pyc create mode 100644 subject1-4/AdaDiff/client.py create mode 100644 subject1-4/AdaDiff/data/preprocess_smap_msl.ipynb create mode 100644 subject1-4/AdaDiff/data/preprocess_smd.ipynb create mode 100644 subject1-4/AdaDiff/data/preprocess_synthetic.ipynb create mode 100644 subject1-4/AdaDiff/data/split_val_swat.ipynb create mode 100644 subject1-4/AdaDiff/data/split_val_wadi.ipynb create mode 100644 subject1-4/AdaDiff/denoising_diffusion_pytorch_1d.py create mode 100644 subject1-4/AdaDiff/diffusion_module2.py create mode 100644 subject1-4/AdaDiff/huigui.ipynb create mode 100644 subject1-4/AdaDiff/models2.py create mode 100644 subject1-4/AdaDiff/server.py create mode 100644 subject1-4/AdaDiff/src/__pycache__/dlutils.cpython-38.pyc create mode 100644 subject1-4/AdaDiff/src/__pycache__/eval.cpython-311.pyc create mode 100644 subject1-4/AdaDiff/src/__pycache__/eval.cpython-38.pyc create mode 100644 subject1-4/AdaDiff/src/__pycache__/my_plotting.cpython-38.pyc create mode 100644 subject1-4/AdaDiff/src/__pycache__/parser.cpython-311.pyc create mode 100644 subject1-4/AdaDiff/src/__pycache__/parser.cpython-38.pyc create mode 100644 subject1-4/AdaDiff/src/dlutils.py create mode 100644 subject1-4/AdaDiff/src/eval.py create mode 100644 subject1-4/AdaDiff/src/my_plotting.py create mode 100644 subject1-4/AdaDiff/src/parser.py create mode 100644 subject1-4/AdaDiff/train_diffusion_val.py create mode 100644 subject1-4/AdaDiff/unet2.py diff --git a/subject1-4/AdaDiff/__pycache__/denoising_diffusion_pytorch_1d.cpython-38.pyc b/subject1-4/AdaDiff/__pycache__/denoising_diffusion_pytorch_1d.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fd767cc1f05e0a812322e7c3b3ff2dfcdc91cccb GIT binary patch literal 24787 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 literal 0 HcmV?d00001 diff --git a/subject1-4/AdaDiff/__pycache__/models2.cpython-38.pyc b/subject1-4/AdaDiff/__pycache__/models2.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b258adaeb142817db9045816fba314a6537b315c GIT binary patch literal 7950 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 literal 0 HcmV?d00001 diff --git a/subject1-4/AdaDiff/__pycache__/train_diffusion_val.cpython-311.pyc b/subject1-4/AdaDiff/__pycache__/train_diffusion_val.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..989f09cd914b8bd7802aa50332df0a18aea74d48 GIT binary patch literal 23917 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 UkA=v;9gl%h7jvp2a)SAP0mv*t6#xJL literal 0 HcmV?d00001 diff --git a/subject1-4/AdaDiff/__pycache__/train_diffusion_val.cpython-38.pyc b/subject1-4/AdaDiff/__pycache__/train_diffusion_val.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a5fd163f8f052e9584ed87e1857a78a32e654070 GIT binary patch literal 10418 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 kQ`p!T_Pve68R<7u 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�s%;Rnk`KLIb;ma0t^ykc!v5n1fZjCa)PIJ_1u=86(?lXVwtJ1PWM3sNO>!46@tsW+ zvGdw1NXsQrHF6kn_6^xgew|OI6t^y8o1Y8VO}`yye0&w)>sr{)^dhI%^EDYJyTyWJ zVsK=8DbBVUs+y!j#8-_y62yTXUAoMa$PHg3k1U(6aT>n0Y(Gq`Hrlmjl?fB+B+e!T z$)3!Q*@xf504km^j47r+*&f49w!CgJR>3#o(s6*;t6Jv3byrN z)+&6T_jr?e^wOI+Ajt>90D46XBgJaGj!`0bHk$k@1>vZ^jPy|wLNj6QiG8qIl8Jv)j4IgF-^{@oai8 z!)Jk~`0vx;3-6$}v1{;$NxA-W=owcdcc0H1d!X~Zr~y9))Qt(e?d{>)@*zfytLeQ- z*_j)RdN_thTt7M=U!jB*1wty4yh~Hi$_YXcq zqAMF`p^qJiT4U2sASw^)A+TB>g4JnR;zzsdf|iuY@^qYn#CLCt9woRVuJg~b`#<2D zQ}t#Cdtdt`{1FR*g+F2K9*aL^@y95z@!#p{KWFpXD8|EY{RRk?+^y;m=kV!RH#W8Y zCEgyeXtR*q;BTN7X9c5@Pd_{WmDI+jF3NNccPc6q;}3ko1hFrgMflvFm9-p8GK6fI zS+wbk=j|c__N;|d?kPf%diil~VSjdcS$_lF33ey0)raQke;4<990Wgi@Em-_H2VGb zRoki;fjCiz(wFR{47;Z~y=R literal 0 HcmV?d00001 diff --git a/subject1-4/AdaDiff/client.py b/subject1-4/AdaDiff/client.py new file mode 100644 index 0000000..f1412b9 --- /dev/null +++ b/subject1-4/AdaDiff/client.py @@ -0,0 +1,203 @@ +import socket +import threading +import time +from queue import Queue +import train_diffusion_val +import torch +from torch.utils.data import Dataset, DataLoader, TensorDataset +import torch.nn as nn +import numpy as np +import pickle +import random +class EdgeNode: + def __init__(self, server_address, data_set, model): + # self.node_id = node_id + # self.data_buffer = [] + # self.data_stream = [] + self.ratio = 0.6 + self.model = model + self.server_address = server_address + self.data_set = data_set + self.data_index = 0 + self.lock = threading.Lock() + self.is_running = True # 用于控制数据流读取的循环 + self.results = [] + self.time = 0 + + def read_data_stream(self): + while self.is_running: + time.sleep(2) + new_data_point = self.generate_data_point() + # self.data_stream.append(new_data_point) + + with self.lock: + print(f"Processing data: ") + # 创建新线程处理数据 + self.process_data(new_data_point) + self.data_index+=1 + # if len(self.data_buffer) == 3: + # print(f"Node {self.node_id} - Processing data: {self.data_buffer}") + # # 创建新线程处理数据 + # processing_thread = threading.Thread(target=self.process_data, args=(self.data_buffer,)) + # processing_thread.start() + + # # 移动窗口,准备接收下一个数据点 + # # self.data_buffer = self.data_buffer[1:] + + def generate_data_point(self): + # 按顺序从数据集中获取数据点 + if(self.data_index == np.shape(self.data_set)[0] - 1): + self.is_running = False + # data_point = self.data_set[self.data_index] + return self.data_set[self.data_index].unsqueeze(0) + + def process_data(self, data_fragment): + # import time + startTime = time.time() + noised_series = self.noising(data_fragment) + + if(random.randint(1,100) < 10): + print("网络故障,本地计算") + self.results.append(noised_series) + endTime = time.time() + print("耗时", endTime - startTime) + self.time += endTime - startTime + return + + print(f"将加噪后的时序传输给服务器:") + # 异常检测到,将数据片段、异常数据点的ID和边缘节点ID上报给中心服务器 + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client_socket: + client_socket.connect(self.server_address) + + send_dict = {"ratio":self.ratio,"data":noised_series} + + serialized_data = pickle.dumps(send_dict) + chunk_size = 1024 + + client_socket.sendall(str(len(serialized_data)).encode()) + point = client_socket.recv(1024) + print("收到信号", point.decode()) + print(len(serialized_data)) + for i in range(0, len(serialized_data), chunk_size): + chunk = serialized_data[i:i+chunk_size] + client_socket.sendall(chunk) + # client_socket.sendall(data_to_send) + + print("等待接受服务端数据:") + length = int(client_socket.recv(1024).decode()) + + print("收到长度",length) + client_socket.sendall('go'.encode()) + serialized_data = b'' + while True: + chunk = client_socket.recv(1024) # 接收数据块(这里假设每次接收1KB) + + serialized_data += chunk + if len(serialized_data) == length: # 如果接收到的数据为空,表示传输完毕 + break + # print(len(serialized_data)) + deserialized_data = pickle.loads(serialized_data) + # print(deserialized_data) + print(len(serialized_data)) + self.results.append(deserialized_data) + endTime = time.time() + print("耗时", endTime - startTime) + self.time += endTime - startTime + + def noising(self, data): + return self.model(data, 0, int(self.model.denoise_steps*self.ratio))[1].transpose(2,1) + + +if __name__ == "__main__": + server_address = ('localhost', 8892) # 中心服务器地址和端口 + + training_mode = "diffusion" + lr = 1e-3 + window_size = 128 + p1 = 1 + p2 = 1 + dataset_name = "point_global" + batch_size = 32 + noise_steps = 100 + denoise_steps = 50 + diff_lambda = 0.1 + part = None + device = "cuda" + + experiment = f'diffv4_{dataset_name}_{noise_steps}-{denoise_steps}_{diff_lambda}_1e-3_{batch_size}_{window_size}' + + train_loader, test_loader, validation_loader, labels, validation_labels = train_diffusion_val.load_dataset(dataset_name, part) + + model, diffusion_training_net, diffusion_prediction_net, optimizer, scheduler = \ + train_diffusion_val.load_model(training_mode ,lr, window_size, p1, p2, labels.shape[1], batch_size, noise_steps, denoise_steps) + model, diffusion_training_net = train_diffusion_val.load_from_checkpoint(training_mode, experiment, model, diffusion_training_net) + diffusion_training_net = diffusion_training_net.to(device) + diffusion_prediction_net = diffusion_prediction_net.to(device) + + diffusion_prediction_net.load_state_dict(diffusion_training_net.state_dict()) + diffusion_prediction_net.eval() + diffusion_training_net.eval() + + trainD, testD, validationD = next(iter(train_loader)), next(iter(test_loader)), next(iter(validation_loader)) + testD = train_diffusion_val.convert_to_windows(testD, window_size) + print(np.shape(testD)) + data_x = torch.tensor(testD, dtype=torch.float32) + data_x = data_x.to(device) + # dataset = TensorDataset(data_x, data_x) + # dataloader = DataLoader(dataset, batch_size = batch_size) + + # STime = time.time() + # l1s = [] + # feats=labels.shape[1] + # for window, _ in dataloader: + # window = window.to(device) + # _, x_recon = diffusion_prediction_net(window,0,45) + # _, x_recon = diffusion_prediction_net(window,45,50) + # x_recon = x_recon.transpose(2,1) + # l = nn.MSELoss(reduction = 'none') + # loss = l(x_recon, window) + # l1s.append(loss) + # ETime = time.time() + # loss0 = torch.cat(l1s).detach().cpu().numpy() + # loss0 = loss0.reshape(-1,feats) + + # lossFinal = np.mean(np.array(loss0), axis=1) + # labelsFinal = (np.sum(labels, axis=1) >= 1) + 0 + # validation_thresh = 0 + # result, fprs, tprs = train_diffusion_val.evaluate(lossFinal, labelsFinal, validation_thresh=validation_thresh) + # result_roc = result["ROC/AUC"] + # result_f1 = result["f1"] + + # print(result, ETime - STime) + + edge_node = EdgeNode(server_address=server_address, data_set=data_x, model = diffusion_prediction_net) + edge_node.read_data_stream() + # print(torch.stack(edge_node.results)) + denoised_data = torch.stack(edge_node.results).squeeze(1) + print(edge_node.time) + # 边缘节点线程结束后,自动关闭客户端 + print(f"Client closed.") + # print(np.shape(data_x)) + dataset = TensorDataset(data_x, denoised_data) + dataloader = DataLoader(dataset, batch_size = batch_size) + + l1s = [] + feats=labels.shape[1] + for raw, window in dataloader: + window = window.to(device) + l = nn.MSELoss(reduction = 'none') + loss = l(raw, window) + l1s.append(loss) + loss0 = torch.cat(l1s).detach().cpu().numpy() + loss0 = loss0.reshape(-1,feats) + + print(np.shape(loss0)) + lossFinal = np.mean(np.array(loss0), axis=1) + labelsFinal = (np.sum(labels, axis=1) >= 1) + 0 + validation_thresh = 0 + result, fprs, tprs = train_diffusion_val.evaluate(lossFinal, labelsFinal, validation_thresh=validation_thresh) + result_roc = result["ROC/AUC"] + result_f1 = result["f1"] + print("ROC",result_roc) + print("f1", result_f1) + print("time",edge_node.time / np.shape(denoised_data)[0]) \ No newline at end of file diff --git a/subject1-4/AdaDiff/data/preprocess_smap_msl.ipynb b/subject1-4/AdaDiff/data/preprocess_smap_msl.ipynb new file mode 100644 index 0000000..768a0d5 --- /dev/null +++ b/subject1-4/AdaDiff/data/preprocess_smap_msl.ipynb @@ -0,0 +1,1261 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/mts/SMAP_MSL/data\n" + ] + } + ], + "source": [ + "%cd '../../../../mts/SMAP_MSL/data'" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'/mts/SMAP_MSL/data'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%pwd" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "train_folder = '../../../../mts/SMAP_MSL/data/train/'\n", + "test_folder = '../../../../mts/SMAP_MSL/data/test/'" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import os" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "labeled_anomalies = pd.read_csv('../../../../mts/SMAP_MSL/data/labeled_anomalies.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
chan_idspacecraftanomaly_sequencesclassnum_values
0P-1SMAP[[2149, 2349], [4536, 4844], [3539, 3779]][contextual, contextual, contextual]8505
1S-1SMAP[[5300, 5747]][point]7331
2E-1SMAP[[5000, 5030], [5610, 6086]][contextual, contextual]8516
3E-2SMAP[[5598, 6995]][point]8532
4E-3SMAP[[5094, 8306]][point]8307
\n", + "
" + ], + "text/plain": [ + " chan_id spacecraft anomaly_sequences \\\n", + "0 P-1 SMAP [[2149, 2349], [4536, 4844], [3539, 3779]] \n", + "1 S-1 SMAP [[5300, 5747]] \n", + "2 E-1 SMAP [[5000, 5030], [5610, 6086]] \n", + "3 E-2 SMAP [[5598, 6995]] \n", + "4 E-3 SMAP [[5094, 8306]] \n", + "\n", + " class num_values \n", + "0 [contextual, contextual, contextual] 8505 \n", + "1 [point] 7331 \n", + "2 [contextual, contextual] 8516 \n", + "3 [point] 8532 \n", + "4 [point] 8307 " + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "labeled_anomalies.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "random_file = np.load(test_folder + 'A-1.npy')" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/root/.conda/envs/py3.9test/lib/python3.9/site-packages/scipy/__init__.py:138: UserWarning: A NumPy version >=1.16.5 and <1.23.0 is required for this version of SciPy (detected version 1.23.1)\n", + " warnings.warn(f\"A NumPy version >={np_minversion} and <{np_maxversion} is required for this version of \"\n" + ] + } + ], + "source": [ + "from sklearn.preprocessing import MinMaxScaler\n", + "\n", + "def scale_data(train, test):\n", + " scaler = MinMaxScaler(feature_range=(0, 1), clip=True).fit(train)\n", + "\n", + " train_scaled = scaler.transform(train)\n", + " test_scaled = scaler.transform(test)\n", + "\n", + " return train_scaled, test_scaled" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
chan_idspacecraftanomaly_sequencesclassnum_values
0P-1SMAP[[2149, 2349], [4536, 4844], [3539, 3779]][contextual, contextual, contextual]8505
1S-1SMAP[[5300, 5747]][point]7331
2E-1SMAP[[5000, 5030], [5610, 6086]][contextual, contextual]8516
3E-2SMAP[[5598, 6995]][point]8532
4E-3SMAP[[5094, 8306]][point]8307
\n", + "
" + ], + "text/plain": [ + " chan_id spacecraft anomaly_sequences \\\n", + "0 P-1 SMAP [[2149, 2349], [4536, 4844], [3539, 3779]] \n", + "1 S-1 SMAP [[5300, 5747]] \n", + "2 E-1 SMAP [[5000, 5030], [5610, 6086]] \n", + "3 E-2 SMAP [[5598, 6995]] \n", + "4 E-3 SMAP [[5094, 8306]] \n", + "\n", + " class num_values \n", + "0 [contextual, contextual, contextual] 8505 \n", + "1 [point] 7331 \n", + "2 [contextual, contextual] 8516 \n", + "3 [point] 8532 \n", + "4 [point] 8307 " + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "smap = labeled_anomalies[labeled_anomalies['spacecraft'] == 'SMAP']\n", + "smap.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
chan_idspacecraftanomaly_sequencesclassnum_values
33T-1SMAP[[2399, 3898], [6550, 6585]][point, contextual]8612
\n", + "
" + ], + "text/plain": [ + " chan_id spacecraft anomaly_sequences class \\\n", + "33 T-1 SMAP [[2399, 3898], [6550, 6585]] [point, contextual] \n", + "\n", + " num_values \n", + "33 8612 " + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "smap[smap['chan_id'] == 'T-1']" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
chan_idspacecraftanomaly_sequencesclassnum_values
55M-6MSL[[1850, 2030]][point]2049
56M-1MSL[[1110, 2250]][contextual]2277
57M-2MSL[[1110, 2250]][contextual]2277
58S-2MSL[[900, 910]][point]1827
59P-10MSL[[4590, 4720]][point]6100
\n", + "
" + ], + "text/plain": [ + " chan_id spacecraft anomaly_sequences class num_values\n", + "55 M-6 MSL [[1850, 2030]] [point] 2049\n", + "56 M-1 MSL [[1110, 2250]] [contextual] 2277\n", + "57 M-2 MSL [[1110, 2250]] [contextual] 2277\n", + "58 S-2 MSL [[900, 910]] [point] 1827\n", + "59 P-10 MSL [[4590, 4720]] [point] 6100" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "msl = labeled_anomalies[labeled_anomalies['spacecraft'] == 'MSL']\n", + "msl.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'msl' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m/root/Diff-Anomaly/TranAD/data/preprocess_smap_msl.ipynb Cell 12\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0m msl[msl[\u001b[39m'\u001b[39m\u001b[39mchan_id\u001b[39m\u001b[39m'\u001b[39m] \u001b[39m==\u001b[39m \u001b[39m'\u001b[39m\u001b[39mT-1\u001b[39m\u001b[39m'\u001b[39m]\n", + "\u001b[0;31mNameError\u001b[0m: name 'msl' is not defined" + ] + } + ], + "source": [ + "msl[msl['chan_id'] == 'T-1']" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "27\n", + "['C-1', 'C-2', 'D-14', 'D-15', 'D-16', 'F-4', 'F-5', 'F-7', 'F-8', 'M-1', 'M-2', 'M-3', 'M-4', 'M-5', 'M-6', 'M-7', 'P-10', 'P-11', 'P-14', 'P-15', 'S-2', 'T-12', 'T-13', 'T-4', 'T-5', 'T-8', 'T-9']\n" + ] + } + ], + "source": [ + "# smap_files = smap['chan_id'].values\n", + "msl_files = msl['chan_id'].values\n", + "# print(len(smap_files))\n", + "print(len(msl_files))\n", + "# print(smap_files)\n", + "print(sorted(msl_files))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Original range for P-1: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for P-1: [0.0 1.0], [0.0 1.0]\n", + "Original range for S-1: [-0.4 1.0], [-0.4 1.0]\n", + "Scaled range for S-1: [0.0 1.0], [0.0 1.0]\n", + "Original range for E-1: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for E-1: [0.0 1.0], [0.0 1.0]\n", + "Original range for E-2: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for E-2: [0.0 1.0], [0.0 1.0]\n", + "Original range for E-3: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for E-3: [0.0 1.0], [0.0 1.0]\n", + "Original range for E-4: [-0.9999999999999998 1.0000000000000004], [-0.9999999999999998 1.0000000000000004]\n", + "Scaled range for E-4: [0.0 1.0], [0.0 1.0]\n", + "Original range for E-5: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for E-5: [0.0 1.0], [0.0 1.0]\n", + "Original range for E-6: [0.0 1.0], [0.0 1.0]\n", + "Scaled range for E-6: [0.0 1.0], [0.0 1.0]\n", + "Original range for E-7: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for E-7: [0.0 1.0], [0.0 1.0]\n", + "Original range for E-8: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for E-8: [0.0 1.0], [0.0 1.0]\n", + "Original range for E-9: [-1.0 1.0000000000000018], [-1.0 1.0000000000000018]\n", + "Scaled range for E-9: [0.0 1.0], [0.0 1.0]\n", + "Original range for E-10: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for E-10: [0.0 1.0], [0.0 1.0]\n", + "Original range for E-11: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for E-11: [0.0 1.0], [0.0 1.0]\n", + "Original range for E-12: [-1.0 1.0000000000000002], [-1.0 1.0000000000000002]\n", + "Scaled range for E-12: [0.0 1.0], [0.0 1.0]\n", + "Original range for E-13: [-1.0 1.0000000000000002], [-1.0 1.0000000000000002]\n", + "Scaled range for E-13: [0.0 1.0], [0.0 1.0]\n", + "Original range for A-1: [0.0 1.0], [0.0 1.0]\n", + "Scaled range for A-1: [0.0 1.0], [0.0 1.0]\n", + "Original range for D-1: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for D-1: [0.0 1.0], [0.0 1.0]\n", + "Original range for P-2: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for P-2: [0.0 1.0], [0.0 1.0]\n", + "Original range for P-3: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for P-3: [0.0 1.0], [0.0 1.0]\n", + "Original range for D-2: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for D-2: [0.0 1.0], [0.0 1.0]\n", + "Original range for D-3: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for D-3: [0.0 1.0], [0.0 1.0]\n", + "Original range for D-4: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for D-4: [0.0 1.0], [0.0 1.0]\n", + "Original range for A-2: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for A-2: [0.0 1.0], [0.0 1.0]\n", + "Original range for A-3: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for A-3: [0.0 1.0], [0.0 1.0]\n", + "Original range for A-4: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for A-4: [0.0 1.0], [0.0 1.0]\n", + "Original range for G-1: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for G-1: [0.0 1.0], [0.0 1.0]\n", + "Original range for G-2: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for G-2: [0.0 1.0], [0.0 1.0]\n", + "Original range for D-5: [0.0 1.0], [0.0 1.0]\n", + "Scaled range for D-5: [0.0 1.0], [0.0 1.0]\n", + "Original range for D-6: [-0.9999999999999999 1.0], [-0.9999999999999999 1.0]\n", + "Scaled range for D-6: [0.0 1.0], [0.0 1.0]\n", + "Original range for D-7: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for D-7: [0.0 1.0], [0.0 1.0]\n", + "Original range for F-1: [-0.34 1.0], [-0.34 1.0]\n", + "Scaled range for F-1: [0.0 1.0], [0.0 1.0]\n", + "Original range for P-4: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for P-4: [0.0 1.0], [0.0 1.0]\n", + "Original range for G-3: [-0.9999999999999998 1.0], [-0.9999999999999998 1.0]\n", + "Scaled range for G-3: [0.0 1.0], [0.0 1.0]\n", + "Original range for T-1: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for T-1: [0.0 1.0], [0.0 1.0]\n", + "Original range for T-2: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for T-2: [0.0 1.0], [0.0 1.0]\n", + "Original range for D-8: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for D-8: [0.0 1.0], [0.0 1.0]\n", + "Original range for D-9: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for D-9: [0.0 1.0], [0.0 1.0]\n", + "Original range for F-2: [-0.54 1.0], [-0.54 1.0]\n", + "Scaled range for F-2: [0.0 1.0], [0.0 1.0]\n", + "Original range for G-4: [0.0 1.0], [0.0 1.0]\n", + "Scaled range for G-4: [0.0 1.0], [0.0 1.0]\n", + "Original range for T-3: [0.0 1.0], [0.0 1.0]\n", + "Scaled range for T-3: [0.0 1.0], [0.0 1.0]\n", + "Original range for D-11: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for D-11: [0.0 1.0], [0.0 1.0]\n", + "Original range for D-12: [-1.0 0.0], [-1.0 0.0]\n", + "Scaled range for D-12: [0.0 0.0], [0.0 1.0]\n", + "Original range for B-1: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for B-1: [0.0 1.0], [0.0 1.0]\n", + "Original range for G-6: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for G-6: [0.0 1.0], [0.0 1.0]\n", + "Original range for G-7: [-0.9999999999999998 1.0], [-0.9999999999999998 1.0]\n", + "Scaled range for G-7: [0.0 1.0], [0.0 1.0]\n", + "Original range for P-7: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for P-7: [0.0 1.0], [0.0 1.0]\n", + "Original range for R-1: [0.0 1.0], [0.0 1.0]\n", + "Scaled range for R-1: [0.0 1.0], [0.0 1.0]\n", + "Original range for A-5: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for A-5: [0.0 1.0], [0.0 1.0]\n", + "Original range for A-6: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for A-6: [0.0 1.0], [0.0 0.9999999999999999]\n", + "Original range for A-7: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for A-7: [0.0 1.0], [0.0 1.0]\n", + "Original range for D-13: [-1.0 0.0], [-1.0 0.0]\n", + "Scaled range for D-13: [0.0 0.0], [0.0 1.0]\n", + "Original range for P-2: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for P-2: [0.0 1.0], [0.0 1.0]\n", + "Original range for A-8: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for A-8: [0.0 1.0], [0.0 1.0]\n", + "Original range for A-9: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for A-9: [0.0 1.0], [0.0 1.0]\n", + "Original range for F-3: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for F-3: [0.0 1.0], [0.0 1.0]\n" + ] + } + ], + "source": [ + "for file in smap_files:\n", + " # load\n", + " train_original = np.load(train_folder + f'{file}.npy')\n", + " test_original = np.load(test_folder + f'{file}.npy')\n", + " print(f'Original range for {file}: [{train_original.min()} {train_original.max()}], [{train_original.min()} {train_original.max()}]')\n", + " # scale\n", + " train_scaled, test_scaled = scale_data(train_original, test_original)\n", + " print(f'Scaled range for {file}: [{train_scaled.min()} {train_scaled.max()}], [{test_scaled.min()} {test_scaled.max()}]')\n", + " # build labels\n", + " labels = np.zeros_like(test_scaled)\n", + " indices = smap[smap['chan_id'] == file]['anomaly_sequences'].values[0]\n", + " indices = indices.replace(']', '').replace('[', '').split(', ')\n", + " indices = [int(i) for i in indices]\n", + " for i in range(0, len(indices), 2):\n", + " labels[indices[i]:indices[i+1], :] = 1\n", + " # save\n", + " dir = '../../TranAD/processed/SMAP'\n", + " os.makedirs(dir, exist_ok=True)\n", + " np.save(f'{dir}/{file}_train.npy', train_scaled)\n", + " np.save(f'{dir}/{file}_test.npy', test_scaled)\n", + " np.save(f'{dir}/{file}_labels.npy', labels) \n" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Original range for M-6: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for M-6: [0.0 1.0], [0.0 1.0]\n", + "Original range for M-1: [-0.9160935512741932 2.4922982712327473], [-0.9160935512741932 2.4922982712327473]\n", + "Scaled range for M-1: [0.0 1.0], [0.0 1.0]\n", + "Original range for M-2: [-1.210726170949998 1.0], [-1.210726170949998 1.0]\n", + "Scaled range for M-2: [0.0 1.0], [0.0 1.0]\n", + "Original range for S-2: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for S-2: [0.0 1.0], [0.0 1.0]\n", + "Original range for P-10: [0.0 1.001129464915996], [0.0 1.001129464915996]\n", + "Scaled range for P-10: [0.0 1.0], [0.0 1.0]\n", + "Original range for T-4: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for T-4: [0.0 1.0], [0.0 1.0]\n", + "Original range for T-5: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for T-5: [0.0 1.0], [0.0 1.0]\n", + "Original range for F-7: [-0.9999999999999998 1.0], [-0.9999999999999998 1.0]\n", + "Scaled range for F-7: [0.0 1.0], [0.0 1.0]\n", + "Original range for M-3: [-1.47721668720188 1.000070758018348], [-1.47721668720188 1.000070758018348]\n", + "Scaled range for M-3: [0.0 1.0], [0.0 1.0]\n", + "Original range for M-4: [-1.4654640190905774 1.00000547321409], [-1.4654640190905774 1.00000547321409]\n", + "Scaled range for M-4: [0.0 1.0], [0.0 1.0]\n", + "Original range for M-5: [-1.2550059949886205 1.0], [-1.2550059949886205 1.0]\n", + "Scaled range for M-5: [0.0 1.0], [0.0 1.0]\n", + "Original range for P-15: [0.0 1.0052196607220525], [0.0 1.0052196607220525]\n", + "Scaled range for P-15: [0.0 1.0], [0.0 1.0]\n", + "Original range for C-1: [-1.0 2.1934477379095165], [-1.0 2.1934477379095165]\n", + "Scaled range for C-1: [0.0 1.0], [0.0 1.0]\n", + "Original range for C-2: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for C-2: [0.0 1.0], [0.0 1.0]\n", + "Original range for T-12: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for T-12: [0.0 1.0], [0.0 1.0]\n", + "Original range for T-13: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for T-13: [0.0 1.0], [0.0 1.0]\n", + "Original range for F-4: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for F-4: [0.0 1.0], [0.0 1.0]\n", + "Original range for F-5: [-1.1163775338154294 4.162651279553374], [-1.1163775338154294 4.162651279553374]\n", + "Scaled range for F-5: [0.0 1.0], [0.0 1.0]\n", + "Original range for D-14: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for D-14: [0.0 1.0], [0.0 1.0]\n", + "Original range for T-9: [-1.0 1.0], [-1.0 1.0]\n", + "Scaled range for T-9: [0.0 1.0], [0.0 1.0]\n", + "Original range for P-14: [0.0 1.0], [0.0 1.0]\n", + "Scaled range for P-14: [0.0 1.0], [0.0 1.0]\n", + "Original range for T-8: [-1.0 1.0294117647058822], [-1.0 1.0294117647058822]\n", + "Scaled range for T-8: [0.0 1.0], [0.0 1.0]\n", + "Original range for P-11: [0.0 1.0], [0.0 1.0]\n", + "Scaled range for P-11: [0.0 1.0], [0.0 1.0]\n", + "Original range for D-15: [-1.0 1.1915779731605738], [-1.0 1.1915779731605738]\n", + "Scaled range for D-15: [0.0 1.0], [0.0 1.0]\n", + "Original range for D-16: [-1.0 1.008879901529805], [-1.0 1.008879901529805]\n", + "Scaled range for D-16: [0.0 1.0], [0.0 1.0]\n", + "Original range for M-7: [-1.0020241085789672 1.0], [-1.0020241085789672 1.0]\n", + "Scaled range for M-7: [0.0 1.0], [0.0 1.0]\n", + "Original range for F-8: [-1.0 1.1304347826086958], [-1.0 1.1304347826086958]\n", + "Scaled range for F-8: [0.0 1.0], [0.0 1.0]\n" + ] + } + ], + "source": [ + "for file in msl_files:\n", + " # load\n", + " train_original = np.load(train_folder + f'{file}.npy')\n", + " test_original = np.load(test_folder + f'{file}.npy')\n", + " print(f'Original range for {file}: [{train_original.min()} {train_original.max()}], [{train_original.min()} {train_original.max()}]')\n", + " # scale\n", + " train_scaled, test_scaled = scale_data(train_original, test_original)\n", + " print(f'Scaled range for {file}: [{train_scaled.min()} {train_scaled.max()}], [{test_scaled.min()} {test_scaled.max()}]')\n", + " # build labels\n", + " labels = np.zeros_like(test_scaled)\n", + " indices = msl[msl['chan_id'] == file]['anomaly_sequences'].values[0]\n", + " indices = indices.replace(']', '').replace('[', '').split(', ')\n", + " indices = [int(i) for i in indices]\n", + " for i in range(0, len(indices), 2):\n", + " labels[indices[i]:indices[i+1], :] = 1\n", + " # save\n", + " dir = '../../TranAD/processed/MSL'\n", + " os.makedirs(dir, exist_ok=True)\n", + " np.save(f'{dir}/{file}_train.npy', train_scaled)\n", + " np.save(f'{dir}/{file}_test.npy', test_scaled)\n", + " np.save(f'{dir}/{file}_labels.npy', labels) \n" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [], + "source": [ + "t_1_test = np.load(test_folder + 'T-1.npy')\n", + "t_1_train = np.load(train_folder + 'T-1.npy')" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(2875, 25)" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "t_1_train.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "min_original_test = t_1_test.min()\n", + "max_original_test = t_1_test.max()\n", + "min_original_train = t_1_train.min()\n", + "max_original_train = t_1_train.max()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-1.0 1.0\n", + "-1.0 1.0\n" + ] + } + ], + "source": [ + "print(f'{min_original_train} {max_original_train}')\n", + "print(f'{min_original_test} {max_original_test}')" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.023095539152304296\n", + "0.020554483585080625\n" + ] + } + ], + "source": [ + "print(t_1_train.mean())\n", + "print(t_1_test.mean())" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "t_1_train_scaled, t_1_test_scaled = scale_data(t_1_train, t_1_test)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "min_train_scaled = t_1_train_scaled.min()\n", + "max_train_scaled = t_1_train.max()\n", + "min_test_scaled = t_1_test_scaled.min()\n", + "max_test_scaled = t_1_test.max()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.0 1.0\n", + "0.0 1.0\n" + ] + } + ], + "source": [ + "print(f'{min_train_scaled} {max_train_scaled}')\n", + "print(f'{min_test_scaled} {max_test_scaled}')" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.0315616826196304\n", + "0.030848537658773482\n" + ] + } + ], + "source": [ + "print(t_1_train_scaled.mean())\n", + "print(t_1_test_scaled.mean())" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([ 191, 112, 88, 76, 64, 69065, 84, 76, 176,\n", + " 1943]),\n", + " array([-1. , -0.8, -0.6, -0.4, -0.2, 0. , 0.2, 0.4, 0.6, 0.8, 1. ]))" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.histogram(t_1_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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EolKpYJSqcTUJTFW61OpVEKlUtW7vSAID23j4uKCtWvXYu3atY9SGhERkU1jIBKJRqOBVqvls8yIiIiaAAYiEWk0GgYUIiKiJoB3mREREZHsMRARERGR7DEQERERkewxEBEREZHsMRARERGR7DEQERERkewxEBEREZHscR4iEel0Ok7MSERE1AQwEIlEp9MhKCgIRqPRan0qlUpotdp6h6IlS5Zgy5YtyM3NhUKhQP/+/bFs2TIEBASY2vztb39DamoqfvzxR9y6dQs3b96Eh4eHSCMgIiKSBgORSAwGA4xGIzZMS0FA20DR+zt7JRexq2NgMBjqHYgOHDiAuLg49O7dG1VVVZg1axYiIiJw5swZtGzZEgBgNBoxZMgQDBkyBImJiWIOgYiISDIMRCILaBuInh17Sl1GndLT082WU1JS4OXlhaysLAwcOBAAMG3aNABARkaGlasjIiKyHl5UTSbFxcUAAE9PT4krISIisi4GIgIA1NTUYNq0aRgwYAC6du0qdTlERERWxVNmBACIi4tDTk4ODh06JHUpREREVsdARIiPj8f27dtx8OBBtG3bVupyiIiIrI6BSMYEQcDUqVORlpaGjIwM+Pv7S10SERGRJBiIZCwuLg6pqanYunUrXF1dodfrAQDu7u5QKBQAAL1eD71ej7y8PADAqVOn4OrqCo1Gw4uviYio2WAgEtnZK7k2209SUhIAICwszGx9cnIyYmJiAADr1q3DggULTNtqb8f/dRsiIqKmjoFIJCqVCkqlErGrY6zWp1KphEqlqnd7QRAe2mb+/PmYP3/+I1RFRERk+xiIRKLRaKDVavksMyIioiaAgUhEGo2GAYWIiKgJ4MSMREREJHsMRERERCR7DEREREQkewxEREREJHsMRERERCR7DEREREQkewxEREREJHuch0hEOp2OEzMSERE1AQxEItHpdAgKCoLRaLRan0qlElqttt6haMmSJdiyZQtyc3OhUCjQv39/LFu2DAEBAQCAGzduYN68efj222+h0+nQpk0bDB8+HIsWLYK7u7uYQyEiIrIqBiKRGAwGGI1GpExPQmDbJ0TvL/fK/xCzagoMBkO9A9GBAwcQFxeH3r17o6qqCrNmzUJERATOnDmDli1b4urVq7h69SpWrFiB4OBgXLp0CZMnT8bVq1fx73//W+QRERERWY9NB6L58+ebPWkd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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import seaborn as sns\n", + "sns.histplot(t_1_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkQAAAJCCAYAAAAhudhHAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAABbYElEQVR4nO3de3gU5d3/8U8IJGQxCcYlJ2EhHAzhTBExoDQoTYjUSqFVlGI4KBUDFtIigiIgKiIqWMVQFRP6KEVtiVrQIGdEQCWSR5ANFQisSBJcFULYcErm94c/9jHlYE67O7Dv13XtVWbm3rm/MyXxwz0z9wQYhmEIAADAjzXwdQEAAAC+RiACAAB+j0AEAAD8HoEIAAD4PQIRAADwewQiAADg9whEAADA7xGIAACA32vo6wIAoKKiQqdPn/Z1GT7VqFEjBQYG+roMwG8RiAD4VFlZmQ4ePCh/nzQ/ICBAzZs31xVXXOHrUgC/FMCrOwD4SkVFhb766itZLBY1a9ZMAQEBvi7JJwzD0LfffiuXy6V27doxUgT4ACNEAHzm9OnTMgxDzZo1U0hIiK/L8almzZpp//79On36NIEI8AFuqgbgc/46MvRTnAPAtwhEAADA73HJDIDpOBwOOZ1Or/VntVpls9m81h8A8yEQATAVh8OhhIQEuVwur/VpsVhkt9sJRYAfIxABMBWn0ymXy6XsSdOUYGvp8f7sjgMaMXeWnE5njQPRggULNHfuXBUXF6tr16564YUXdN1113moUgCeRCACYEoJtpbq3jbe12Vc0JtvvqmMjAwtXLhQvXr10vz585WSkqLdu3crMjLS1+UBqCFuqgaAWnjuued07733auTIkerQoYMWLlwoi8Wi1157zdelAagFAhEA1NCpU6eUl5en/v37u9c1aNBA/fv315YtW3xYGYDaIhABQA05nU5VVFQoKiqqyvqoqCgVFxf7qCoAdUEgAgAAfo9ABAA1ZLVaFRgYqJKSkirrS0pKFB0d7aOqANQFgQgAaigoKEg9evTQmjVr3OsqKyu1Zs0aJSYm+rAyALXFY/cATMnuOGDqfjIyMpSWlqZrr71W1113nebPn6/jx49r5MiR9VwhAG8gEAEwFavVKovFohFzZ3mtT4vFIqvVWqPv3HHHHfr222/16KOPqri4WN26dVNubu45N1oDuDQEGIZh+LoIAP7pxIkTKiwsVFxcnBo3buxe74/vMrvQuQDgHYwQATAdm83m84ACwL9wUzUAAPB7BCIAAOD3CEQAAMDvEYgAAIDfIxABAAC/RyACAAB+j0AEAAD8HvMQATAdf5yYEYBvEYgAmIrD4VBCQoJcLpfX+rRYLLLb7YQiwI8RiACYitPplMvlUvbkPymhRXOP92f/+qBGzHleTqezRoFo48aNmjt3rvLy8lRUVKScnBwNGjTIc4UC8CgCEQBTSmjRXN3btfF1GRd0/Phxde3aVaNGjdLgwYN9XQ6AOiIQAUAtpKamKjU11ddlAKgnPGUGAAD8HoEIAAD4PQIRAADwewQiAADg9whEAADA7/GUGQBTsn990NT9lJWVac+ePe7lwsJC5efnKyIiggkegUsQgQiAqVitVlksFo2Y87zX+rRYLLJarTX6zrZt29SvXz/3ckZGhiQpLS1N2dnZ9VkeAC8gEAEwFZvNJrvdbvp3mSUlJckwDA9VBMDbCEQATMdms3HZCYBXcVM1AADwewQiAADg9whEAADA7xGIAACA3yMQAQAAv0cgAgAAfo9ABAAA/B7zEAEwHYfDYfqJGQFcXghEAEzF4XAoIaG9XK5yr/VpsYTIbi+odiiaPXu2li1bpoKCAoWEhKh3796aM2eO4uPjPVwpAE8hEAEwFafTKZerXK9OHan4ljEe72/3gSLd82SWnE5ntQPRhg0blJ6erp49e+rMmTOaOnWqkpOTtWvXLjVp0sTDFQPwBAIRAFOKbxmjbteY8zJWbm5uleXs7GxFRkYqLy9Pffv29VFVAOqCm6oBoI6OHj0qSYqIiPBxJQBqi0AEAHVQWVmpCRMmqE+fPurUqZOvywFQS1wyA4A6SE9P186dO7Vp0yZflwKgDghEAFBL48aN0/Lly7Vx40Y1b97c1+UAqAMCEQDUkGEYGj9+vHJycrR+/XrFxcX5uiQAdUQgAoAaSk9P15IlS/Tuu+8qNDRUxcXFkqTw8HCFhIT4uDoAtUEgAmBKuw8UmbafzMxMSVJSUlKV9VlZWRoxYkQ9VAXA2whEAEzFarXKYgnRPU9mea1PiyVEVqu12u0Nw/BgNQB8gUAEwFRsNpvs9gLeZQbAqwhEAEzHZrMRUAB4FRMzAgAAv0cgAgAAfo9ABAAA/B6BCAAA+D0CEQAA8HsEIgAA4PcIRAAAwO8xDxEA03E4HEzMCMCrCEQATMXhcCghob1crnKv9WmxhMhuL6h2KMrMzFRmZqb2798vSerYsaMeffRRpaamerBKAJ5EIAJgKk6nUy5XuV6cPlLtWsV4vL+v9hdp3MwsOZ3Oagei5s2b66mnnlK7du1kGIYWL16s2267Tdu3b1fHjh09XDEATyAQATCldq1i1CXenJexbr311irLTzzxhDIzM7V161YCEXCJIhABQB1UVFTo7bff1vHjx5WYmOjrcgDUEoEIAGphx44dSkxM1IkTJ3TFFVcoJydHHTp08HVZAGqJx+4BoBbi4+OVn5+vTz75RGPHjlVaWpp27drl67IA1BIjRABQC0FBQWrbtq0kqUePHvrss8/0/PPP629/+5uPKwNQG4wQAUA9qKys1MmTJ31dBoBaYoQIAGpoypQpSk1Nlc1m07Fjx7RkyRKtX79eK1eu9HVpAGqJQATAlL7aX2Tafg4fPqy7775bRUVFCg8PV5cuXbRy5Ur96le/8kCFALyBQATAVKxWqyyWEI2bmeW1Pi2WEFmt1mq3X7RokQerAeALBCIApmKz2WS3F/AuMwBeRSACYDo2m42AAsCreMoMAAD4PQIRAADwewQiAADg9whEAADA7xGIAACA3yMQAQAAv0cgAgAAfo95iACYjsPhYGJGAF5FIAJgKg6HQwkJ7eVylXutT4slRHZ7Qa1D0VNPPaUpU6boT3/6k+bPn1+/xQHwCgIRAFNxOp1yucr13GMj1bZVjMf727O/SBmPZsnpdNYqEH322Wf629/+pi5dunigOgDeQiACYEptW8WoU3tzX8YqKyvTsGHD9Morr+jxxx/3dTkA6oCbqgGgltLT0zVw4ED179/f16UAqCNGiACgFpYuXarPP/9cn332ma9LAVAPCEQAUENff/21/vSnP2nVqlVq3Lixr8sBUA8IRABQQ3l5eTp8+LB+8YtfuNdVVFRo48aNevHFF3Xy5EkFBgb6sEIANUUgAoAauvnmm7Vjx44q60aOHKn27dtr8uTJhCHgEkQgAoAaCg0NVadOnaqsa9Kkia666qpz1gO4NBCIAJjSnv1Fl1U/AMyNQATAVKxWqyyWEGU8muW1Pi2WEFmt1jrtY/369fVTDACfIBABMBWbzSa7vYB3mQHwKgIRANOx2WwEFABexUzVAADA7xGIAACA3yMQAQAAv0cgAgAAfo9ABAAA/B6BCAAA+D0CEQAA8HvMQwTAdBwOBxMzAvAqAhEAU3E4HEpIaC+Xq9xrfVosIbLbC6odimbMmKGZM2dWWRcfH6+CggJPlAfACwhEAEzF6XTK5SrXnFkj1SYu2uP97S0s1uRpWXI6nTUaJerYsaNWr17tXm7YkF+nwKWMn2AAptQmLlodEsx7Gathw4aKjvZ8YAPgHdxUDQC18NVXXyk2NlatW7fWsGHD5HA4fF0SgDogEAFADfXq1UvZ2dnKzc1VZmamCgsLdeONN+rYsWO+Lg1ALXHJDABqKDU11f3nLl26qFevXmrZsqXeeustjR492oeVAagtRogAoI6aNm2qa665Rnv27PF1KQBqiUAEAHVUVlamvXv3KiYmxtelAKglAhEA1NBf/vIXbdiwQfv379fmzZv129/+VoGBgbrzzjt9XRqAWuIeIgCmtLew2LT9HDx4UHfeeae+++47NWvWTDfccIO2bt2qZs2aeaBCAN5AIAJgKlarVRZLiCZPy/JanxZLiKxWa7XbL1261IPVAPAFAhEAU7HZbLLbC3iXGQCvIhABMB2bzUZAAeBV3FQNAAD8HoEIAAD4PQIRAADwewQiAADg9whEAADA7xGIAACA3yMQAQAAv8c8RABMx+FwMDEjAK8iEAEwFYfDoYSE9nK5yr3Wp8USIru9oEah6JtvvtHkyZP1wQcfyOVyqW3btsrKytK1117rwUoBeAqBCICpOJ1OuVzlmvXESMW1jvZ4f4X7ijXt4Sw5nc5qB6IffvhBffr0Ub9+/fTBBx+oWbNm+uqrr3TllVd6uFoAnkIgAmBKca2jlZBgzstYc+bMUYsWLZSV9X8voI2Li/NhRQDqipuqAaCG3nvvPV177bX6/e9/r8jISHXv3l2vvPKKr8sCUAcEIgCooX379ikzM1Pt2rXTypUrNXbsWD3wwANavHixr0sDUEtcMgOAGqqsrNS1116rJ598UpLUvXt37dy5UwsXLlRaWpqPqwNQG4wQAUANxcTEqEOHDlXWJSQkyOFw+KgiAHVFIAKAGurTp492795dZd1//vMftWzZ0kcVAagrAhEA1NDEiRO1detWPfnkk9qzZ4+WLFmil19+Wenp6b4uDUAtcQ8RAFMq3Fds2n569uypnJwcTZkyRY899pji4uI0f/58DRs2zAMVAvCGAMMwDF8XAcA/nThxQoWFhYqLi1Pjxo0lXTozVde3850LAN7DCBEAU7HZbLLbC3iXGQCvIhABMB2bzUZAAeBV3FQNAAD8HoEIAAD4PQIRAADwewQiAADg9whEAADA7xGIAACA3yMQAQAAv8c8RABMx+FwMDEjAK8iEAEwlUvh1R2tWrXSgQMHzll///33a8GCBfVdHgAvIBABMBWn0ymXq1yPzB6plq2jPd7fgX3FenxKlpxOZ7UD0WeffaaKigr38s6dO/WrX/1Kv//97z1VJgAPIxABMKWWraMV38Gcl7GaNWtWZfmpp55SmzZt9Mtf/tJHFQGoK26qBoA6OHXqlF5//XWNGjVKAQEBvi4HQC0RiACgDt555x0dOXJEI0aM8HUpAOqAQAQAdbBo0SKlpqYqNjbW16UAqAPuIQKAWjpw4IBWr16tZcuW+boUAHXECBEA1FJWVpYiIyM1cOBAX5cCoI4IRABQC5WVlcrKylJaWpoaNmSwHbjU8VMMwJQO7Cs2dT+rV6+Ww+HQqFGj6rkiAD5h+NBLL71kdO7c2QgNDTVCQ0ON66+/3nj//ffd28vLy43777/fiIiIMJo0aWIMHjzYKC4urrKPAwcOGLfccosREhJiNGvWzPjLX/5inD59ukqbdevWGd27dzeCgoKMNm3aGFlZWd44PAA/o7y83Ni1a5dRXl7uXnfgwAHDYgkxJHntY7GEGAcOHPDhmTj/uQDgPT4dIWrevLmeeuoptWvXToZhaPHixbrtttu0fft2dezYURMnTtSKFSv09ttvKzw8XOPGjdPgwYP18ccfS5IqKio0cOBARUdHa/PmzSoqKtLdd9+tRo0a6cknn5QkFRYWauDAgbrvvvv0xhtvaM2aNbrnnnsUExOjlJSUatVZWVmpQ4cOKTQ0lHlGgHp06tQpVVZWqqKiwj3z89VXX62dO7/0+rvMrr766iqzT3tbRUWFKisrVVZWplOnTvmsDuByYhiGjh07ptjYWDVocPG7hAIMwzC8VFe1REREaO7cufrd736nZs2aacmSJfrd734nSSooKFBCQoK2bNmi66+/Xh988IF+/etf69ChQ4qKipIkLVy4UJMnT9a3336roKAgTZ48WStWrNDOnTvdfQwdOlRHjhxRbm5utWo6ePCgWrRoUf8HC/i5li1bauHChbJarb4uxRScTqfuu+++874nDUDtff3112revPlF25jmHqKKigq9/fbbOn78uBITE5WXl6fTp0+rf//+7jbt27eXzWZzB6ItW7aoc+fO7jAkSSkpKRo7dqy+/PJLde/eXVu2bKmyj7NtJkyYcMFaTp48qZMnT7qXz2bGr7/+WmFhYfV0xABOnTqlkpIStWrVSo0bN/Z1OT514sQJ7d+/X9u2bVNQUJCvywEuC6WlpWrRooVCQ0N/tq3PA9GOHTuUmJioEydO6IorrlBOTo46dOig/Px8BQUFqWnTplXaR0VFqbj4x5sgi4uLq4Shs9vPbrtYm9LSUpWXlyskJOScmmbPnq2ZM2eesz4sLIxABNSjEydO6Ntvv1VgYKACAwN9XY5PBQYGqkGDBrriiiv8PhwC9a06t7v4/LH7+Ph45efn65NPPtHYsWOVlpamXbt2+bSmKVOm6OjRo+7P119/7dN6AACAZ/l8hCgoKEht27aVJPXo0UOfffaZnn/+ed1xxx06deqUjhw5UmWUqKSkRNHR0ZKk6Ohoffrpp1X2V1JS4t529n/Prvtpm7CwsPOODklScHCwgoOD6+X4AACA+fl8hOi/VVZW6uTJk+rRo4caNWqkNWvWuLft3r1bDodDiYmJkqTExETt2LFDhw8fdrdZtWqVwsLC1KFDB3ebn+7jbJuz+wAAAPDpCNGUKVOUmpoqm82mY8eOacmSJVq/fr1Wrlyp8PBwjR49WhkZGYqIiFBYWJjGjx+vxMREXX/99ZKk5ORkdejQQcOHD9fTTz+t4uJiPfLII0pPT3eP8Nx333168cUX9eCDD2rUqFFau3at3nrrLa1YscKXhw4AAEzEp4Ho8OHDuvvuu1VUVKTw8HB16dJFK1eu1K9+9StJ0rx589SgQQMNGTJEJ0+eVEpKil566SX39wMDA7V8+XKNHTtWiYmJatKkidLS0vTYY4+528TFxWnFihWaOHGinn/+eTVv3lyvvvpqtecgAgAAlz/TzUNkRqWlpQoPD9fRo0d5ygyoRydOnFBhYaHi4uKqPFnlcDi8PjGjzWbzWn/nc6FzAaD2avLfb5/fVA0AP+VwOJSQ0F4uV7nX+rRYQmS3F1Q7FFVUVGjGjBl6/fXXVVxcrNjYWI0YMUKPPPIIs9kDlygCEQBTcTqdcrnKNXHOSDVvE+3x/g7uLda8yVlyOp3VDkRz5sxRZmamFi9erI4dO2rbtm0aOXKkwsPD9cADD3i4YgCeQCACYErN20SrTQffXsa6kM2bN+u2227TwIEDJUmtWrXSP/7xj3OmAQFw6TDdY/cAYHa9e/fWmjVr9J///EeS9L//+7/atGmTUlNTfVwZgNpihAgAauihhx5SaWmp2rdvr8DAQFVUVOiJJ57QsGHDfF0agFoiEAFADb311lt64403tGTJEnXs2FH5+fmaMGGCYmNjlZaW5uvyANQCgQgAamjSpEl66KGHNHToUElS586ddeDAAc2ePZtABFyiCEQmYLFYVF7u2UeMQ0JC5HK5PNoH4C9cLpcaNKh6C2ZgYKAqKyt9VBGAuiIQ+ZjFYtEJD4chSTpRXi6LxUIoAurBrbfeqieeeEI2m00dO3bU9u3b9dxzz2nUqFG+Lg1ALRGIfOzsyNCExHbqHBPqkT52FB3T/C1feXwUCqhPB/cWm7afF154QdOmTdP999+vw4cPKzY2Vn/84x/16KOPeqBCAN5AIDKJzjGhGtAp0tdlAD5ntVplsYRo3uQsr/VpsYTIarVWu31oaKjmz5+v+fPne64oAF5FIAJgKjabTXZ7gd+9ywyAbxGIAJiOzWYjoADwKmaqBgAAfo9ABAAA/B6BCAAA+D0CEQAA8HsEIgAA4PcIRAAAwO8RiAAAgN9jHiIApuNwOJiYEYBXEYgAmIrD4VD7hPYqd3nv3XshlhAV2AtqFIqOHTumadOmKScnR4cPH1b37t31/PPPq2fPnh6sFICnEIgAmIrT6VS5q1wj545TTOurPd5f0b5vlDXpRTmdzhoFonvuuUc7d+7U//zP/yg2Nlavv/66+vfvr127dunqqz1fN4D6RSACYEoxra+WrWOcr8s4r/Lycv3rX//Su+++q759+0qSZsyYoX//+9/KzMzU448/7uMKAdQUN1UDQA2dOXNGFRUVaty4cZX1ISEh2rRpk4+qAlAXBCIAqKHQ0FAlJiZq1qxZOnTokCoqKvT6669ry5YtKioq8nV5AGqBQAQAtfA///M/MgxDV199tYKDg/XXv/5Vd955pxo04NcqcCniJxcAaqFNmzbasGGDysrK9PXXX+vTTz/V6dOn1bp1a1+XBqAWCEQAUAdNmjRRTEyMfvjhB61cuVK33Xabr0sCUAs8ZQYAtbBy5UoZhqH4+Hjt2bNHkyZNUvv27TVy5EhflwagFghEAEypaN83pu7n6NGjmjJlig4ePKiIiAgNGTJETzzxhBo1alTPFQLwBgIRAFOxWq0KsYQoa9KLXuszxBIiq9Vao+/cfvvtuv322z1UEQBvIxABMBWbzaYCewHvMgPgVQQiAKZjs9kIKAC8iqfMAACA3yMQAQAAv0cgAgAAfo9ABAAA/B6BCAAA+D0CEQAA8HsEIgAA4PeYhwiA6TgcDiZmBOBVBCIApuJwONQ+IUHlLpfX+gyxWFRgt9coFG3cuFFz585VXl6eioqKlJOTo0GDBrm3G4ah6dOn65VXXtGRI0fUp08fZWZmql27dh44AgB1RSACYCpOp1PlLpdGPj1FMa09P2pTtM+hrAdny+l01igQHT9+XF27dtWoUaM0ePDgc7Y//fTT+utf/6rFixcrLi5O06ZNU0pKinbt2qXGjRvX5yEAqAcEIgCmFNPaJltH846mpKamKjU19bzbDMPQ/Pnz9cgjj+i2226TJP39739XVFSU3nnnHQ0dOtSbpQKoBm6qBoB6VlhYqOLiYvXv39+9Ljw8XL169dKWLVt8WBmACyEQAUA9Ky4uliRFRUVVWR8VFeXeBsBcCEQAAMDvEYgAoJ5FR0dLkkpKSqqsLykpcW8DYC4EIgCoZ3FxcYqOjtaaNWvc60pLS/XJJ58oMTHRh5UBuBCfBqLZs2erZ8+eCg0NVWRkpAYNGqTdu3dXaZOUlKSAgIAqn/vuu69KG4fDoYEDB8pisSgyMlKTJk3SmTNnqrRZv369fvGLXyg4OFht27ZVdna2pw8PwGWsrKxM+fn5ys/Pl/TjjdT5+flyOBwKCAjQhAkT9Pjjj+u9997Tjh07dPfddys2NrbKXEUAzMOnj91v2LBB6enp6tmzp86cOaOpU6cqOTlZu3btUpMmTdzt7r33Xj322GPuZYvF4v5zRUWFBg4cqOjoaG3evFlFRUW6++671ahRIz355JOSfvxFNXDgQN1333164403tGbNGt1zzz2KiYlRSkqK9w4YQLUV7XOYup9t27apX79+7uWMjAxJUlpamrKzs/Xggw/q+PHjGjNmjI4cOaIbbrhBubm5zEEEmFSAYRiGr4s469tvv1VkZKQ2bNigvn37SvpxhKhbt26aP3/+eb/zwQcf6Ne//rUOHTrkfqJj4cKFmjx5sr799lsFBQVp8uTJWrFihXbu3On+3tChQ3XkyBHl5ub+bF2lpaUKDw/X0aNHFRYWVvcD/YmAgABJ0qLBv9CATpH1uu+zcnce1uhln0v6cX4UwCxOnDihwsJCxcXFuYPCpTJTdX0737kAUDc1+e+3qSZmPHr0qCQpIiKiyvo33nhDr7/+uqKjo3Xrrbdq2rRp7lGiLVu2qHPnzlUeb01JSdHYsWP15Zdfqnv37tqyZUuV+UDOtpkwYcJ56zh58qROnjzpXi4tLa2PwwNQDTabTQV2O+8yA+BVpglElZWVmjBhgvr06aNOnTq51991111q2bKlYmNj9cUXX2jy5MnavXu3li1bJunH+T7ON9fH2W0Xa1NaWqry8nKFhIRU2TZ79mzNnDmz3o8RQPXYbDYCCgCvMk0gSk9P186dO7Vp06Yq68eMGeP+c+fOnRUTE6Obb75Ze/fuVZs2bTxSy5QpU9z3A0g/jhC1aNHCI30BAADfM8Vj9+PGjdPy5cu1bt06NW/e/KJte/XqJUnas2ePpB/n+zjfXB9nt12sTVhY2DmjQ5IUHByssLCwKh8AAHD58mkgMgxD48aNU05OjtauXau4uLif/c7ZR1xjYmIkSYmJidqxY4cOHz7sbrNq1SqFhYWpQ4cO7jY/nQ/kbBvmAwEAAJKPA1F6erpef/11LVmyRKGhoSouLlZxcbHKy8slSXv37tWsWbOUl5en/fv367333tPdd9+tvn37qkuXLpKk5ORkdejQQcOHD9f//u//auXKlXrkkUeUnp6u4OBgSdJ9992nffv26cEHH1RBQYFeeuklvfXWW5o4caLPjh0AAJiHTwNRZmamjh49qqSkJMXExLg/b775piQpKChIq1evVnJystq3b68///nPGjJkiP7973+79xEYGKjly5crMDBQiYmJ+sMf/qC77767yrxFcXFxWrFihVatWqWuXbvq2Wef1auvvsocRAAAQJKPb6r+uTlxWrRooQ0bNvzsflq2bKn333//om2SkpK0ffv2GtUHAAD8gyluqgYAAPAl0zx2DwBnORwOJmYE4FUEIgCmcqm8umPjxo2aO3eu8vLyVFRUpJycnCovbl22bJkWLlyovLw8ff/999q+fbu6detW/8UDqBcEIgCm4nQ6Ve5yadSc6Ypp08rj/RXt3a/XJs+U0+msUSA6fvy4unbtqlGjRmnw4MHn3X7DDTfo9ttv17333lufJQPwAAIRAFOKadNKtg7xvi7jglJTU5WamnrB7cOHD5ck7d+/30sVAagLbqoGAAB+j0AEAAD8HoEIAAD4PQIRAADwewQiAADg93jKDIApFe3db+p+ysrKtGfPHvdyYWGh8vPzFRERIZvNpu+//14Oh0OHDh2SJO3evVuSFB0drejo6DrXDaB+EYgAmIrValWIxaLXJs/0Wp8hFousVmuNvrNt2zb169fPvZyRkSFJSktLU3Z2tt577z2NHDnSvX3o0KGSpOnTp2vGjBl1LxpAvSIQATAVm82mArvd9K/uSEpKuugLqkeMGKERI0bUsTIA3kIgAmA6NpuNd4sB8CpuqgYAAH6PQAQAAPwegQgAAPg9AhEAAPB7BCIAAOD3CEQAAMDvEYgAAIDfIxABAAC/x8SMAEzH4XCYfqZqAJcXAhEAU3E4HGqfkKByl8trfYZYLCqw22sUijZu3Ki5c+cqLy9PRUVFysnJ0aBBgyRJp0+f1iOPPKL3339f+/btU3h4uPr376+nnnpKsbGxHjoKAHVBIAJgKk6nU+Uul0bNeVwxreM83l/RvkK9NvkROZ3OGgWi48ePq2vXrho1apQGDx5cZZvL5dLnn3+uadOmqWvXrvrhhx/0pz/9Sb/5zW+0bdu2+j4EAPWAQATAlGJax8nWIcHXZVxQamqqUlNTz7stPDxcq1atqrLuxRdf1HXXXSeHw8HlOcCEuKkaALzg6NGjCggIUNOmTX1dCoDzIBABgIedOHFCkydP1p133qmwsDBflwPgPAhEAOBBp0+f1u233y7DMJSZmenrcgBcAPcQAYCHnA1DBw4c0Nq1axkdAkyMQAQAHnA2DH311Vdat26drrrqKl+XBOAiCEQATKloX6Gp+ykrK9OePXvcy4WFhcrPz1dERIRiYmL0u9/9Tp9//rmWL1+uiooKFRcXS5IiIiIUFBRUL7UDqD8EIgCmYrVaFWKx6LXJj3itzxCLRVartUbf2bZtm/r16+dezsjIkCSlpaVpxowZeu+99yRJ3bp1q/K9devWKSkpqU71Aqh/BCIApmKz2VRgt5v+1R1JSUkyDOOC2y+2DYD5EIgAmI7NZmPyQgBexWP3AADA7xGIAACA3yMQAQAAv0cgAgAAfo9ABAAA/B6BCAAA+D0CEQAA8HsEIgAA4PeYmBGA6TgcDtPPVA3g8kIgAmAqDodD7RMSVO5yea3PEItFBXZ7jULRxo0bNXfuXOXl5amoqEg5OTkaNGiQe/uMGTO0dOlSff311woKClKPHj30xBNPqFevXh44AgB1RSACYCpOp1PlLpdGz3lK0a1be7y/4n37tGjyQ3I6nTUKRMePH1fXrl01atQoDR48+Jzt11xzjV588UW1bt1a5eXlmjdvnpKTk7Vnzx41a9asPg8BQD0gEAEwpejWrdWyQwdfl3FBqampSk1NveD2u+66q8ryc889p0WLFumLL77QzTff7OnyANQQN1UDgIedOnVKL7/8ssLDw9W1a1dflwPgPBghAgAPWb58uYYOHSqXy6WYmBitWrVKVqvV12UBOA9GiADAQ/r166f8/Hxt3rxZAwYM0O23367Dhw/7uiwA5+HTQDR79mz17NlToaGhioyM1KBBg7R79+4qbU6cOKH09HRdddVVuuKKKzRkyBCVlJRUaeNwODRw4EBZLBZFRkZq0qRJOnPmTJU269ev1y9+8QsFBwerbdu2ys7O9vThAfBzTZo0Udu2bXX99ddr0aJFatiwoRYtWuTrsgCch08D0YYNG5Senq6tW7dq1apVOn36tJKTk3X8+HF3m4kTJ+rf//633n77bW3YsEGHDh2q8kRHRUWFBg4cqFOnTmnz5s1avHixsrOz9eijj7rbFBYWauDAge5/rU2YMEH33HOPVq5c6dXjBeDfKisrdfLkSV+XAeA8fHoPUW5ubpXl7OxsRUZGKi8vT3379tXRo0e1aNEiLVmyRDfddJMkKSsrSwkJCdq6dauuv/56ffjhh9q1a5dWr16tqKgodevWTbNmzdLkyZM1Y8YMBQUFaeHChYqLi9Ozzz4rSUpISNCmTZs0b948paSkeP24Afy84n37TN1PWVmZ9uzZ414uLCxUfn6+IiIidNVVV+mJJ57Qb37zG8XExMjpdGrBggX65ptv9Pvf/76+SgdQj0x1U/XRo0clSREREZKkvLw8nT59Wv3793e3ad++vWw2m7Zs2aLrr79eW7ZsUefOnRUVFeVuk5KSorFjx+rLL79U9+7dtWXLlir7ONtmwoQJ563j5MmTVf4VV1paWl+HCOBnWK1WhVgsWjT5Ia/1GWKx1Phm523btqlfv37u5YyMDElSWlqaFi5cqIKCAi1evFhOp1NXXXWVevbsqY8++kgdO3as19oB1A/TBKLKykpNmDBBffr0UadOnSRJxcXFCgoKUtOmTau0jYqKUnFxsbvNT8PQ2e1nt12sTWlpqcrLyxUSElJl2+zZszVz5sx6OzYA1Wez2VRgt5v+1R1JSUkyDOOC25ctW1bXsgB4kWkCUXp6unbu3KlNmzb5uhRNmTLF/a896ccRohYtWviwIsC/2Gw23i0GwKtMEYjGjRun5cuXa+PGjWrevLl7fXR0tE6dOqUjR45UGSUqKSlRdHS0u82nn35aZX9nn0L7aZv/fjKtpKREYWFh54wOSVJwcLCCg4Pr5dgAAID5+fQpM8MwNG7cOOXk5Gjt2rWKi4ursr1Hjx5q1KiR1qxZ4163e/duORwOJSYmSpISExO1Y8eOKnN7rFq1SmFhYerw/6f9T0xMrLKPs23O7gMAAPg3n44Qpaena8mSJXr33XcVGhrqvucnPDxcISEhCg8P1+jRo5WRkaGIiAiFhYVp/PjxSkxM1PXXXy9JSk5OVocOHTR8+HA9/fTTKi4u1iOPPKL09HT3KM99992nF198UQ8++KBGjRqltWvX6q233tKKFSt8duwAAMA8fDpClJmZqaNHjyopKUkxMTHuz5tvvuluM2/ePP3617/WkCFD1LdvX0VHR1e5WTEwMFDLly9XYGCgEhMT9Yc//EF33323HnvsMXebuLg4rVixQqtWrVLXrl317LPP6tVXX+WRewAAIMnHI0QXe0LjrMaNG2vBggVasGDBBdu0bNlS77///kX3k5SUpO3bt9e4RgAAcPnjXWYAAMDvEYgAAIDfIxABAAC/Z4p5iADgpxwOh+lnqgZweSEQATAVh8Oh9gkJKne5vNZniMWiAru9RqFo48aNmjt3rvLy8lRUVKScnBwNGjTovG3vu+8+/e1vf9O8efMu+A5FAL5FIAJgKk6nU+Uul0Y/9YyiW7fxeH/F+/Zq0UN/kdPprFEgOn78uLp27apRo0Zp8ODBF2yXk5OjrVu3KjY2tj7KBeAhBCIAphTduo1adjDvm+FTU1OVmpp60TbffPONxo8fr5UrV2rgwIFeqgxAbXBTNQB4QGVlpYYPH65JkyapY0fzBjsAPyIQAYAHzJkzRw0bNtQDDzzg61IAVAOXzACgnuXl5en555/X559/roCAAF+XA6AaGCECgHr20Ucf6fDhw7LZbGrYsKEaNmyoAwcO6M9//rNatWrl6/IAnAcjRABQz4YPH67+/ftXWZeSkqLhw4dr5MiRPqoKwMUQiACYUvG+vabup6ysTHv27HEvFxYWKj8/XxEREbLZbLrqqquqtG/UqJGio6MVHx9fp3oBeAaBCICpWK1WhVgsWvTQX7zWZ4jFIqvVWqPvbNu2Tf369XMvZ2RkSJLS0tKUnZ1dn+UB8AICEQBTsdlsKrDbTf/qjqSkJBmGUe32+/fvr2FVALyJQATAdGw2G+8WA+BVPGUGAAD8HoEIAAD4PQIRAADwewQiAADg9whEAADA7xGIAACA3yMQAQAAv0cgAgAAfo+JGQGYjsPhMP1M1QAuLwQiAKbicDjUPiFB5S6X1/oMsVhUYLfXKBRt3LhRc+fOVV5enoqKipSTk6NBgwa5t48YMUKLFy+u8p2UlBTl5ubWV9kA6hGBCICpOJ1OlbtcGj17vmJat/V4f0X79mjRlAlyOp01CkTHjx9X165dNWrUKA0ePPi8bQYMGKCsrCz3cnBwcJ3rBeAZBCIAphTTuq1adujs6zIuKDU1VampqRdtExwcrOjoaC9VBKAuuKkaADxk/fr1ioyMVHx8vMaOHavvvvvO1yUBuABGiADAAwYMGKDBgwcrLi5Oe/fu1dSpU5WamqotW7YoMDDQ1+UB+C8EIgDwgKFDh7r/3LlzZ3Xp0kVt2rTR+vXrdfPNN/uwMgDnwyUzAPCC1q1by2q1as+ePb4uBcB5EIgAwAsOHjyo7777TjExMb4uBcB5cMkMgCkV7fPOSEpt+ykrK6sy2lNYWKj8/HxFREQoIiJCM2fO1JAhQxQdHa29e/fqwQcfVNu2bZWSklJfpQOoRwQiAKZitVoVYrFo0ZQJXuszxGKR1Wqt0Xe2bdumfv36uZczMjIkSWlpacrMzNQXX3yhxYsX68iRI4qNjVVycrJmzZrFXESASRGIAJiKzWZTgd1u+ld3JCUlyTCMC25fuXJlXcsC4EW1CkStW7fWZ599pquuuqrK+iNHjugXv/iF9u3bVy/FAfBPNpuNd4sB8Kpa3VS9f/9+VVRUnLP+5MmT+uabb+pcFAAAgDfVaITovffec/955cqVCg8Pdy9XVFRozZo1atWqVb0VBwAA4A01CkRn3+QcEBCgtLS0KtsaNWqkVq1a6dlnn6234gAAALyhRoGosrJSkhQXF6fPPvusxk9lAAAAmFGtbqouLCys7zoAAAB8ptaP3a9Zs0Zr1qzR4cOH3SNHZ7322mt1LgwAAMBbahWIZs6cqccee0zXXnutYmJiFBAQUN91AQAAeE2tAtHChQuVnZ2t4cOH13c9ACCHw2H6iRkBXF5qFYhOnTql3r1713ctACCHw6H2CQkqd7m81meIxaICu51QBPixWgWie+65R0uWLNG0adPqux4Afs7pdKrc5dI9szMVE9fO4/0VFX6lV6eMldPprFEg2rhxo+bOnau8vDwVFRUpJyfHPTXJWXa7XZMnT9aGDRt05swZdejQQf/6178IXoAJ1SoQnThxQi+//LJWr16tLl26qFGjRlW2P/fcc/VSHAD/FRPXTi07dPV1GRd0/Phxde3aVaNGjdLgwYPP2b53717dcMMNGj16tGbOnKmwsDB9+eWXaty4sQ+qBfBzahWIvvjiC3Xr1k2StHPnzirbuMEagD9ITU1VamrqBbc//PDDuuWWW/T000+717Vp08YbpQGohVoFonXr1tV3HQBw2aisrNSKFSv04IMPKiUlRdu3b1dcXJymTJlyzmU1AOZQq5e7AgAu7PDhwyorK9NTTz2lAQMG6MMPP9Rvf/tbDR48WBs2bPB1eQDOo1YjRP369bvopbG1a9dWaz8/d1PiiBEjtHjx4irfSUlJUW5urnv5+++/1/jx4/Xvf/9bDRo00JAhQ/T888/riiuucLf54osvlJ6ers8++0zNmjXT+PHj9eCDD1bzaAGgZs5OVnvbbbdp4sSJkqRu3bpp8+bNWrhwoX75y1/6sjygxrwxFYavp7+oVSA6e//QWadPn1Z+fr527tx5zktfL+bnbkqUpAEDBigrK8u9HBwcXGX7sGHDVFRUpFWrVun06dMaOXKkxowZoyVLlkiSSktLlZycrP79+2vhwoXasWOHRo0apaZNm2rMmDHVrhUAqstqtaphw4bq0KFDlfUJCQnatGmTj6oCasfhcCghIUEuD0+FYbFYZPfh9Be1CkTz5s077/oZM2aorKys2vv5uZsSpR8DUHR09Hm32e125ebm6rPPPtO1114rSXrhhRd0yy236JlnnlFsbKzeeOMNnTp1Sq+99pqCgoLUsWNH5efn67nnniMQAfCIoKAg9ezZU7t3766y/j//+Y9atmzpo6qA2nE6nXK5XMqeNE0JNs/8/bU7DmjE3Fk1nv6iPtX6XWbn84c//EHXXXednnnmmXrb5/r16xUZGakrr7xSN910kx5//HFdddVVkqQtW7aoadOm7jAkSf3791eDBg30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o4+quLhY3bp1U25urqKionxaV3BwsKZPn+7xGWz9HefZOzjP3sF59h7OtXeY4Tz7xWP3AAAAF+MX9xABAABcDIEIAAD4PQIRAADwewQiAADg9whEXrBgwQK1atVKjRs3Vq9evfTpp59etP3bb7+t9u3bq3HjxurcubPef/99L1V6aavJeX7llVd044036sorr9SVV16p/v37/+z/L/hRTf8+n7V06VIFBARUeZ8gLqym5/nIkSNKT09XTEyMgoODdc011/C7o5pqeq7nz5+v+Ph4hYSEqEWLFpo4caJOnDjhpWovPRs3btStt96q2NhYBQQE6J133vnZ76xfv16/+MUvFBwcrLZt2yo7O9vjdfrFu8x8aenSpUZQUJDx2muvGV9++aVx7733Gk2bNjVKSkrO2/7jjz82AgMDjaefftrYtWuX8cgjjxiNGjUyduzY4eXKLy01Pc933XWXsWDBAmP79u2G3W43RowYYYSHhxsHDx70cuWXlpqe57MKCwuNq6++2rjxxhuN2267zTvFXsJqep5PnjxpXHvttcYtt9xibNq0ySgsLDTWr19v5Ofne7nyS09Nz/Ubb7xhBAcHG2+88YZRWFhorFy50oiJiTEmTpzo5covHe+//77x8MMPG8uWLTMkGTk5ORdtv2/fPsNisRgZGRnGrl27jBdeeMEIDAw0cnNzPVongcjDrrvuOiM9Pd29XFFRYcTGxhqzZ88+b/vbb7/dGDhwYJV1vXr1Mv74xz96tM5LXU3P8387c+aMERoaaixevNhTJV4WanOez5w5Y/Tu3dt49dVXjbS0NAJRNdT0PGdmZhqtW7c2Tp065a0SLxs1Pdfp6enGTTfdVGVdRkaG0adPH4/WebmoTiB68MEHjY4dO1ZZd8cddxgpKSkerMwwuGTmQadOnVJeXp769+/vXtegQQP1799fW7ZsOe93tmzZUqW9JKWkpFywPWp3nv+by+XS6dOnFRER4akyL3m1Pc+PPfaYIiMjNXr0aG+UecmrzXl+7733lJiYqPT0dEVFRalTp0568sknVVFR4a2yL0m1Ode9e/dWXl6e+7Lavn379P777+uWW27xSs3+wFf/HfSbmap9wel0qqKi4pzZsKOiolRQUHDe7xQXF5+3fXFxscfqvNTV5jz/t8mTJys2NvacH0L8n9qc502bNmnRokXKz8/3QoWXh9qc53379mnt2rUaNmyY3n//fe3Zs0f333+/Tp8+renTp3uj7EtSbc71XXfdJafTqRtuuEGGYejMmTO67777NHXqVG+U7Bcu9N/B0tJSlZeXKyQkxCP9MkIEv/fUU09p6dKlysnJUePGjX1dzmXj2LFjGj58uF555RVZrVZfl3NZq6ysVGRkpF5++WX16NFDd9xxhx5++GEtXLjQ16VddtavX68nn3xSL730kj7//HMtW7ZMK1as0KxZs3xdGuqIESIPslqtCgwMVElJSZX1JSUlio6OPu93oqOja9QetTvPZz3zzDN66qmntHr1anXp0sWTZV7yanqe9+7dq/379+vWW291r6usrJQkNWzYULt371abNm08W/QlqDZ/n2NiYtSoUSMFBga61yUkJKi4uFinTp1SUFCQR2u+VNXmXE+bNk3Dhw/XPffcI0nq3Lmzjh8/rjFjxujhhx9WgwaMM9TVhf47GBYW5rHRIYkRIo8KCgpSjx49tGbNGve6yspKrVmzRomJief9TmJiYpX2krRq1aoLtkftzrMkPf3005o1a5Zyc3N17bXXeqPUS1pNz3P79u21Y8cO5efnuz+/+c1v1K9fP+Xn56tFixbeLP+SUZu/z3369NGePXvcgVOS/vOf/ygmJoYwdBG1Odcul+uc0HM2iBq8GrRe+Oy/gx69ZRvG0qVLjeDgYCM7O9vYtWuXMWbMGKNp06ZGcXGxYRiGMXz4cOOhhx5yt//444+Nhg0bGs8884xht9uN6dOn89h9NdT0PD/11FNGUFCQ8c9//tMoKipyf44dO+arQ7gk1PQ8/zeeMquemp5nh8NhhIaGGuPGjTN2795tLF++3IiMjDQef/xxXx3CJaOm53r69OlGaGio8Y9//MPYt2+f8eGHHxpt2rQxbr/9dl8dgukdO3bM2L59u7F9+3ZDkvHcc88Z27dvNw4cOGAYhmE89NBDxvDhw93tzz52P2nSJMNutxsLFizgsfvLxQsvvGDYbDYjKCjIuO6664ytW7e6t/3yl7800tLSqrR/6623jGuuucYICgoyOnbsaKxYscLLFV+aanKeW7ZsaUg65zN9+nTvF36Jqenf558iEFVfTc/z5s2bjV69ehnBwcFG69atjSeeeMI4c+aMl6u+NNXkXJ8+fdqYMWOG0aZNG6Nx48ZGixYtjPvvv9/44YcfvF/4JWLdunXn/X179rympaUZv/zlL8/5Trdu3YygoCCjdevWRlZWlsfrDDAMxvgAAIB/4x4iAADg9whEAADA7xGIAACA3yMQAQAAv0cgAgAAfo9ABAAA/B6BCAAA+D0CEQAA8HsEIgAA4PcIRAAAwO8RiAAAgN8jEAEAAL/3/wBcBoliJ/eicwAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "sns.histplot(t_1_train_scaled)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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uXzWZ4TFohy7vcqhaMuWLZo7d66ysrKUn5+vzMxMDR482H182rRpWrFihQ4fPqywsDB169ZNM2fOVM+ePU0aAQAA/kEgMonT6dRpl0uj58xWTKtWpvdXcOCAlk56XE6ns8qB6NSpU+rcubNGjRqlIUOGXHD8uuuu00svvaRWrVrp9OnTWrBggfr376/c3Fw1btzY20MAAMBvCEQmi2nVSi3at/d3GZVKTk5WcnLyRY//9re/9dieP3++li5dqi+++EK33Xab2eUBAOAz3FSNKiktLdUrr7yiqKgode7c2d/lAADgVVwhwiW9++67GjZsmFwul2JjY7Vu3TpZrVZ/lwUAgFdxhQiX1K9fP2VnZ+uTTz7RwIEDddddd+no0aP+LgsAAK/yeyD69ttv9bvf/U7XXHONIiIi1KlTJ+3cudN93DAMTZ06VbGxsYqIiFBSUpL279/vcY5jx45p+PDhioyMVKNGjTR69GiVlJR4tPniiy/0s5/9TOHh4WrevLmee+45n4yvpmvQoIHatGmjm266SUuXLlXdunW1dOlSf5cFAIBX+TUQHT9+XDfffLPq1aunDz74QHv37tXzzz+vq6++2t3mueee05/+9CctWbJEn376qRo0aKABAwbozJkz7jbDhw/Xnj17tG7dOr377rvasmWLxowZ4z5eXFys/v37q0WLFsrKytLcuXM1bdo0vfLKKz4db21QUVGhs2fP+rsMAAC8yq/3EM2ZM0fNmzdXenq6e198fLz73w3D0MKFC/Xkk0/qjjvukCT99a9/VdOmTfXOO+9o2LBhstvtWrNmjXbs2KEbb7xRkvTiiy/q9ttv17x58xQXF6c33nhDpaWleu211xQWFqYOHTooOztb8+fP9whOZig4cMDU819JPyUlJcrNzXVv5+XlKTs7W9HR0brmmms0c+ZM/epXv1JsbKycTqcWLVqkb7/9Vr/+9a+9WToAAH7n10C0evVqDRgwQL/+9a+1efNmXXvttXrooYd0//33S/r+D3RBQYGSkpLcr4mKilLPnj21bds2DRs2TNu2bVOjRo3cYUiSkpKSVKdOHX366ae68847tW3bNvXp00dhYWHuNgMGDNCcOXN0/PhxjytSknT27FmPqyDFxcXVHpvValWExaKlkx6v9msvV4TFUq0bnnfu3Kl+/fq5t9PS0iRJKSkpWrJkiXJycrRs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iAglJSVp//79Hm2OHTum4cOHKzIyUo0aNdLo0aNVUlJiwgh+WnVrOXjwoEJCQir9evvtt93tKju+YsUKXwzJw+V8r/v27XtB7Q888IBHG4fDoUGDBslisahJkyaaOHGiysrKzBxKpao7vmPHjunhhx9WQkKCIiIiZLPZNG7cOBUVFXm08+f7t2jRIrVs2VLh4eHq2bOnPvvss0u2f/vtt9WuXTuFh4erU6dOev/99z2OV+V30peqM75XX31VP/vZz3T11Vfr6quvVlJS0gXtR4wYccF7NXDgQLOHcUnVGWNGRsYF9YeHh3u0qcnvYWX/PQkJCdGgQYPcbQLpPdyyZYt++ctfKi4uTiEhIXrnnXd+8jWbNm3SDTfcoPr166tNmzbKyMi4oE11f6+rzQtLheESpk6dasyfP99IS0szoqKiqvSa2bNnG1FRUcY777xj/Pvf/zZ+9atfGfHx8cbp06fdbQYOHGh07tzZ2L59u/Gvf/3LaNOmjXH33XebNIpLq24tZWVlRn5+vsfX9OnTjauuuso4efKku50kIz093aPdD78HvnI53+tbb73VuP/++z1qLyoqch8vKyszOnbsaCQlJRm7du0y3n//fcNqtRqTJ082ezgXqO74vvzyS2PIkCHG6tWrjdzcXGP9+vVG27ZtjaFDh3q089f7t2LFCiMsLMx47bXXjD179hj333+/0ahRI6OwsLDS9h9//LERGhpqPPfcc8bevXuNJ5980qhXr57x5ZdfuttU5XfSV6o7vt/+9rfGokWLjF27dhl2u90YMWKEERUVZXzzzTfuNikpKcbAgQM93qtjx475akgXqO4Y09PTjcjISI/6CwoKPNrU5Pfwu+++8xjb7t27jdDQUCM9Pd3dJpDew/fff9/44x//aKxcudKQZGRmZl6y/YEDBwyLxWKkpaUZe/fuNV588UUjNDTUWLNmjbtNdb9nl4NA5CPp6elVCkQVFRVGTEyMMXfuXPe+EydOGPXr1zf+9re/GYZhGHv37jUkGTt27HC3+eCDD4yQkBDj22+/9Xrtl+KtWrp06WKMGjXKY19VfpHMdrnju/XWW41HHnnkosfff/99o06dOh7/0V68eLERGRlpnD171iu1V4W33r+33nrLCAsLM86dO+fe56/3r0ePHkZqaqp7u7y83IiLizNmzZpVafu77rrLGDRokMe+nj17Gr///e8Nw6ja76QvVXd8P1ZWVmY0bNjQWLZsmXtfSkqKcccdd3i71MtW3TH+1H9fa9t7uGDBAqNhw4ZGSUmJe1+gvYfnVeW/A4899pjRoUMHj32/+c1vjAEDBri3r/R7VhV8ZBZg8vLyVFBQoKSkJPe+qKgo9ezZU9u2bZMkbdu2TY0aNdKNN97obpOUlKQ6dero008/9Wm93qglKytL2dnZGj169AXHUlNTZbVa1aNHD7322msyfDxt1pWM74033pDValXHjh01efJkuVwuj/N26tTJY2LQAQMGqLi4WHv27PH+QC7CWz9LRUVFioyMVN26nnO9+vr9Ky0tVVZWlsfvT506dZSUlOT+/fmxbdu2ebSXvn8vzrevyu+kr1zO+H7M5XLp3Llzio6O9ti/adMmNWnSRAkJCXrwwQf13XffebX2qrrcMZaUlKhFixZq3ry57rjjDo/fo9r2Hi5dulTDhg1TgwYNPPYHyntYXT/1O+iN71lVBM1M1TVFQUGBJF0wg3bTpk3dxwoKCtSkSROP43Xr1lV0dLS7ja94o5alS5cqMTFRvXv39tj/9NNP6+c//7ksFos+/PBDPfTQQyopKdG4ceO8Vv9Pudzx/fa3v1WLFi0UFxenL774QpMmTdK+ffu0cuVK93kre4/PH/MVb7x/TqdTM2bM0JgxYzz2++P9czqdKi8vr/R7m5OTU+lrLvZe/PD37fy+i7XxlcsZ349NmjRJcXFxHn9cBg4cqCFDhig+Pl5ff/21nnjiCSUnJ2vbtm0KDQ316hh+yuWMMSEhQa+99pquv/56FRUVad68eerdu7f27NmjZs2a1ar38LPPPtPu3bu1dOlSj/2B9B5W18V+B4uLi3X69GkdP378in/uq4JAdBkef/xxzZkz55Jt7Ha72rVr56OKvK+qY7xSp0+f1vLlyzVlypQLjv1wX9euXXXq1CnNnTvXK39QzR7fD8NBp06dFBsbq9tuu01ff/21WrdufdnnrSpfvX/FxcUaNGiQ2rdvr2nTpnkcM/P9w+WZPXu2VqxYoU2bNnncdDxs2DD3v3fq1EnXX3+9WrdurU2bNum2227zR6nV0qtXL4+Funv37q3ExES9/PLLmjFjhh8r876lS5eqU6dO6tGjh8f+mv4eBgIC0WV49NFHNWLEiEu2adWq1WWdOyYmRpJUWFio2NhY9/7CwkJ16dLF3ebo0aMerysrK9OxY8fcr79SVR3jldby97//XS6XS/fee+9Ptu3Zs6dmzJihs2fPXvF6N74a33k9e/aUJOXm5qp169aKiYm54AmJwsJCSfLKe+iL8Z08eVIDBw5Uw4YNlZmZqXr16l2yvTffv4uxWq0KDQ11fy/PKywsvOh4YmJiLtm+Kr+TvnI54ztv3rx5mj17tj766CNdf/31l2zbqlUrWa1W5ebm+vyP6ZWM8bx69eqpa9euys3NlVR73sNTp05pxYoVevrpp3+yH3++h9V1sd/ByMhIRUREKDQ09Ip/JqrEa3cj4ZKqe1P1vHnz3PuKiooqval6586d7jZr1671603Vl1vLrbfeesHTSRfzzDPPGFdfffVl13o5vPW93rp1qyHJ+Pe//20Yxv/dVP3DJyRefvllIzIy0jhz5oz3BvATLnd8RUVFxk033WTceuutxqlTp6rUl6/evx49ehhjx451b5eXlxvXXnvtJW+q/p//+R+Pfb169brgpupL/U76UnXHZxiGMWfOHCMyMtLYtm1blfo4fPiwERISYqxateqK670clzPGHyorKzMSEhKMCRMmGIZRO95Dw/j+70j9+vUNp9P5k334+z08T1W8qbpjx44e++6+++4Lbqq+kp+JKtXqtTOhUocOHTJ27drlfqx8165dxq5duzweL09ISDBWrlzp3p49e7bRqFEjY9WqVcYXX3xh3HHHHZU+dt+1a1fj008/NbZu3Wq0bdvWr4/dX6qWb775xkhISDA+/fRTj9ft37/fCAkJMT744IMLzrl69Wrj1VdfNb788ktj//79xp///GfDYrEYU6dONX08P1bd8eXm5hpPP/20sXPnTiMvL89YtWqV0apVK6NPnz7u15x/7L5///5Gdna2sWbNGqNx48Z+e+y+OuMrKioyevbsaXTq1MnIzc31eMy3rKzMMAz/vn8rVqww6tevb2RkZBh79+41xowZYzRq1Mj9RN8999xjPP744+72H3/8sVG3bl1j3rx5ht1uN5566qlKH7v/qd9JX6nu+GbPnm2EhYUZf//73z3eq/P/DTp58qTxhz/8wdi2bZuRl5dnfPTRR8YNN9xgtG3b1qfh/ErGOH36dGPt2rXG119/bWRlZRnDhg0zwsPDjT179rjb1OT38LxbbrnF+M1vfnPB/kB7D0+ePOn+WyfJmD9/vrFr1y7j0KFDhmEYxuOPP27cc8897vbnH7ufOHGiYbfbjUWLFlX62P2lvmfeQCAyWUpKiiHpgq+NGze62+i/87WcV1FRYUyZMsVo2rSpUb9+feO2224z9u3b53He7777zrj77ruNq666yoiMjDRGjhzpEbJ86adqycvLu2DMhmEYkydPNpo3b26Ul5dfcM4PPvjA6NKli3HVVVcZDRo0MDp37mwsWbKk0rZmq+74HA6H0adPHyM6OtqoX7++0aZNG2PixIke8xAZhmEcPHjQSE5ONiIiIgyr1Wo8+uijHo+t+0p1x7dx48ZKf6YlGXl5eYZh+P/9e/HFFw2bzWaEhYUZPXr0MLZv3+4+duuttxopKSke7d966y3juuuuM8LCwowOHToY7733nsfxqvxO+lJ1xteiRYtK36unnnrKMAzDcLlcRv/+/Y3GjRsb9erVM1q0aGHcf//9Xv1DczmqM8bx48e72zZt2tS4/fbbjc8//9zjfDX5PTQMw8jJyTEkGR9++OEF5wq09/Bi/404P6aUlBTj1ltvveA1Xbp0McLCwoxWrVp5/E0871LfM28IMQwfP8cMAAAQYJiHCAAABD0CEQAACHoEIgAAEPQIRAAAIOgRiAAAQNAjEAEAgKBHIAIAAEGPQAQAAIIegQgAAAQ9AhEAAAh6BCIAABD0CEQAACDo/X+KCI8qAphZNgAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sns.histplot(t_1_test)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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AOADM2bMUO3atfX4448HuhQAVcAlMwDwstzcXL366qvatm2bezR6AObGGSIA8LJ///vfOnTokGw2m2rXrq3atWtr3759+uMf/6gWLVoEujwAF8EZIgDwsiFDhqh3796V1vXt21dDhgzRsGHDAlQVgMshEAEwpeI935i6n7KyMhUUFLiXCwsLlZeXp+joaNlsNjVs2LBS+zp16igmJkZt27atUb0AfINABMBUrFarIiwWLXjqf/zWZ4TFIqvV6tF7tm7dql69ermX09PTJUmpqanKysryZnkA/IBABMBUbDab8u1200/dkZycLMMwqtx+7969HlYFwJ8IRABMx2azMbcYAL/iKTMAABD0CEQAACDoEYgAAEDQIxABAICgRyACAABBj0AEAACCHoEIAAAEPQIRAAAIegzMCMB0HA6H6UeqBnB1IRABMBWHw6GExESddLn81meExaJ8u92jUJSTk6OZM2cqNzdXRUVFys7OVv/+/d3bhw4dqoULF1Z6T9++fbVixQpvlQ3AiwhEAEzF6XTqpMulEdPmKLZla5/3V7SnQAvGj5bT6fQoEJ04cUIdO3bU8OHDNWDAgIu2ueuuu5SZmelerlu3bo3rBeAbBCIAphTbsrWat7sh0GVcUkpKilJSUi7bpm7duoqJifFTRQBqgpuqAcBH1q1bp8aNG6tt27Z65JFH9P333we6JACXwBkiAPCBu+66SwMGDFB8fLy++eYbTZgwQSkpKdq0aZNCQ0MDXR6AnyAQAYAPDBo0yP3nG264QTfeeKNatWqldevW6c477wxgZQAuhktmAOAHLVu2lNVqVUFBQaBLAXARBCIA8IMDBw7o+++/V2xsbKBLAXARXDIDYEpFe/xzJqW6/ZSVlVU621NYWKi8vDxFR0crOjpazz33nAYOHKiYmBh98803evLJJ9W6dWv17dvXW6UD8CICEQBTsVqtirBYtGD8aL/1GWGxyGq1evSerVu3qlevXu7l9PR0SVJqaqoyMjL0xRdfaOHChTp69Kji4uLUp08fTZkyhbGIAJMiEAEwFZvNpny73fRTdyQnJ8swjEtuX7lyZU3LAuBH1QpELVu21JYtW9SwYcNK648ePaqbb75Ze/bs8UpxAIKTzWZjbjEAflWtm6r37t2r8vLyC9afPn1a3377bY2LAgAA8CePzhAtXbrU/eeVK1cqKirKvVxe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ePBghYeHB7oUAJfg0SWzZ555RkuWLNH111+vUaNGqW3btpKk/Px8zZs3T+Xl5Xr66ac9KqCsrEyDBw/Wm2++qRdeeMG9/tixY1qwYIEWLVqkX/ziF5KkzMxMJSYmavPmzbr11lv18ccfa+fOnfrkk0/UpEkT3XTTTZoyZYrGjRunyZMnKywsTPPnz1d8fLxeeeUVST8MD7BhwwbNnj1bffv29ahWAPDUv//9b+3atUvvvvtuoEsBcBkenSFq0qSJNm7cqA4dOmj8+PG67777dN9992nChAnq0KGDNmzYoCZNmnhUQFpamvr163fBGEa5ubk6e/ZspfUJCQmy2WzatGmTJGnTpk264YYbKvXZt29flZaW6quvvnK3+em++/bt697HxZw+fVqlpaWVXgBQHQsWLFDnzp3VsWPHQJcC4DI8HpixefPm+vDDD3XkyBEVFBTIMAy1adNG1157rcedL168WNu2bdOWLVsu2FZcXKywsDA1aNCg0vomTZqouLjY3eanAez88s+1KS0t1cmTJxUREXFB39OmTdNzzz3n8ecB4D0HC/NN3U9ZWZkKCgrcy4WFhcrLy1N0dLR7PKPS0lK9//777jPUAMyrWiNVS9K1116rrl27Vrvj/fv364knntCqVatMd119/PjxSk9Pdy+Xlpa6pygB4FtWq1URFosynh7qtz4jLBZZrVaP3rN161b16tXLvXz+Z0Zqaqr7wY3FixfLMAw98MADXqsVgG9UOxDVVG5urg4dOqSbb77Zva68vFw5OTl6/fXXtXLlSp05c0ZHjx6tdJaopKTEPb5HTEyMPv/880r7Pf8U2o/b/PTJtJKSEkVGRl707JAk1a1bV3Xr1q3xZwTgOZvNpny73fRzmSUnJ8swjMu2GTlypEaOHFmT0gD4ScAC0Z133qkvv/yy0rphw4YpISFB48aNU7NmzVSnTh2tXr3aPbLrrl275HA4lJSUJElKSkrS1KlTdejQITVu3FiStGrVKkVGRqpdu3buNh9++GGlflatWuXeBwDzsdlszCsGwK8CFojq16+vDh06VFpXr149NWzY0L1+xIgRSk9PV3R0tCIjI/XYY48pKSlJt956q6QfRsZu166dhgwZopdeeknFxcV65plnlJaW5j7D8/DDD+v111/Xk08+qeHDh2vNmjV67733tHz5cv9+YAAAYFoBC0RVMXv2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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sns.histplot(t_1_test_scaled)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "train_scaled_2, test_scaled_1 = scale_data2(t_1_train, t_1_test)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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AOADM2bMUO3atfX4448HuhQAVcAlMwDwstzcXL366qvatm2bezR6AObGGSIA8LJ///vfOnTokGw2m2rXrq3atWtr3759+uMf/6gWLVoEujwAF8EZIgDwsiFDhqh3796V1vXt21dDhgzRsGHDAlQVgMshEAEwpeI935i6n7KyMhUUFLiXCwsLlZeXp+joaNlsNjVs2LBS+zp16igmJkZt27atUb0AfINABMBUrFarIiwWLXjqf/zWZ4TFIqvV6tF7tm7dql69ermX09PTJUmpqanKysryZnkA/IBABMBUbDab8u1200/dkZycLMMwqtx+7969HlYFwJ8IRABMx2azMbcYAL/iKTMAABD0CEQAACDoEYgAAEDQIxABAICgRyACAABBj0AEAACCHoEIAAAEPQIRAAAIegzMCMB0HA6H6UeqBnB1IRABMBWHw6GExESddLn81meExaJ8u92jUJSTk6OZM2cqNzdXRUVFys7OVv/+/d3bhw4dqoULF1Z6T9++fbVixQpvlQ3AiwhEAEzF6XTqpMulEdPmKLZla5/3V7SnQAvGj5bT6fQoEJ04cUIdO3bU8OHDNWDAgIu2ueuuu5SZmelerlu3bo3rBeAbBCIAphTbsrWat7sh0GVcUkpKilJSUi7bpm7duoqJifFTRQBqgpuqAcBH1q1bp8aNG6tt27Z65JFH9P333we6JACXwBkiAPCBu+66SwMGDFB8fLy++eYbTZgwQSkpKdq0aZNCQ0MDXR6AnyAQAYAPDBo0yP3nG264QTfeeKNatWqldevW6c477wxgZQAuhktmAOAHLVu2lNVqVUFBQaBLAXARBCIA8IMDBw7o+++/V2xsbKBLAXARXDIDYEpFe/xzJqW6/ZSVlVU621NYWKi8vDxFR0crOjpazz33nAYOHKiYmBh98803evLJJ9W6dWv17dvXW6UD8CICEQBTsVqtirBYtGD8aL/1GWGxyGq1evSerVu3qlevXu7l9PR0SVJqaqoyMjL0xRdfaOHChTp69Kji4uLUp08fTZkyhbGIAJMiEAEwFZvNpny73fRTdyQnJ8swjEtuX7lyZU3LAuBH1QpELVu21JYtW9SwYcNK648ePaqbb75Ze/bs8UpxAIKTzWZjbjEAflWtm6r37t2r8vLyC9afPn1a3377bY2LAgAA8CePzhAtXbrU/eeVK1cqKirKvVxe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ePBghYeHB7oUAJfg0SWzZ555RkuWLNH111+vUaNGqW3btpKk/Px8zZs3T+Xl5Xr66ac9KqCsrEyDBw/Wm2++qRdeeMG9/tixY1qwYIEWLVqkX/ziF5KkzMxMJSYmavPmzbr11lv18ccfa+fOnfrkk0/UpEkT3XTTTZoyZYrGjRunyZMnKywsTPPnz1d8fLxeeeUVST8MD7BhwwbNnj1bffv29ahWAPDUv//9b+3atUvvvvtuoEsBcBkenSFq0qSJNm7cqA4dOmj8+PG67777dN9992nChAnq0KGDNmzYoCZNmnhUQFpamvr163fBGEa5ubk6e/ZspfUJCQmy2WzatGmTJGnTpk264YYbKvXZt29flZaW6quvvnK3+em++/bt697HxZw+fVqlpaWVXgBQHQsWLFDnzp3VsWPHQJcC4DI8HpixefPm+vDDD3XkyBEVFBTIMAy1adNG1157rcedL168WNu2bdOWLVsu2FZcXKywsDA1aNCg0vomTZqouLjY3eanAez88s+1KS0t1cmTJxUREXFB39OmTdNzzz3n8ecB4D0HC/NN3U9ZWZkKCgrcy4WFhcrLy1N0dLR7PKPS0lK9//777jPUAMyrWiNVS9K1116rrl27Vrvj/fv364knntCqVatMd119/PjxSk9Pdy+Xlpa6pygB4FtWq1URFosynh7qtz4jLBZZrVaP3rN161b16tXLvXz+Z0Zqaqr7wY3FixfLMAw98MADXqsVgG9UOxDVVG5urg4dOqSbb77Zva68vFw5OTl6/fXXtXLlSp05c0ZHjx6tdJaopKTEPb5HTEyMPv/880r7Pf8U2o/b/PTJtJKSEkVGRl707JAk1a1bV3Xr1q3xZwTgOZvNpny73fRzmSUnJ8swjMu2GTlypEaOHFmT0gD4ScAC0Z133qkvv/yy0rphw4YpISFB48aNU7NmzVSnTh2tXr3aPbLrrl275HA4lJSUJElKSkrS1KlTdejQITVu3FiStGrVKkVGRqpdu3buNh9++GGlflatWuXeBwDzsdlszCsGwK8CFojq16+vDh06VFpXr149NWzY0L1+xIgRSk9PV3R0tCIjI/XYY48pKSlJt956q6QfRsZu166dhgwZopdeeknFxcV65plnlJaW5j7D8/DDD+v111/Xk08+qeHDh2vNmjV67733tHz5cv9+YAAAYFoBC0RVMXv2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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sns.histplot(test_scaled_1)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(2875, 25)" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "t_1_train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1.0" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "t_1_train[:, 0].min()" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.48529729631535756 0.7426486481576787\n", + "-1.0 1.0\n", + "0.0 1.0\n", + "-------------\n", + "0.0019739897816999537 0.0019739897816999537\n", + "0.0 1.0\n", + "0.0 1.0\n", + "-------------\n", + "0.00034835113794705065 0.00034835113794705065\n", + "0.0 1.0\n", + "0.0 1.0\n", + "-------------\n", + "0.0015095215977705527 0.0015095215977705527\n", + "0.0 1.0\n", + "0.0 1.0\n", + "-------------\n", + "0.0 0.0\n", + "0.0 0.0\n", + "0.0 0.0\n", + "-------------\n", + "0.008941012540640966 0.008941012540640966\n", + "0.0 1.0\n", + "0.0 1.0\n", + "-------------\n", + "0.006967022758941012 0.006967022758941012\n", + "0.0 1.0\n", + "0.0 1.0\n", + "-------------\n", + "0.00023223409196470042 0.00023223409196470042\n", + "0.0 1.0\n", + "0.0 1.0\n", + "-------------\n", + "0.0 0.0\n", + "0.0 0.0\n", + "0.0 0.0\n", + "-------------\n", + "0.0 0.0\n", + "0.0 0.0\n", + "0.0 0.0\n", + "-------------\n", + "0.0 0.0\n", + "0.0 0.0\n", + "0.0 0.0\n", + "-------------\n", + "0.00023223409196470042 0.00023223409196470042\n", + "0.0 1.0\n", + "0.0 1.0\n", + "-------------\n", + "0.0 0.0\n", + "0.0 0.0\n", + "0.0 0.0\n", + "-------------\n", + "0.00011611704598235021 0.00011611704598235021\n", + "0.0 1.0\n", + "0.0 1.0\n", + "-------------\n", + "0.00011611704598235021 0.00011611704598235021\n", + "0.0 1.0\n", + "0.0 1.0\n", + "-------------\n", + "0.0 0.0\n", + "0.0 0.0\n", + "0.0 0.0\n", + "-------------\n", + "0.0 0.0\n", + "0.0 0.0\n", + "0.0 0.0\n", + "-------------\n", + "0.0013934045517882026 0.0013934045517882026\n", + "0.0 1.0\n", + "0.0 1.0\n", + "-------------\n", + "0.0013934045517882026 0.0013934045517882026\n", + "0.0 1.0\n", + "0.0 1.0\n", + "-------------\n", + "0.0006967022758941013 0.0006967022758941013\n", + "0.0 1.0\n", + "0.0 1.0\n", + "-------------\n", + "0.0 0.0\n", + "0.0 0.0\n", + "0.0 0.0\n", + "-------------\n", + "0.0024384579656293545 0.0024384579656293545\n", + "0.0 1.0\n", + "0.0 1.0\n", + "-------------\n", + "0.002206223873664654 0.002206223873664654\n", + "0.0 1.0\n", + "0.0 1.0\n", + "-------------\n", + "0.0 0.0\n", + "0.0 0.0\n", + "0.0 0.0\n", + "-------------\n", + "0.0 0.0\n", + "0.0 0.0\n", + "0.0 0.0\n", + "-------------\n" + ] + } + ], + "source": [ + "for feature in range(0, 25):\n", + " print(f'{t_1_test[:, feature].mean()} {t_1_test_scaled[:, feature].mean()}')\n", + " print(f'{t_1_test[:, feature].min()} {t_1_test[:, feature].max()}')\n", + " print(f'{t_1_test_scaled[:, feature].min()} {t_1_test_scaled[:, feature].max()}')\n", + " print('-------------')\n", + " " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "py3.9test", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "27efe6010b91a164a18a011cd71b7afbe2f076e5b83b7f8099f414d97e11e710" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/subject1-4/AdaDiff/data/preprocess_smd.ipynb b/subject1-4/AdaDiff/data/preprocess_smd.ipynb new file mode 100644 index 0000000..0126dc7 --- /dev/null +++ b/subject1-4/AdaDiff/data/preprocess_smd.ipynb @@ -0,0 +1,263 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'/root/Diff-Anomaly/TranAD/data'" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%pwd" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "smd_dir = '../processed/SMD/'" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import os" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "84\n", + "(28479, 38)\n", + "normalized: machine-1-1_test.npy 0.0 - 1.0\n", + "(23703, 38)\n", + "normalized: machine-3-2_labels.npy 0.0 - 1.0\n", + "(28743, 38)\n", + "normalized: machine-2-6_train.npy 0.0 - 1.0\n", + "(23693, 38)\n", + "normalized: machine-3-10_test.npy 0.0 - 1.0\n", + "(23700, 38)\n", + "normalized: machine-2-2_labels.npy 0.0 - 1.0\n", + "(23689, 38)\n", + "normalized: machine-1-6_labels.npy 0.0 - 1.0\n", + "(23694, 38)\n", + "normalized: machine-1-2_test.npy 0.0 - 1.0\n", + "(23696, 38)\n", + "normalized: machine-2-7_test.npy 0.0 - 1.0\n", + "(28479, 38)\n", + "normalized: machine-1-1_train.npy 0.0 - 1.0\n", + "(23702, 38)\n", + "normalized: machine-1-3_train.npy 0.0 - 1.0\n", + "(28696, 38)\n", + "normalized: machine-3-11_test.npy 0.0 - 1.0\n", + "(28700, 38)\n", + "normalized: machine-3-1_labels.npy 0.0 - 1.0\n", + "(28705, 38)\n", + "normalized: machine-3-7_test.npy 0.0 - 1.0\n", + "(28713, 38)\n", + "normalized: machine-3-9_test.npy 0.0 - 1.0\n", + "(28695, 38)\n", + "normalized: machine-3-11_train.npy 0.0 - 1.0\n", + "(23688, 38)\n", + "normalized: machine-2-3_train.npy 0.0 - 1.0\n", + "(23689, 38)\n", + "normalized: machine-2-4_labels.npy 0.0 - 1.0\n", + "(23699, 38)\n", + "normalized: machine-1-8_test.npy 0.0 - 1.0\n", + "(23694, 38)\n", + "normalized: machine-2-1_labels.npy 0.0 - 1.0\n", + "(23706, 38)\n", + "normalized: machine-1-4_train.npy 0.0 - 1.0\n", + "(23702, 38)\n", + "normalized: machine-3-2_train.npy 0.0 - 1.0\n", + "(23694, 38)\n", + "normalized: machine-1-2_train.npy 0.0 - 1.0\n", + "(28705, 38)\n", + "normalized: machine-3-7_train.npy 0.0 - 1.0\n", + "(23703, 38)\n", + "normalized: machine-3-3_test.npy 0.0 - 1.0\n", + "(23707, 38)\n", + "normalized: machine-1-4_labels.npy 0.0 - 1.0\n", + "(28743, 38)\n", + "normalized: machine-2-6_test.npy 0.0 - 1.0\n", + "(28479, 38)\n", + "normalized: machine-1-1_labels.npy 0.0 - 1.0\n", + "(23699, 38)\n", + "normalized: machine-2-2_train.npy 0.0 - 1.0\n", + "(28704, 38)\n", + "normalized: machine-3-8_test.npy 0.0 - 1.0\n", + "(23689, 38)\n", + "normalized: machine-1-6_test.npy 0.0 - 1.0\n", + "(23698, 38)\n", + "normalized: machine-1-8_train.npy 0.0 - 1.0\n", + "(28722, 38)\n", + "normalized: machine-2-9_labels.npy 0.0 - 1.0\n", + "(23699, 38)\n", + "normalized: machine-1-8_labels.npy 0.0 - 1.0\n", + "(23706, 38)\n", + "normalized: machine-1-5_labels.npy 0.0 - 1.0\n", + "(23687, 38)\n", + "normalized: machine-3-4_train.npy 0.0 - 1.0\n", + "(23689, 38)\n", + "normalized: machine-2-5_labels.npy 0.0 - 1.0\n", + "(28726, 38)\n", + "normalized: machine-3-6_labels.npy 0.0 - 1.0\n", + "(23693, 38)\n", + "normalized: machine-3-10_labels.npy 0.0 - 1.0\n", + "(23697, 38)\n", + "normalized: machine-1-7_train.npy 0.0 - 1.0\n", + "(23690, 38)\n", + "normalized: machine-3-5_train.npy 0.0 - 1.0\n", + "(23694, 38)\n", + "normalized: machine-2-1_test.npy 0.0 - 1.0\n", + "(23703, 38)\n", + "normalized: machine-2-8_test.npy 0.0 - 1.0\n", + "(23689, 38)\n", + "normalized: machine-2-3_labels.npy 0.0 - 1.0\n", + "(23689, 38)\n", + "normalized: machine-2-3_test.npy 0.0 - 1.0\n", + "(23691, 38)\n", + "normalized: machine-3-5_labels.npy 0.0 - 1.0\n", + "(23689, 38)\n", + "normalized: machine-2-5_test.npy 0.0 - 1.0\n", + "(23687, 38)\n", + "normalized: machine-3-4_labels.npy 0.0 - 1.0\n", + "(23703, 38)\n", + "normalized: machine-2-8_labels.npy 0.0 - 1.0\n", + "(23706, 38)\n", + "normalized: machine-1-5_test.npy 0.0 - 1.0\n", + "(23692, 38)\n", + "normalized: machine-3-10_train.npy 0.0 - 1.0\n", + "(23697, 38)\n", + "normalized: machine-1-7_labels.npy 0.0 - 1.0\n", + "(28704, 38)\n", + "normalized: machine-3-8_labels.npy 0.0 - 1.0\n", + "(23700, 38)\n", + "normalized: machine-2-2_test.npy 0.0 - 1.0\n", + "(28700, 38)\n", + "normalized: machine-3-1_test.npy 0.0 - 1.0\n", + "(28705, 38)\n", + "normalized: machine-3-7_labels.npy 0.0 - 1.0\n", + "(28722, 38)\n", + "normalized: machine-2-9_test.npy 0.0 - 1.0\n", + "(28726, 38)\n", + "normalized: machine-3-6_train.npy 0.0 - 1.0\n", + "(23688, 38)\n", + "normalized: machine-1-6_train.npy 0.0 - 1.0\n", + "(23696, 38)\n", + "normalized: machine-2-7_labels.npy 0.0 - 1.0\n", + "(23703, 38)\n", + "normalized: machine-3-3_labels.npy 0.0 - 1.0\n", + "(23689, 38)\n", + "normalized: machine-2-4_train.npy 0.0 - 1.0\n", + "(23694, 38)\n", + "normalized: machine-1-2_labels.npy 0.0 - 1.0\n", + "(23705, 38)\n", + "normalized: machine-1-5_train.npy 0.0 - 1.0\n", + "(23689, 38)\n", + "normalized: machine-2-4_test.npy 0.0 - 1.0\n", + "(23703, 38)\n", + "normalized: machine-1-3_test.npy 0.0 - 1.0\n", + "(23687, 38)\n", + "normalized: machine-3-4_test.npy 0.0 - 1.0\n", + "(23693, 38)\n", + "normalized: machine-2-1_train.npy 0.0 - 1.0\n", + "(23707, 38)\n", + "normalized: machine-1-4_test.npy 0.0 - 1.0\n", + "(28713, 38)\n", + "normalized: machine-3-9_train.npy 0.0 - 1.0\n", + "(23696, 38)\n", + "normalized: machine-2-7_train.npy 0.0 - 1.0\n", + "(23703, 38)\n", + "normalized: machine-3-2_test.npy 0.0 - 1.0\n", + "(23691, 38)\n", + "normalized: machine-3-5_test.npy 0.0 - 1.0\n", + "(28703, 38)\n", + "normalized: machine-3-8_train.npy 0.0 - 1.0\n", + "(28713, 38)\n", + "normalized: machine-3-9_labels.npy 0.0 - 1.0\n", + "(23702, 38)\n", + "normalized: machine-2-8_train.npy 0.0 - 1.0\n", + "(28726, 38)\n", + "normalized: machine-3-6_test.npy 0.0 - 1.0\n", + "(23697, 38)\n", + "normalized: machine-1-7_test.npy 0.0 - 1.0\n", + "(28700, 38)\n", + "normalized: machine-3-1_train.npy 0.0 - 1.0\n", + "(23703, 38)\n", + "normalized: machine-1-3_labels.npy 0.0 - 1.0\n", + "(28722, 38)\n", + "normalized: machine-2-9_train.npy 0.0 - 1.0\n", + "(28696, 38)\n", + "normalized: machine-3-11_labels.npy 0.0 - 1.0\n", + "(23688, 38)\n", + "normalized: machine-2-5_train.npy 0.0 - 1.0\n", + "(23703, 38)\n", + "normalized: machine-3-3_train.npy 0.0 - 1.0\n", + "(28743, 38)\n", + "normalized: machine-2-6_labels.npy 0.0 - 1.0\n" + ] + } + ], + "source": [ + "files = os.listdir(smd_dir)\n", + "print(len(files))\n", + "for file in files:\n", + " sample = np.load(smd_dir + file)\n", + " max = sample.max()\n", + " min = sample.min()\n", + " print(sample.shape)\n", + " if min == 0 and max == 1:\n", + " print(f'normalized: {file} {min} - {max}')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "py3.9test", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "27efe6010b91a164a18a011cd71b7afbe2f076e5b83b7f8099f414d97e11e710" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/subject1-4/AdaDiff/data/preprocess_synthetic.ipynb b/subject1-4/AdaDiff/data/preprocess_synthetic.ipynb new file mode 100644 index 0000000..a079c75 --- /dev/null +++ b/subject1-4/AdaDiff/data/preprocess_synthetic.ipynb @@ -0,0 +1,850 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 147, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd" + ] + }, + { + "cell_type": "code", + "execution_count": 148, + "metadata": {}, + "outputs": [], + "source": [ + "DATASET = 'pattern_trend10'\n", + "ORIG = 'trend'\n", + "FILE = 'trend10'" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": {}, + "outputs": [], + "source": [ + "def abs_normalize(a):\n", + " a = a / np.maximum(np.absolute(a.max(axis=0)), np.absolute(a.min(axis=0)))\n", + " a = np.nan_to_num(a)\n", + " return (a / 2 + 0.5)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/root/.conda/envs/py3.9test/lib/python3.9/site-packages/scipy/__init__.py:138: UserWarning: A NumPy version >=1.16.5 and <1.23.0 is required for this version of SciPy (detected version 1.23.1)\n", + " warnings.warn(f\"A NumPy version >={np_minversion} and <{np_maxversion} is required for this version of \"\n" + ] + } + ], + "source": [ + "from sklearn.preprocessing import MinMaxScaler\n", + "\n", + "def scale_data(train, test, validation):\n", + " scaler = MinMaxScaler(feature_range=(0, 1), clip=True).fit(train)\n", + "\n", + " train_scaled = scaler.transform(train)\n", + " test_scaled = scaler.transform(test)\n", + " validation_scaled = scaler.transform(validation)\n", + "\n", + " return train_scaled, test_scaled, validation_scaled" + ] + }, + { + "cell_type": "code", + "execution_count": 149, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
col_0col_1col_2col_3col_4anomaly
0-0.1312322.6078500.0660114.381993-1.8944490
10.3987362.4039650.4427014.554839-1.5307900
20.8091082.1706900.7025473.998227-1.4148470
31.0078881.8746751.0067003.990737-0.9104900
41.3400911.3111061.3379473.413961-0.7203440
\n", + "
" + ], + "text/plain": [ + " col_0 col_1 col_2 col_3 col_4 anomaly\n", + "0 -0.131232 2.607850 0.066011 4.381993 -1.894449 0\n", + "1 0.398736 2.403965 0.442701 4.554839 -1.530790 0\n", + "2 0.809108 2.170690 0.702547 3.998227 -1.414847 0\n", + "3 1.007888 1.874675 1.006700 3.990737 -0.910490 0\n", + "4 1.340091 1.311106 1.337947 3.413961 -0.720344 0" + ] + }, + "execution_count": 149, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "time_series = pd.read_csv(f'{FILE}_train_test_val.csv')\n", + "time_series.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 150, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
col_0col_1col_2col_3col_4anomaly
0-0.1312322.6078500.0660114.381993-1.8944490
10.3987362.4039650.4427014.554839-1.5307900
20.8091082.1706900.7025473.998227-1.4148470
31.0078881.8746751.0067003.990737-0.9104900
41.3400911.3111061.3379473.413961-0.7203440
\n", + "
" + ], + "text/plain": [ + " col_0 col_1 col_2 col_3 col_4 anomaly\n", + "0 -0.131232 2.607850 0.066011 4.381993 -1.894449 0\n", + "1 0.398736 2.403965 0.442701 4.554839 -1.530790 0\n", + "2 0.809108 2.170690 0.702547 3.998227 -1.414847 0\n", + "3 1.007888 1.874675 1.006700 3.990737 -0.910490 0\n", + "4 1.340091 1.311106 1.337947 3.413961 -0.720344 0" + ] + }, + "execution_count": 150, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train_time_series = time_series[:20000]\n", + "train_time_series.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 152, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-15.097620609417833\n", + "85.04304598705383\n" + ] + } + ], + "source": [ + "print(train_time_series['col_4'].min())\n", + "print(train_time_series['col_4'].max())" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
col_0col_1col_2col_3col_4anomaly
200000.1134802.5419600.0024184.4137782.5139330
200010.4253302.3527050.4029864.3433632.8619540
200020.5934772.3853190.7958604.2505153.3436780
200030.9907081.6829741.0200783.9477633.4182430
200041.3283721.4523741.2582303.1268273.6719270
\n", + "
" + ], + "text/plain": [ + " col_0 col_1 col_2 col_3 col_4 anomaly\n", + "20000 0.113480 2.541960 0.002418 4.413778 2.513933 0\n", + "20001 0.425330 2.352705 0.402986 4.343363 2.861954 0\n", + "20002 0.593477 2.385319 0.795860 4.250515 3.343678 0\n", + "20003 0.990708 1.682974 1.020078 3.947763 3.418243 0\n", + "20004 1.328372 1.452374 1.258230 3.126827 3.671927 0" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test_time_series = time_series[20000:40000]\n", + "test_time_series.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
col_0col_1col_2col_3col_4anomaly
40000-0.0948022.6521710.0189394.550506-6.4912400
400010.3597502.2560460.3312344.466656-6.1598940
400020.8235032.1833440.8220094.316569-5.6821000
400031.0802651.8167901.0566593.858038-5.4638390
400041.2489271.3742571.2385673.136138-5.1982220
\n", + "
" + ], + "text/plain": [ + " col_0 col_1 col_2 col_3 col_4 anomaly\n", + "40000 -0.094802 2.652171 0.018939 4.550506 -6.491240 0\n", + "40001 0.359750 2.256046 0.331234 4.466656 -6.159894 0\n", + "40002 0.823503 2.183344 0.822009 4.316569 -5.682100 0\n", + "40003 1.080265 1.816790 1.056659 3.858038 -5.463839 0\n", + "40004 1.248927 1.374257 1.238567 3.136138 -5.198222 0" + ] + }, + "execution_count": 80, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "val_time_series = time_series[40000:]\n", + "val_time_series.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": {}, + "outputs": [], + "source": [ + "train_labels = train_time_series.anomaly.to_numpy()\n", + "test_labels = test_time_series.anomaly.to_numpy()\n", + "val_labels = val_time_series.anomaly.to_numpy()" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train (20000, 5)\n", + "Test: (20000, 5)\n", + "Val: (10000, 5)\n" + ] + } + ], + "source": [ + "train_no_labels = train_time_series.drop(['anomaly'], axis=1).to_numpy()\n", + "test_no_labels = test_time_series.drop(['anomaly'], axis=1).to_numpy()\n", + "val_no_labels = val_time_series.drop(['anomaly'], axis=1).to_numpy()\n", + "print('Train ', train_no_labels.shape)\n", + "print('Test: ', test_no_labels.shape)\n", + "print('Val: ', val_no_labels.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train ratio: 1.01\n", + "Val ratio: 0.8999999999999999\n" + ] + } + ], + "source": [ + "train_ratio = (train_labels.sum() / train_labels.shape[0]) * 100\n", + "val_ratio = (val_labels.sum() / val_labels.shape[0]) * 100\n", + "print('Train ratio: ', train_ratio)\n", + "print('Val ratio: ', val_ratio)" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "normalized dataset\n" + ] + } + ], + "source": [ + "if ORIG != 'pattern_trend': \n", + " train_normalized = abs_normalize(train_no_labels)\n", + " val_normalized = abs_normalize(val_no_labels)\n", + " test_normalized = abs_normalize(test_no_labels)\n", + " print('normalized dataset')" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [], + "source": [ + "def expand_labels(data, labels):\n", + " labels_reshaped = np.zeros_like(data)\n", + " for idx in range(0, len(labels)):\n", + " if labels[idx]:\n", + " labels_reshaped[idx][0:labels_reshaped.shape[1]] = 1\n", + " return labels_reshaped" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# val_labels_reshaped = expand_labels(val_normalized, val_labels)\n", + "# test_labels_reshaped = expand_labels(test_normalized, test_labels)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "# FOR RATIO ABLATION\n", + "#test5 = np.load(f'../processed/{ORIG}/test.npy')\n", + "#labels5 = np.load(f'../processed/{ORIG}/labels.npy')" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.preprocessing import MinMaxScaler\n", + "\n", + "def scale_test(test):\n", + " scaler = MinMaxScaler(feature_range=(0, 1)).fit(test)\n", + "\n", + " #train_scaled = scaler.transform(train)\n", + " test_scaled = scaler.transform(test)\n", + "\n", + " return test_scaled" + ] + }, + { + "cell_type": "code", + "execution_count": 153, + "metadata": {}, + "outputs": [], + "source": [ + "trend5_series = pd.read_csv('trend_train_test_val.csv')\n", + "test_trend5 = trend5_series[20000:40000]\n", + "#labels5 = test_trend5.anomaly.to_numpy()\n", + "#test_trend5 = test_trend5.drop(['anomaly'], axis=1).to_numpy()\n", + "#labels5 = expand_labels(test_trend5, labels5)" + ] + }, + { + "cell_type": "code", + "execution_count": 154, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-97.97744390787436\n", + "-1.0244058283630473\n" + ] + } + ], + "source": [ + "print(test_trend5['col_4'].min())\n", + "print(test_trend5['col_4'].max())" + ] + }, + { + "cell_type": "code", + "execution_count": 117, + "metadata": {}, + "outputs": [], + "source": [ + "#ratio = 1\n", + "#ds = f'pattern_trend{ratio}_test5'\n", + "#test5_normalized = scale_test(train_no_labels, test_trend5)\n", + "test5_normalized = scale_test(test_trend5)\n", + "#np.save(f'../processed/{ds}/test.npy', normalized_test_for_ds)\n", + "#np.save(f'../processed/{ds}/labels.npy', labels_5_expanded)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "normalized trend\n" + ] + } + ], + "source": [ + "# if ORIG == 'pattern_trend':\n", + "# train_normalized, test5_normalized, val_normalized = scale_data(train_no_labels, test5, val_no_labels)\n", + "# print('normalized trend')" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": {}, + "outputs": [], + "source": [ + "val_labels_reshaped = expand_labels(val_normalized, val_labels)\n", + "#test_labels_reshaped = expand_labels(test_normalized, test_labels)" + ] + }, + { + "cell_type": "code", + "execution_count": 118, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "saved trend\n" + ] + } + ], + "source": [ + "import os \n", + "os.makedirs(f'../processed/{DATASET}_test5', exist_ok=True)\n", + "# np.save(f'../processed/{DATASET}_test5/train.npy', train_normalized)\n", + "if ORIG != 'pattern_trend' and ORIG != 'trend':\n", + " np.save(f'../processed/{DATASET}_test5/test.npy', test5)\n", + " print('saved NOT trend')\n", + "else:\n", + " np.save(f'../processed/{DATASET}_test5/test.npy', test5_normalized)\n", + " print('saved trend')\n", + "np.save(f'../processed/{DATASET}_test5/labels.npy', labels5)\n", + "# np.save(f'../processed/{DATASET}_test5/validation.npy', val_normalized)\n", + "# np.save(f'../processed/{DATASET}_test5/labels_validation.npy', val_labels_reshaped)" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(20000, 5)" + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "labels_5_reshaped.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 145, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "train = np.load('../processed/pattern_trend15_test5/train.npy')" + ] + }, + { + "cell_type": "code", + "execution_count": 144, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 144, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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N4y+PADAH/7wh7Dy9+rVK7C/trYWM2bMQNu2bdG6dWtcd911KC0tDcqD5evLzc0Nuz6Xy4UZM2YAsN/zW7t2La644gpkZ2fD5XJh6dKlQfs5jsPcuXORlZWF+Ph4FBYWYvfu3UFpTp8+jalTpyIpKQkpKSm45ZZbcPbs2aA0P/zwA0aOHIm4uDjk5OTgySefDCvLe++9h169eiEuLg79+vXD8uXLDb/GhoYGzJ49G/369UOrVq2QnZ2NadOm4ejRo0F5CD33BQsWMHGNkZ7hb37zm7CyT5gwISgNy88w0vUJvY8ulwtPPfVUIA3Lz09Ov2Bmu6lLX8pFKe+++y7n9Xq5xYsXcz/99BN32223cSkpKVxpaanVRQti/Pjx3Ouvv85t27aN27JlC3fZZZdxHTt25M6ePRtIM3r0aO62227jjh07FvhXXl4e2N/Y2Mj17duXKyws5DZv3swtX76cS0tL4+bMmRNIs2/fPi4hIYGbNWsW9/PPP3N/+9vfOI/Hw61YscLwa5w3bx7Xp0+foPKfOHEisP/OO+/kcnJyuFWrVnHff/89N2zYMG748OG2ub7jx48HXdvKlSs5ANwXX3zBcZz9nt/y5cu5hx9+mPvggw84ANyHH34YtH/BggVccnIyt3TpUm7r1q3clVdeyXXu3JmrqakJpJkwYQKXl5fHffvtt9y6deu4bt26cVOmTAnsLy8v5zIyMripU6dy27Zt49555x0uPj6ee+mllwJpvv76a87j8XBPPvkk9/PPP3OPPPIIFxsby/3444+GXmNZWRlXWFjILVmyhNuxYwdXVFTEDR06lBs8eHBQHp06deIef/zxoOfKf2+tvMZIz/Cmm27iJkyYEFT206dPB6Vh+RlGuj7+dR07doxbvHgx53K5uL179wbSsPz85PQLZrWbevWlUStGhg4dys2YMSPwu6mpicvOzubmz59vYakic/z4cQ4A9+WXXwa2jR49mrv33ntFj1m+fDnndru5kpKSwLYXXniBS0pK4urq6jiO47gHHniA69OnT9BxkydP5saPH6/vBQgwb948Li8vT3BfWVkZFxsby7333nuBbdu3b+cAcEVFRRzHsX99odx7771c165duebmZo7j7P38Qhv65uZmLjMzk3vqqacC28rKyjifz8e98847HMdx3M8//8wB4L777rtAmk8//ZRzuVzckSNH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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "plt.plot(train[:, 4])" + ] + }, + { + "cell_type": "code", + "execution_count": 146, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 146, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGdCAYAAADAAnMpAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAABz0UlEQVR4nO3dd3wUdf4/8NduyiaBkACBhBIIHREITTAgIBopctgV0RNFxYoNTwELWH4KdyrnfT2Us6DeWbCc5e5AVBBEBaUjSJEeWhJaGiF9fn/ALrO7M7NTd2Y3r+fj4R3ZnZ35zO6U93zK++MSBEEAERERkU3cdheAiIiI6jcGI0RERGQrBiNERERkKwYjREREZCsGI0RERGQrBiNERERkKwYjREREZCsGI0RERGSrWLsLoEZdXR0OHTqE5ORkuFwuu4tDREREKgiCgNLSUrRs2RJut3z9R0QEI4cOHUJmZqbdxSAiIiId9u/fj9atW8u+HxHBSHJyMoDTO9OoUSObS0NERERqlJSUIDMz03cflxMRwYi3aaZRo0YMRoiIiCJMqC4W7MBKREREtmIwQkRERLZiMEJERES2YjBCREREtmIwQkRERLZiMEJERES2YjBCREREtmIwQkRERLZiMEJERES20hyMLF++HGPGjEHLli3hcrnwxRdfhPzMsmXL0KdPH3g8HnTs2BHvvPOOjqISERFRNNIcjJw8eRLZ2dmYM2eOquX37NmD0aNHY9iwYdiwYQMefPBB3H777fj66681F5aIiIiij+a5aUaNGoVRo0apXn7u3Llo164dXnrpJQDAOeecgx9//BF//etfMWLECK2bJyIioihj+UR5K1euRG5urt9rI0aMwIMPPij7mcrKSlRWVvr+Likpsap4RGFXVyfgrR/34HBxBYrKq3BBpzRc1Ud+am0iomhneTCSn5+P9PR0v9fS09NRUlKCU6dOITExMegzM2fOxNNPP2110YhssWRbIZ5buNX392frD+K8rCbIbJJkY6mIiOzjyNE006ZNQ3Fxse+//fv3210kItNszw+u6TtaVimxJBFR/WB5zUhGRgYKCgr8XisoKECjRo0ka0UAwOPxwOPxWF00IlsIQvBrcTGOfC4gIgoLy6+AOTk5WLJkid9r3377LXJycqzeNJEjud2uoNdiJF4jIqovNAcjZWVl2LBhAzZs2ADg9NDd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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "plt.plot(train[:, 4])" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [], + "source": [ + "np.save(f'../processed/{DATASET}_test5/labels.npy', labels5)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "py3.9test", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/subject1-4/AdaDiff/data/split_val_swat.ipynb b/subject1-4/AdaDiff/data/split_val_swat.ipynb new file mode 100644 index 0000000..13168f5 --- /dev/null +++ b/subject1-4/AdaDiff/data/split_val_swat.ipynb @@ -0,0 +1,1863 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#normal0 = pd.read_excel('SWaT_Dataset_Normal_v0.xlsx')\n", + "normal1 = pd.read_excel('SWaT_Dataset_Normal_v1.xlsx')\n", + "attack = pd.read_excel('SWaT_Dataset_Attack_v0.xlsx')" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "#if not os.path.isfile(directory + 'train.csv'):\n", + "#normal0.to_csv('train.csv', index=None, header=None)\n", + "normal1.to_csv('train1.csv', index=None, header=None)\n", + "attack.to_csv('test.csv', index=None, header=None)" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": {}, + "outputs": [], + "source": [ + "test = pd.read_csv('test.csv')\n", + "train1 = pd.read_csv('train1.csv')\n", + "#train = pd.read_csv('train.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(496800, 53)" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(495000, 53)" + ] + }, + "execution_count": 80, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train1.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(449919, 53)" + ] + }, + "execution_count": 81, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [], + "source": [ + "train1['Normal/Attack'] = [0 if x == 'Normal' else 1 for x in train1['Normal/Attack']]\n", + "test['Normal/Attack'] = [0 if x == 'Normal' else 1 for x in test['Normal/Attack']]" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 395298\n", + "1 54621\n", + "Name: Normal/Attack, dtype: int64" + ] + }, + "execution_count": 83, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test['Normal/Attack'].value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 495000\n", + "Name: Normal/Attack, dtype: int64" + ] + }, + "execution_count": 84, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train1['Normal/Attack'].value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [], + "source": [ + "# trim column names\n", + "train1 = train1.rename(columns=lambda x: x.strip())\n", + "test = test.rename(columns=lambda x: x.strip())" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 0\n", + "1 0\n", + "2 0\n", + "3 0\n", + "4 0\n", + " ..\n", + "449914 0\n", + "449915 0\n", + "449916 0\n", + "449917 0\n", + "449918 0\n", + "Name: Normal/Attack, Length: 449919, dtype: int64" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test_labels = test['Normal/Attack']\n", + "test_labels" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": {}, + "outputs": [], + "source": [ + "def search_ratio(test_labels, val_len):\n", + " test = test_labels[val_len:]\n", + " val = test_labels[:val_len]\n", + " test_ratio = (np.sum(test) /test.shape[0]) * 100\n", + " val_ratio = (np.sum(val) / val.shape[0]) * 100\n", + " print(f'val ratio: {val_ratio}')\n", + " print(f'test ratio: {test_ratio}')\n", + " print('----')\n", + " return val_ratio, test_ratio" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "val ratio: 5.764422168631852\n", + "test ratio: 13.734108285917495\n", + "----\n", + "val ratio: 9.926429730390522\n", + "test ratio: 12.386152599968389\n", + "----\n", + "val ratio: 6.432302278199667\n", + "test ratio: 14.586402662060557\n", + "----\n" + ] + } + ], + "source": [ + "vr, tr = search_ratio(test_labels=test_labels.to_numpy(), val_len=int(0.2 * test.shape[0]))\n", + "vr, tr = search_ratio(test_labels=test_labels.to_numpy(), val_len=int(0.1 * test.shape[0]))\n", + "vr, tr = search_ratio(test_labels=test_labels.to_numpy(), val_len=int(0.3 * test.shape[0]))" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "44991" + ] + }, + "execution_count": 89, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "val_len = int(0.1 * test.shape[0])\n", + "val_len" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(44991, 53)" + ] + }, + "execution_count": 90, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "validation = test[:val_len]\n", + "validation.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 40525\n", + "1 4466\n", + "Name: Normal/Attack, dtype: int64" + ] + }, + "execution_count": 91, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "validation['Normal/Attack'].value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 0\n", + "1 0\n", + "2 0\n", + "3 0\n", + "4 0\n", + " ..\n", + "44986 0\n", + "44987 0\n", + "44988 0\n", + "44989 0\n", + "44990 0\n", + "Name: Normal/Attack, Length: 44991, dtype: int64" + ] + }, + "execution_count": 92, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "validation_labels = validation['Normal/Attack']\n", + "validation_labels" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(404928, 53)" + ] + }, + "execution_count": 93, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test_clipped = test[val_len:]\n", + "test_clipped.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(404928,)" + ] + }, + "execution_count": 94, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test_labels_clipped = test_labels[val_len:]\n", + "test_labels_clipped.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 95, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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JwBQHtx+++10+umnU0NDAzU0NNCyZcvo4Ycfzp7HHAGA0UVcn4A5AgCjmy996UuUyWTo+uuvzx7DXAGMOB4AjvzsZz/zampqvDvuuMNbu3at9+EPf9hramry2tvbC501AEAe3HLLLd4pp5zi7d27N/vvwIED2fMf+chHvJkzZ3qPPfaYt3LlSu+8887zzj///Oz5gYEB79RTT/UuueQS7+WXX/Yeeughb9KkSd7NN9+c/c3WrVu9sWPHejfccIO3bt0677//+7+9yspK73e/+132N+hTACgMDz30kPeZz3zGu++++zwi8u6///7A+S996UteY2Oj98ADD3ivvPKK9+d//ufe3LlzvWPHjmV/c9lll3lLly71nn32We9Pf/qTt2DBAu9973tf9nx3d7fX0tLivf/97/fWrFnj3X333d6YMWO87373u9nfPPPMM15lZaX35S9/2Vu3bp332c9+1quurvZWr16dV14AAG7E9QnXXnutd9lllwXmDYcOHQr8Bn0CAOXBpZde6v3v//6vt2bNGm/VqlXeFVdc4c2aNcs7fPhw9jfFtFaIywsAwI1c+oSLLrrI+/CHPxyYJ3R3d2fPo08AoHz49a9/7T344IPexo0bvQ0bNnif/vSnverqam/NmjWe52GOAMBoI65PwBwBgNHL888/782ZM8c7/fTTvY9//OPZ45grgJEGBlLAmXPOOce77rrrst8HBwe9adOmebfddlsBcwUAyJdbbrnFW7p0qfFcV1eXV11d7f3iF7/IHnvttdc8IvJWrFjheZ54kVpRUeHt27cv+5vbb7/da2ho8Pr6+jzP87wbb7zRO+WUUwKy3/Oe93iXXnpp9jv6FAAKj24MMTQ05LW2tnr/8R//kT3W1dXl1dbWenfffbfneZ63bt06j4i8F154Ifubhx9+2MtkMt7u3bs9z/O8b3/7215zc3O2T/A8z7vpppu8xYsXZ7+/+93v9q688spAfs4991zv7//+73POCwCAF5uB1Nvf/nbrNegTAChf9u/f7xGR9+STT3qeV1xrhVzyAgDgRe8TPE+8/FRfeuigTwCgvGlubvZ+8IMfYI4AAPA8z+8TPA9zBABGK729vd7ChQu9Rx99NNAPYK4ACgG22ANOnDhxgl588UW65JJLsscqKirokksuoRUrVhQwZwCAJGzatImmTZtG8+bNo/e///3U1tZGREQvvvgi9ff3B9r6kiVLaNasWdm2vmLFCjrttNOopaUl+5tLL72Uenp6aO3atdnfqDLkb6QM9CkAFCfbtm2jffv2BdpmY2MjnXvuuYE+oKmpiV73utdlf3PJJZdQRUUFPffcc9nfvOENb6Camprsby699FLasGEDdXZ2Zn8T1U/kkhcAwMjwxBNP0JQpU2jx4sX00Y9+lDo6OrLn0CcAUL50d3cTEdGECROIqLjWCrnkBQDAi94nSH7605/SpEmT6NRTT6Wbb76Zjh49mj2HPgGA8mRwcJB+9rOf0ZEjR2jZsmWYIwAwytH7BAnmCACMPq677jq68sorQ20XcwVQCKoKnQFQ2hw8eJAGBwcDnRIRUUtLC61fv75AuQIAJOHcc8+lO++8kxYvXkx79+6lW2+9lS688EJas2YN7du3j2pqaqipqSlwTUtLC+3bt4+IiPbt22fsC+S5qN/09PTQsWPHqLOzE30KAEWIbMOmtqm27ylTpgTOV1VV0YQJEwK/mTt3bkiGPNfc3GztJ1QZcXkBAKTPZZddRu94xzto7ty5tGXLFvr0pz9Nl19+Oa1YsYIqKyvRJwBQpgwNDdH1119PF1xwAZ166qlEREW1VsglLwAAPkx9AhHRX/7lX9Ls2bNp2rRp9Oqrr9JNN91EGzZsoPvuu4+I0CcAUG6sXr2ali1bRsePH6fx48fT/fffTyeffDKtWrUKcwQARiG2PoEIcwQARiM/+9nP6KWXXqIXXnghdA76BFAIYCAFAACAiIguv/zy7N+nn346nXvuuTR79mz6+c9/TmPGjClgzgAAAABQbLz3ve/N/n3aaafR6aefTvPnz6cnnniC3vzmNxcwZwCANLnuuutozZo19PTTTxc6KwCAIsDWJ/z/9u4mJKq+jeP41eM4kxKmMeIMhqL5Ar1QaRQDYYsJqVW0EomQgqRCcGGCLSJok4sIKlq0qqVEEEKBZL5FUoLipJEIY1MWmIKhGVop87tXneceNPV+7Faf6fuBA+M5f/9cm/PjOnoxp7Ky0vm8a9cu8/v9FgwGbWhoyLZt27baZQL4lxUWFlooFLLJyUl78OCBVVRUWEdHx1qXBWCN/CoTtm/fTo8A/GE+fPhg1dXV1tzcbBs3blzrcgAzM+MVe1gRr9drCQkJNjo6GnN+dHTUfD7fGlUF4HdITU21goICC4fD5vP57MePHzYxMRGz5u/3us/nWzALfl5bbE1KSoolJSWRKcA69fP+W+ze9Pl8NjY2FnN9bm7OPn/+/Fty4u/Xl6oFwOrLzc01r9dr4XDYzMgEIB5VVVXZo0ePrK2tzbZu3eqcX0/PCsupBcDv8atMWMiBAwfMzGL6BDIBiB9ut9vy8vKsuLjYrl69art377YbN27QIwB/qF9lwkLoEYD41tPTY2NjY1ZUVGQul8tcLpd1dHTYzZs3zeVyWUZGBr0CVh0DUlgRt9ttxcXF1tLS4pyLRqPW0tIS805hAP9/vn79akNDQ+b3+624uNgSExNj7vXBwUEbHh527vVAIGD9/f0x/wxtbm62lJQU5yt0A4FAzB4/1/zcg0wB1qecnBzz+Xwx9+aXL1+sq6srJgMmJiasp6fHWdPa2mrRaNT5Y0cgELBnz57Z7Oyss6a5udkKCwstLS3NWbNYTiynFgCr7+PHjzY+Pm5+v9/MyAQgnkiyqqoqe/jwobW2ts57NeZ6elZYTi0AVmapTFhIKBQyM4vpE8gEIH5Fo1H7/v07PQIAM/tvJiyEHgGIb8Fg0Pr7+y0UCjnHvn377MSJE85negWsOgEr1NDQII/Ho3v37unNmzeqrKxUamqqPn36tNalAfgHampq1N7erkgkos7OTh0+fFher1djY2OSpLNnzyorK0utra3q7u5WIBBQIBBwfn9ubk47d+5UaWmpQqGQmpqalJ6erosXLzpr3r59q+TkZNXW1mpgYEC3b99WQkKCmpqanDVkCrA2pqam1Nvbq97eXpmZrl+/rt7eXr1//16SVF9fr9TUVDU2Nqqvr0/Hjh1TTk6OZmZmnD2OHDmivXv3qqurS8+fP1d+fr7Ky8ud6xMTE8rIyNDJkyf1+vVrNTQ0KDk5WXfu3HHWdHZ2yuVy6dq1axoYGNDly5eVmJio/v5+Z81yagGwMotlwtTUlC5cuKAXL14oEono6dOnKioqUn5+vr59++bsQSYA8eHcuXPavHmz2tvbNTIy4hzT09POmvX0rLBULQBWZqlMCIfDunLlirq7uxWJRNTY2Kjc3FyVlJQ4e5AJQPyoq6tTR0eHIpGI+vr6VFdXpw0bNujJkyeS6BGAP81imUCPAECSDh06pOrqaudnegWsNgak8FvcunVLWVlZcrvd2r9/v16+fLnWJQH4h8rKyuT3++V2u5WZmamysjKFw2Hn+szMjM6fP6+0tDQlJyfr+PHjGhkZidnj3bt3Onr0qJKSkuT1elVTU6PZ2dmYNW1tbdqzZ4/cbrdyc3N19+7debWQKcDqa2trk5nNOyoqKiRJ0WhUly5dUkZGhjwej4LBoAYHB2P2GB8fV3l5uTZt2qSUlBSdOnVKU1NTMWtevXqlgwcPyuPxKDMzU/X19fNquX//vgoKCuR2u7Vjxw49fvw45vpyagGwMotlwvT0tEpLS5Wenq7ExERlZ2frzJkz84aZyQQgPiyUBWYW08evp2eF5dQC4H+3VCYMDw+rpKREW7ZskcfjUV5enmprazU5ORmzD5kAxIfTp08rOztbbrdb6enpCgaDznCURI8A/GkWywR6BADS/AEpegWstg2StHrfVwUAAAAAAAAAAAAAAAAAq+c/a10AAAAAAAAAAAAAAAAAAPxbGJACAAAAAAAAAAAAAAAAELcYkAIAAAAAAAAAAAAAAAAQtxiQAgAAAAAAAAAAAAAAABC3GJACAAAAAAAAAAAAAAAAELcYkAIAAAAAAAAAAAAAAAAQtxiQAgAAAAAAAAAAAAAAABC3GJACAAAAAAAAAAAAAAAAELcYkAIAAAAAAAAAAAAAAAAQtxiQAgAAAAAAAAAAAAAAABC3GJACAAAAAAAAAAAAAAAAELf+ApaIy4GpVbnEAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.rcParams['figure.figsize'] = 30, 2\n", + "plt.plot(test_clipped.to_numpy()[:, 4])\n", + "plt.fill_between(np.arange(test_labels_clipped.to_numpy().shape[0]), test_labels_clipped.to_numpy(), color='red', alpha=0.7, linestyle='dashed', linewidth=0.3)" + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 96, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(validation.to_numpy()[:, 4])\n", + "plt.fill_between(np.arange(validation_labels.to_numpy().shape[0]), validation_labels.to_numpy(), color='red', alpha=0.7, linestyle='dashed', linewidth=0.3)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(train_values[:, 4])" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": {}, + "outputs": [], + "source": [ + "# we don't need timestamps or training labels\n", + "train_dropped = train1.drop([\"Timestamp\" , \"Normal/Attack\" ] , axis = 1)\n", + "test_dropped = test_clipped.drop([\"Timestamp\" , \"Normal/Attack\" ] , axis = 1)\n", + "validation_dropped = validation.drop([\"Timestamp\" , \"Normal/Attack\" ] , axis = 1)" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
FIT101LIT101MV101P101P102AIT201AIT202AIT203FIT201MV201...FIT504P501P502PIT501PIT502PIT503FIT601P601P602P603
00.0124.3135111251.92268.313446312.79160.01...0.0119.1002310.03.34850.000256111
10.0124.3920111251.92268.313446312.79160.01...0.0119.1002310.03.34850.000256111
20.0124.4705111251.92268.313446312.79160.01...0.0119.1002310.03.34850.000256111
30.0124.6668111251.92268.313446312.79160.01...0.0119.1002310.03.34850.000256111
40.0124.5098111251.92268.313446312.79160.01...0.0119.1002310.03.34850.000256111
\n", + "

5 rows × 51 columns

\n", + "
" + ], + "text/plain": [ + " FIT101 LIT101 MV101 P101 P102 AIT201 AIT202 AIT203 FIT201 \\\n", + "0 0.0 124.3135 1 1 1 251.9226 8.313446 312.7916 0.0 \n", + "1 0.0 124.3920 1 1 1 251.9226 8.313446 312.7916 0.0 \n", + "2 0.0 124.4705 1 1 1 251.9226 8.313446 312.7916 0.0 \n", + "3 0.0 124.6668 1 1 1 251.9226 8.313446 312.7916 0.0 \n", + "4 0.0 124.5098 1 1 1 251.9226 8.313446 312.7916 0.0 \n", + "\n", + " MV201 ... FIT504 P501 P502 PIT501 PIT502 PIT503 FIT601 P601 \\\n", + "0 1 ... 0.0 1 1 9.100231 0.0 3.3485 0.000256 1 \n", + "1 1 ... 0.0 1 1 9.100231 0.0 3.3485 0.000256 1 \n", + "2 1 ... 0.0 1 1 9.100231 0.0 3.3485 0.000256 1 \n", + "3 1 ... 0.0 1 1 9.100231 0.0 3.3485 0.000256 1 \n", + "4 1 ... 0.0 1 1 9.100231 0.0 3.3485 0.000256 1 \n", + "\n", + " P602 P603 \n", + "0 1 1 \n", + "1 1 1 \n", + "2 1 1 \n", + "3 1 1 \n", + "4 1 1 \n", + "\n", + "[5 rows x 51 columns]" + ] + }, + "execution_count": 98, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train_dropped.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
FIT101LIT101MV101P101P102AIT201AIT202AIT203FIT201MV201...FIT504P501P502PIT501PIT502PIT503FIT601P601P602P603
449912.665983533.0524211258.01088.381697330.73572.4411622...0.30458321247.62881.025214186.61880.000064111
449922.644525532.3066211258.01088.381697330.73572.4411622...0.30458321247.54871.025214186.61880.000064111
449932.621785532.1497211258.01088.381697330.73572.4360360...0.30458321247.54871.025214186.53870.000064111
449942.613778531.5216211258.01088.381697330.73572.3386410...0.30458321247.54871.025214186.52270.000064111
449952.613778531.4038211258.01088.381697330.73572.2215100...0.30458321247.54871.025214186.52270.000064111
\n", + "

5 rows × 51 columns

\n", + "
" + ], + "text/plain": [ + " FIT101 LIT101 MV101 P101 P102 AIT201 AIT202 AIT203 \\\n", + "44991 2.665983 533.0524 2 1 1 258.0108 8.381697 330.7357 \n", + "44992 2.644525 532.3066 2 1 1 258.0108 8.381697 330.7357 \n", + "44993 2.621785 532.1497 2 1 1 258.0108 8.381697 330.7357 \n", + "44994 2.613778 531.5216 2 1 1 258.0108 8.381697 330.7357 \n", + "44995 2.613778 531.4038 2 1 1 258.0108 8.381697 330.7357 \n", + "\n", + " FIT201 MV201 ... FIT504 P501 P502 PIT501 PIT502 \\\n", + "44991 2.441162 2 ... 0.304583 2 1 247.6288 1.025214 \n", + "44992 2.441162 2 ... 0.304583 2 1 247.5487 1.025214 \n", + "44993 2.436036 0 ... 0.304583 2 1 247.5487 1.025214 \n", + "44994 2.338641 0 ... 0.304583 2 1 247.5487 1.025214 \n", + "44995 2.221510 0 ... 0.304583 2 1 247.5487 1.025214 \n", + "\n", + " PIT503 FIT601 P601 P602 P603 \n", + "44991 186.6188 0.000064 1 1 1 \n", + "44992 186.6188 0.000064 1 1 1 \n", + "44993 186.5387 0.000064 1 1 1 \n", + "44994 186.5227 0.000064 1 1 1 \n", + "44995 186.5227 0.000064 1 1 1 \n", + "\n", + "[5 rows x 51 columns]" + ] + }, + "execution_count": 99, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test_dropped.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
FIT101LIT101MV101P101P102AIT201AIT202AIT203FIT201MV201...FIT504P501P502PIT501PIT502PIT503FIT601P601P602P603
02.427057522.8467221262.01618.396437328.63372.4453912...0.30778621250.86521.649953189.59880.000128111
12.446274522.8860221262.01618.396437328.63372.4453912...0.30778621250.86521.649953189.67890.000128111
22.489191522.8467221262.01618.394514328.63372.4423162...0.30861921250.88121.649953189.67890.000128111
32.534350522.9645221262.01618.394514328.63372.4423162...0.30861921250.88121.649953189.61480.000128111
42.569260523.4748221262.01618.394514328.63372.4430852...0.30861921250.88121.649953189.50270.000128111
\n", + "

5 rows × 51 columns

\n", + "
" + ], + "text/plain": [ + " FIT101 LIT101 MV101 P101 P102 AIT201 AIT202 AIT203 \\\n", + "0 2.427057 522.8467 2 2 1 262.0161 8.396437 328.6337 \n", + "1 2.446274 522.8860 2 2 1 262.0161 8.396437 328.6337 \n", + "2 2.489191 522.8467 2 2 1 262.0161 8.394514 328.6337 \n", + "3 2.534350 522.9645 2 2 1 262.0161 8.394514 328.6337 \n", + "4 2.569260 523.4748 2 2 1 262.0161 8.394514 328.6337 \n", + "\n", + " FIT201 MV201 ... FIT504 P501 P502 PIT501 PIT502 PIT503 \\\n", + "0 2.445391 2 ... 0.307786 2 1 250.8652 1.649953 189.5988 \n", + "1 2.445391 2 ... 0.307786 2 1 250.8652 1.649953 189.6789 \n", + "2 2.442316 2 ... 0.308619 2 1 250.8812 1.649953 189.6789 \n", + "3 2.442316 2 ... 0.308619 2 1 250.8812 1.649953 189.6148 \n", + "4 2.443085 2 ... 0.308619 2 1 250.8812 1.649953 189.5027 \n", + "\n", + " FIT601 P601 P602 P603 \n", + "0 0.000128 1 1 1 \n", + "1 0.000128 1 1 1 \n", + "2 0.000128 1 1 1 \n", + "3 0.000128 1 1 1 \n", + "4 0.000128 1 1 1 \n", + "\n", + "[5 rows x 51 columns]" + ] + }, + "execution_count": 100, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "validation_dropped.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "metadata": {}, + "outputs": [], + "source": [ + "# Transform all columns into float64\n", + "for i in list(train_dropped):\n", + " train_dropped[i]=train_dropped[i].apply(lambda x: str(x).replace(\",\" , \".\"))\n", + "train_dropped = train_dropped.astype(float)\n", + "\n", + "for i in list(test_dropped):\n", + " test_dropped[i]=test_dropped[i].apply(lambda x: str(x).replace(\",\" , \".\"))\n", + "test_dropped = test_dropped.astype(float)\n", + "\n", + "for i in list(validation_dropped):\n", + " validation_dropped[i]=validation_dropped[i].apply(lambda x: str(x).replace(\",\" , \".\"))\n", + "validation_dropped = validation_dropped.astype(float)" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [], + "source": [ + "train_values = train_dropped.values\n", + "test_values = test_dropped.values\n", + "validation_values = validation_dropped.values" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train min: 0.0\n", + "Train max: 1014.724\n", + "---\n", + "Test min: 0.0\n", + "Test max: 1201.0\n", + "---\n", + "Validation min: 0.0\n", + "Validation max: 1200.0\n" + ] + } + ], + "source": [ + "print(f'Train min: {train_values.min()}')\n", + "print(f'Train max: {train_values.max()}')\n", + "print('---')\n", + "print(f'Test min: {test_values.min()}')\n", + "print(f'Test max: {test_values.max()}')\n", + "print('---')\n", + "print(f'Validation min: {validation_values.min()}')\n", + "print(f'Validation max: {validation_values.max()}')" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 0. , 189.8263 , 0. , 1. , 1. ,\n", + " 168.0338 , 8.366317, 285.3371 , 0. , 0. ,\n", + " 1. , 1. , 1. , 1. , 1. ,\n", + " 1. , 0. , 0. , 364.3863 , 0. ,\n", + " 0. , 0. , 0. , 1. , 1. ,\n", + " 148.7599 , 140.8357 , 0. , 243.0146 , 1. ,\n", + " 1. , 1. , 1. , 1. , 7.432902,\n", + " 129.8385 , 244.8731 , 9.536016, 0. , 0. ,\n", + " 0. , 0. , 1. , 1. , 9.468726,\n", + " 0. , 3.14022 , 0. , 1. , 1. ,\n", + " 1. ])" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test_values.min(axis=0)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(495000, 51)" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train_values.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.preprocessing import MinMaxScaler, MaxAbsScaler\n", + "\n", + "def scale_data(train, test, validation):\n", + " scaler = MinMaxScaler(feature_range=(0, 1), clip=True).fit(train)\n", + " #scaler = MaxAbsScaler().fit(train)\n", + "\n", + " train_scaled = scaler.transform(train)\n", + " test_scaled = scaler.transform(test)\n", + " validation_scaled = scaler.transform(validation)\n", + "\n", + " # train_scaled = scaler.fit_transform(train)\n", + " # validation_scaled = scaler.fit_transform(validation)\n", + " # test_scaled = scaler.fit_transform(test)\n", + "\n", + " return train_scaled, test_scaled, validation_scaled" + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "metadata": {}, + "outputs": [], + "source": [ + "train_norm, test_norm, validation_norm = scale_data(train_values, test_values, validation_values)" + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-----Dim 0----\n", + "TRAIN original: 0.0, 2.745092\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 0.0, 2.760145\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 0.0, 2.698972\n", + "VAL norm: 0.0, 0.9831991058951758\n", + "-----Dim 1----\n", + "TRAIN original: 120.6237, 817.5565\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 189.8263, 888.1722\n", + "TEST norm: 0.09929594359743149, 1.0\n", + "VAL original: 488.0688, 925.0323\n", + "VAL norm: 0.5272317503208344, 1.0\n", + "-----Dim 2----\n", + "TRAIN original: 0.0, 2.0\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 0.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 0.0, 2.0\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 3----\n", + "TRAIN original: 1.0, 2.0\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 1.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 1.0, 2.0\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 4----\n", + "TRAIN original: 1.0, 1.0\n", + "TRAIN norm: 0.0, 0.0\n", + "TEST original: 1.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 1.0, 2.0\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 5----\n", + "TRAIN original: 251.6662, 272.5263\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 168.0338, 267.7198\n", + "TEST norm: 0.0, 0.7695840384274284\n", + "VAL original: 257.8826, 266.0856\n", + "VAL norm: 0.2980043240444683, 0.6912430908768403\n", + "-----Dim 6----\n", + "TRAIN original: 8.258652, 8.988273\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 8.366317, 8.73321\n", + "TEST norm: 0.14756291279993405, 0.6504171343752443\n", + "VAL original: 6.0, 8.470778\n", + "VAL norm: 0.0, 0.2907345046263732\n", + "-----Dim 7----\n", + "TRAIN original: 312.2789, 567.4699\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 285.3371, 384.4655\n", + "TEST norm: 0.0, 0.2828728285872151\n", + "VAL original: 314.8423, 336.8111\n", + "VAL norm: 0.010045025098847526, 0.09613270060464507\n", + "-----Dim 8----\n", + "TRAIN original: 0.0, 2.487938\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 0.0, 2.826899\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 0.0, 2.804857\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 9----\n", + "TRAIN original: 0.0, 2.0\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 0.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 0.0, 2.0\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 10----\n", + "TRAIN original: 1.0, 1.0\n", + "TRAIN norm: 0.0, 0.0\n", + "TEST original: 1.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 1.0, 1.0\n", + "VAL norm: 0.0, 0.0\n", + "-----Dim 11----\n", + "TRAIN original: 1.0, 1.0\n", + "TRAIN norm: 0.0, 0.0\n", + "TEST original: 1.0, 1.0\n", + "TEST norm: 0.0, 0.0\n", + "VAL original: 1.0, 1.0\n", + "VAL norm: 0.0, 0.0\n", + "-----Dim 12----\n", + "TRAIN original: 1.0, 2.0\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 1.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 1.0, 2.0\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 13----\n", + "TRAIN original: 1.0, 1.0\n", + "TRAIN norm: 0.0, 0.0\n", + "TEST original: 1.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 1.0, 1.0\n", + "VAL norm: 0.0, 0.0\n", + "-----Dim 14----\n", + "TRAIN original: 1.0, 2.0\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 1.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 1.0, 2.0\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 15----\n", + "TRAIN original: 1.0, 1.0\n", + "TRAIN norm: 0.0, 0.0\n", + "TEST original: 1.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 1.0, 1.0\n", + "VAL norm: 0.0, 0.0\n", + "-----Dim 16----\n", + "TRAIN original: 0.0, 21.0993\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 0.0, 45.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 0.006402459, 45.0\n", + "VAL norm: 0.00030344414269667716, 1.0\n", + "-----Dim 17----\n", + "TRAIN original: 0.0, 2.358774\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 0.0, 2.376197\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 0.0, 2.352112\n", + "VAL norm: 0.0, 0.9971756514189151\n", + "-----Dim 18----\n", + "TRAIN original: 132.8185, 1014.724\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 364.3863, 1201.0\n", + "TEST norm: 0.26257665929059293, 1.0\n", + "VAL original: 732.1039, 1200.0\n", + "VAL norm: 0.6795347120524817, 1.0\n", + "-----Dim 19----\n", + "TRAIN original: 0.0, 2.0\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 0.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 0.0, 2.0\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 20----\n", + "TRAIN original: 0.0, 2.0\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 0.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 0.0, 2.0\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 21----\n", + "TRAIN original: 0.0, 2.0\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 0.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 0.0, 2.0\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 22----\n", + "TRAIN original: 0.0, 2.0\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 0.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 0.0, 2.0\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 23----\n", + "TRAIN original: 1.0, 2.0\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 1.0, 1.0\n", + "TEST norm: 0.0, 0.0\n", + "VAL original: 1.0, 1.0\n", + "VAL norm: 0.0, 0.0\n", + "-----Dim 24----\n", + "TRAIN original: 1.0, 2.0\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 1.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 1.0, 2.0\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 25----\n", + "TRAIN original: 0.0, 148.8561\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 148.7599, 148.8561\n", + "TEST norm: 0.9993537382747499, 1.0\n", + "VAL original: 148.7695, 148.8561\n", + "VAL norm: 0.9994182300893278, 1.0\n", + "-----Dim 26----\n", + "TRAIN original: 153.7811, 235.7088\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 140.8357, 333.8118\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 151.961, 297.3853\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 27----\n", + "TRAIN original: 0.0, 1.747862\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 0.0, 1.744914\n", + "TEST norm: 0.0, 0.998313367989006\n", + "VAL original: 0.0, 1.743504\n", + "VAL norm: 0.0, 0.9975066681465699\n", + "-----Dim 28----\n", + "TRAIN original: 130.3896, 1003.935\n", + "TRAIN norm: 0.0, 0.9999999999999999\n", + "TEST original: 243.0146, 1002.781\n", + "TEST norm: 0.12892861664659905, 0.9986789467382003\n", + "VAL original: 572.6224, 1001.935\n", + "VAL norm: 0.5062505051254348, 0.9977104796155986\n", + "-----Dim 29----\n", + "TRAIN original: 1.0, 1.0\n", + "TRAIN norm: 0.0, 0.0\n", + "TEST original: 1.0, 1.0\n", + "TEST norm: 0.0, 0.0\n", + "VAL original: 1.0, 1.0\n", + "VAL norm: 0.0, 0.0\n", + "-----Dim 30----\n", + "TRAIN original: 1.0, 2.0\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 1.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 1.0, 2.0\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 31----\n", + "TRAIN original: 1.0, 1.0\n", + "TRAIN norm: 0.0, 0.0\n", + "TEST original: 1.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 1.0, 1.0\n", + "VAL norm: 0.0, 0.0\n", + "-----Dim 32----\n", + "TRAIN original: 1.0, 1.0\n", + "TRAIN norm: 0.0, 0.0\n", + "TEST original: 1.0, 1.0\n", + "TEST norm: 0.0, 0.0\n", + "VAL original: 1.0, 1.0\n", + "VAL norm: 0.0, 0.0\n", + "-----Dim 33----\n", + "TRAIN original: 1.0, 2.0\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 1.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 1.0, 2.0\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 34----\n", + "TRAIN original: 7.411433, 7.925084\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 7.432902, 8.307037\n", + "TEST norm: 0.04179686207171862, 1.0\n", + "VAL original: 7.831518, 8.219559\n", + "VAL norm: 0.8178412969117161, 1.0\n", + "-----Dim 35----\n", + "TRAIN original: 142.3481, 218.3286\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 129.8385, 260.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 141.8354, 272.8531\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 36----\n", + "TRAIN original: 252.0828, 283.3568\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 244.8731, 297.2635\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 260.0936, 291.0151\n", + "VAL norm: 0.25614887766195515, 1.0\n", + "-----Dim 37----\n", + "TRAIN original: 7.344271, 227.1725\n", + "TRAIN norm: 0.0, 0.9999999999999999\n", + "TEST original: 9.536016, 442.4635\n", + "TEST norm: 0.009970261826564596, 1.0\n", + "VAL original: 9.766726, 18.99513\n", + "VAL norm: 0.011019763071466127, 0.05299983106355279\n", + "-----Dim 38----\n", + "TRAIN original: 0.001281723, 1.757754\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 0.0, 1.753653\n", + "TEST norm: 0.0, 0.9976652065314663\n", + "VAL original: 1.217636, 1.752628\n", + "VAL norm: 0.6924984202298343, 0.9970816504950736\n", + "-----Dim 39----\n", + "TRAIN original: 0.000640451, 1.361983\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 0.0, 1.358781\n", + "TEST norm: 0.0, 0.9976479101440325\n", + "VAL original: 0.8169591, 1.360318\n", + "VAL norm: 0.599642352763926, 0.9987769426576558\n", + "-----Dim 40----\n", + "TRAIN original: 0.001664373, 0.7636911\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 0.0, 0.7415421\n", + "TEST norm: 0.0, 0.9709340903472012\n", + "VAL original: 0.3337708, 0.7391096\n", + "VAL norm: 0.4358199197388519, 0.96774194509322\n", + "-----Dim 41----\n", + "TRAIN original: 0.0, 0.3170099\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 0.0, 0.3116933\n", + "TEST norm: 0.0, 0.9832289149329405\n", + "VAL original: 0.0, 0.3109887\n", + "VAL norm: 0.0, 0.9810062714129748\n", + "-----Dim 42----\n", + "TRAIN original: 1.0, 2.0\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 1.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 1.0, 2.0\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 43----\n", + "TRAIN original: 1.0, 1.0\n", + "TRAIN norm: 0.0, 0.0\n", + "TEST original: 1.0, 1.0\n", + "TEST norm: 0.0, 0.0\n", + "VAL original: 1.0, 1.0\n", + "VAL norm: 0.0, 0.0\n", + "-----Dim 44----\n", + "TRAIN original: 8.891951, 264.6437\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 9.468726, 254.3418\n", + "TEST norm: 0.0022552142937642267, 0.9597191415492528\n", + "VAL original: 163.8843, 251.522\n", + "VAL norm: 0.6060265456874743, 0.9486936060014978\n", + "-----Dim 45----\n", + "TRAIN original: 0.0, 3.668343\n", + "TRAIN norm: 0.0, 0.9999999999999999\n", + "TEST original: 0.0, 1.826162\n", + "TEST norm: 0.0, 0.4978165891248446\n", + "VAL original: 0.0, 1.970333\n", + "VAL norm: 0.0, 0.5371179848776408\n", + "-----Dim 46----\n", + "TRAIN original: 3.108177, 200.6376\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 3.14022, 191.986\n", + "TEST norm: 0.00016221887105902222, 0.9562009554394335\n", + "VAL original: 134.4687, 190.3679\n", + "VAL norm: 0.6650174996967415, 0.9480092644223439\n", + "-----Dim 47----\n", + "TRAIN original: 0.0, 1.746131\n", + "TRAIN norm: 0.0, 0.9999999999999999\n", + "TEST original: 0.0, 1.80271\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 0.0, 1.742287\n", + "VAL norm: 0.0, 0.9977985615054081\n", + "-----Dim 48----\n", + "TRAIN original: 1.0, 1.0\n", + "TRAIN norm: 0.0, 0.0\n", + "TEST original: 1.0, 1.0\n", + "TEST norm: 0.0, 0.0\n", + "VAL original: 1.0, 1.0\n", + "VAL norm: 0.0, 0.0\n", + "-----Dim 49----\n", + "TRAIN original: 1.0, 2.0\n", + "TRAIN norm: 0.0, 1.0\n", + "TEST original: 1.0, 2.0\n", + "TEST norm: 0.0, 1.0\n", + "VAL original: 1.0, 2.0\n", + "VAL norm: 0.0, 1.0\n", + "-----Dim 50----\n", + "TRAIN original: 1.0, 1.0\n", + "TRAIN norm: 0.0, 0.0\n", + "TEST original: 1.0, 1.0\n", + "TEST norm: 0.0, 0.0\n", + "VAL original: 1.0, 1.0\n", + "VAL norm: 0.0, 0.0\n" + ] + } + ], + "source": [ + "for i in range(51):\n", + " print(f'-----Dim {i}----')\n", + " print(f'TRAIN original: {train_values[:, i].min()}, {train_values[:, i].max()}')\n", + " print(f'TRAIN norm: {train_norm[:, i].min()}, {train_norm[:, i].max()}')\n", + " print(f'TEST original: {test_values[:, i].min()}, {test_values[:, i].max()}')\n", + " print(f'TEST norm: {test_norm[:, i].min()}, {test_norm[:, i].max()}')\n", + " print(f'VAL original: {validation_values[:, i].min()}, {validation_values[:, i].max()}')\n", + " print(f'VAL norm: {validation_norm[:, i].min()}, {validation_norm[:, i].max()}')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.0 1.0\n", + "0.0 1.0\n", + "0.0 1.0\n", + "(495000, 51) (404928, 51) (44991, 51)\n" + ] + } + ], + "source": [ + "print(train_norm.min(), train_norm.max())\n", + "print(test_norm.min(), test_norm.max())\n", + "print(validation_norm.min(), validation_norm.max())\n", + "print(train_norm.shape, test_norm.shape, validation_norm.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": {}, + "outputs": [], + "source": [ + "test_labels_clipped = test_labels_clipped.to_numpy()\n", + "test_labels_reshaped = np.zeros_like(test_norm)\n", + "\n", + "for idx in range(0, len(test_labels_clipped)):\n", + " if test_labels_clipped[idx]:\n", + " # labels_reshaped.shape[1] == 51 aka num_feats\n", + " test_labels_reshaped[idx][0:test_labels_reshaped.shape[1]] = 1" + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "metadata": {}, + "outputs": [], + "source": [ + "validation_labels_reshaped = np.zeros_like(validation_norm)\n", + "\n", + "for idx in range(0, len(validation_labels)):\n", + " if validation_labels[idx]:\n", + " # labels_reshaped.shape[1] == 51 aka num_feats\n", + " validation_labels_reshaped[idx][0:validation_labels_reshaped.shape[1]] = 1" + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(404928, 51) (44991, 51)\n" + ] + } + ], + "source": [ + "print(test_labels_reshaped.shape, validation_labels_reshaped.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "metadata": {}, + "outputs": [], + "source": [ + "np.save('labels.npy', test_labels_reshaped)\n", + "np.save('labels_validation.npy', validation_labels_reshaped)\n", + "np.save('train.npy', train_norm)\n", + "np.save('test.npy', test_norm)\n", + "np.save('validation.npy', validation_norm)" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "metadata": {}, + "outputs": [], + "source": [ + "load_test = np.load('../processed/SWAT_big/validation.npy')" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "labels = np.load('../processed/SWAT_big/labels.npy')\n", + "labels_validation = np.load('../processed/SWAT_big/labels_validation.npy')\n", + "labels = (np.sum(labels, axis=1) >= 1) + 0\n", + "labels_validation = (np.sum(labels_validation, axis=1) >= 1) + 0\n", + "# labels.shape[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12.140185233342002" + ] + }, + "execution_count": 82, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "((labels.sum() + labels_validation.sum()) / (labels.shape[0] + labels_validation.shape[0])) * 100" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1501" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "labels.sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.12386152599968389" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(labels.sum() / labels.shape[0]) " + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(44991, 51)" + ] + }, + "execution_count": 113, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "load_test.shape" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "py3.9test", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "27efe6010b91a164a18a011cd71b7afbe2f076e5b83b7f8099f414d97e11e710" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/subject1-4/AdaDiff/data/split_val_wadi.ipynb b/subject1-4/AdaDiff/data/split_val_wadi.ipynb new file mode 100644 index 0000000..fa867f5 --- /dev/null +++ b/subject1-4/AdaDiff/data/split_val_wadi.ipynb @@ -0,0 +1,1188 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "train = pd.read_csv('WADI_14days_new.csv')\n", + "test = pd.read_csv('WADI_attackdataLABLE.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(784571, 130)\n", + "(172803, 131)\n" + ] + } + ], + "source": [ + "print(train.shape)\n", + "print(test.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(784571, 126)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train = train.dropna(axis=1, how='all')\n", + "train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(172803, 127)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test = test.dropna(axis=1, how='all')\n", + "test.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['Row', 'Date', 'Time', '1_AIT_001_PV', '1_AIT_002_PV', '1_AIT_003_PV',\n", + " '1_AIT_004_PV', '1_AIT_005_PV', '1_FIT_001_PV', '1_LS_001_AL',\n", + " ...\n", + " '3_MV_001_STATUS', '3_MV_002_STATUS', '3_MV_003_STATUS',\n", + " '3_P_001_STATUS', '3_P_002_STATUS', '3_P_003_STATUS', '3_P_004_STATUS',\n", + " 'LEAK_DIFF_PRESSURE', 'PLANT_START_STOP_LOG',\n", + " 'TOTAL_CONS_REQUIRED_FLOW'],\n", + " dtype='object', length=126)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train.columns" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['Row ', 'Date ', 'Time', '1_AIT_001_PV', '1_AIT_002_PV', '1_AIT_003_PV',\n", + " '1_AIT_004_PV', '1_AIT_005_PV', '1_FIT_001_PV', '1_LS_001_AL',\n", + " ...\n", + " '3_MV_002_STATUS', '3_MV_003_STATUS', '3_P_001_STATUS',\n", + " '3_P_002_STATUS', '3_P_003_STATUS', '3_P_004_STATUS',\n", + " 'LEAK_DIFF_PRESSURE', 'PLANT_START_STOP_LOG',\n", + " 'TOTAL_CONS_REQUIRED_FLOW', 'Attack LABLE (1:No Attack, -1:Attack)'],\n", + " dtype='object', length=127)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test.columns" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + " 1 162826\n", + "-1 9977\n", + "Name: Attack LABLE (1:No Attack, -1:Attack), dtype: int64" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test['Attack LABLE (1:No Attack, -1:Attack)'].value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# trim column names\n", + "train = train.rename(columns=lambda x: x.strip())\n", + "test = test.rename(columns=lambda x: x.strip())" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 162826\n", + "1 9977\n", + "Name: Attack LABLE (1:No Attack, -1:Attack), dtype: int64" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test['Attack LABLE (1:No Attack, -1:Attack)'] = [1 if x == -1 else 0 for x in test['Attack LABLE (1:No Attack, -1:Attack)']]\n", + "test['Attack LABLE (1:No Attack, -1:Attack)'].value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(172803,)\n", + "9977\n" + ] + } + ], + "source": [ + "test_labels = test['Attack LABLE (1:No Attack, -1:Attack)'].values\n", + "print(test_labels.shape)\n", + "print(np.sum(test_labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "def search_ratio(test_labels, val_len):\n", + " val = test_labels[:val_len]\n", + " test = test_labels[val_len:]\n", + " test_ratio = (np.sum(test) /test.shape[0]) * 100\n", + " val_ratio = (np.sum(val) / val.shape[0]) * 100\n", + " print(f'val ratio: {val_ratio}')\n", + " print(f'test ratio: {test_ratio}')\n", + " print('----')\n", + " return val_ratio, test_ratio" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "val ratio: 8.686342592592593\n", + "test ratio: 5.449997749529008\n", + "----\n", + "val ratio: 5.790895061728396\n", + "test ratio: 5.770579304616599\n", + "----\n", + "val ratio: 4.343171296296297\n", + "test ratio: 6.131232684475886\n", + "----\n", + "val ratio: 2.895447530864198\n", + "test ratio: 7.007101345039392\n", + "----\n" + ] + } + ], + "source": [ + "vr, tr = search_ratio(test_labels=test_labels, val_len=int(0.1 * test.shape[0]))\n", + "vr, tr = search_ratio(test_labels=test_labels, val_len=int(0.15 * test.shape[0]))\n", + "vr, tr = search_ratio(test_labels=test_labels, val_len=int(0.2 * test.shape[0]))\n", + "vr, tr = search_ratio(test_labels=test_labels, val_len=int(0.3 * test.shape[0]))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "25920" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "val_len = int(0.15 * test.shape[0])\n", + "val_len" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(25920, 127)" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "validation = test[:val_len]\n", + "validation.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(146883, 127)" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test_clipped = test[val_len:]\n", + "test_clipped.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 24419\n", + "1 1501\n", + "Name: Attack LABLE (1:No Attack, -1:Attack), dtype: int64" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "validation['Attack LABLE (1:No Attack, -1:Attack)'].value_counts()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(146883,)" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test_labels_clipped = test_labels[val_len:]\n", + "test_labels_clipped.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(25920,)" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "validation_labels = test_labels[:val_len]\n", + "validation_labels.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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AACsQtwAAACrEDcAAMAqxA0AALAKcQMAAKxC3AAAAKsQNwAAwCrEDQAAsApxAwAArELcAAAAqxA3AADAKsQNAACwCnEDAACsQtwAAACrEDcAAMAqxA0AALAKcQMAAKxC3AAAAKuclriZM2eOunfvrtjYWGVnZ2vdunUNrl+6dKnS0tIUGxur9PR0rVy5Muy8MUYzZszQOeeco3bt2snn82nHjh2RHAEAALQSEY+bJUuWqLCwUDNnztTGjRvVr18/5eXlqbKyst7177//vvLz8zV69Ght2rRJQ4YM0ZAhQ1RWVuaseeSRR/Tkk09q3rx5Wrt2rc466yzl5eXp8OHDkR4HAAC0cC5jjInkA2RnZ+vSSy/V008/LUkKhUJKSUnR+PHjNXXq1OPWDxs2TAcPHtSKFSucYwMGDFD//v01b948GWOUnJysSZMm6c9//rMkqbq6WklJSZo/f75uuummk+4pGAwqLi5O1dXV8ng8TTQpAACIpMa+fkdHchNHjhxRaWmppk2b5hyLioqSz+eT3++v9xq/36/CwsKwY3l5eVq+fLkk6bPPPlMgEJDP53POx8XFKTs7W36/v964qampUU1NjfPnYDD4S8Y6oZJtFXrvf/sict8AALQmuWlJurxXYrM8dkTjZt++fTp27JiSkpLCjiclJWn79u31XhMIBOpdHwgEnPN1x0605qeKiop0//33/6wZTkXpzm/0/H8/j/jjAADQ0nXu6LYzblqKadOmhb0bFAwGlZKS0uSPM6BnglyuJr9bAABanUtSz262x45o3CQmJqpNmzaqqKgIO15RUSGv11vvNV6vt8H1df+3oqJC55xzTtia/v3713ufbrdbbrf7547RaL/5VWf95ledI/44AADgxCL6bamYmBhlZGSopKTEORYKhVRSUqKcnJx6r8nJyQlbL0nFxcXO+h49esjr9YatCQaDWrt27QnvEwAAnDki/tdShYWFGjlypDIzM5WVlaVZs2bp4MGDGjVqlCRpxIgR6tq1q4qKiiRJEyZM0KBBg/TYY49p8ODBWrx4sTZs2KBnn31WkuRyuTRx4kT93//9n3r16qUePXrovvvuU3JysoYMGRLpcQAAQAsX8bgZNmyYvvrqK82YMUOBQED9+/fXqlWrnA8E79q1S1FRP7yBNHDgQC1atEjTp0/XPffco169emn58uXq27evs+bu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MKi4uDhVV1fL4/H8smEBAMBp0djX74i8c+P3+xUfH++EjST5fD5FRUVp7dq19V5TWlqq2tpa+Xw+51haWppSU1Pl9/udY1u3btVf/vIXvfDCC4qKatz2a2pqFAwGw24AAMBOEYmbQCCgLl26hB2Ljo5Wp06dFAgETnhNTEzMce/AJCUlOdfU1NQoPz9fjz76qFJTUxu9n6KiIsXFxTm3lJSUUxsIAAC0GqcUN1OnTpXL5Wrwtn379kjtVdOmTVPv3r118803n/J11dXVzm337t0R2iEAAGhu0aeyeNKkSbrlllsaXNOzZ095vV5VVlaGHT969Kj2798vr9db73Ver1dHjhxRVVVV2Ls3FRUVzjWrV6/Wxx9/rJdfflmSVPdxocTERN177726//77671vt9stt9vdmBEBAEArd0px07lzZ3Xu3Pmk63JyclRVVaXS0lJlZGRI+j5MQqGQsrOz670mIyNDbdu2VUlJiYYOHSpJKi8v165du5STkyNJ+te//qXvvvvOuWb9+vW69dZb9e677+q88847lVEAAIClTiluGqt379666qqrdNttt2nevHmqra3VuHHjdNNNNznflNqzZ49yc3P1wgsvKCsrS3FxcRo9erQKCwvVqVMneTwejR8/Xjk5Oc43pX4aMPv27XMe71S+LQUAAOwVkbiRpIULF2rcuHHKzc1VVFSUhg4dqieffNI5X1tbq/Lych06dMg59sQTTzhra2pqlJeXp2eeeSZSWwQAABaKyO+5aen4PTcAALQ+zfp7bgAAAJoLcQMAAKxC3AAAAKsQNwAAwCrEDQAAsApxAwAArELcAAAAqxA3AADAKsQNAACwCnEDAACsQtwAAACrEDcAAMAqxA0AALAKcQMAAKxC3AAAAKsQNwAAwCrEDQAAsApxAwAArELcAAAAqxA3AADAKsQNAACwCnEDAACsQtwAAACrEDcAAMAqxA0AALAKcQMAAKxC3AAAAKsQNwAAwCrEDQAAsApxAwAArELcAAAAqxA3AADAKsQNAACwCnEDAACsQtwAAACrEDcAAMAqxA0AALAKcQMAAKxC3AAAAKsQNwAAwCrEDQAAsApxAwAArBLd3BtoDsYYSVIwGGzmnQAAgMaqe92uex0/kTMybg4cOCBJSklJaeadAACAU3XgwAHFxcWd8LzLnCx/LBQKhbR371517NhRLperSe87GAwqJSVFu3fvlsfjadL7bqmY+cyYWToz5z4TZ5bOzLmZueXPbIzRgQMHlJycrKioE3+y5ox85yYqKkrdunWL6GN4PJ5W8f8oTYmZzxxn4txn4szSmTk3M7dsDb1jU4cPFAMAAKsQNwAAwCrETRNzu92aOXOm3G53c2/ltGHmM8eZOPeZOLN0Zs7NzPY4Iz9QDAAA7MU7NwAAwCrEDQAAsApxAwAArELcAAAAqxA3TWjOnDnq3r27YmNjlZ2drXXr1jX3lupVVFSkSy+9VB07dlSXLl00ZMgQlZeXh605fPiwxo4dq4SEBHXo0EFDhw5VRUVF2Jpdu3Zp8ODBat++vbp06aLJkyfr6NGjYWveeustXXLJJXK73Tr//PM1f/784/bTHM/bQw89JJfLpYkTJzrHbJ15z549uvnmm5WQkKB27dopPT1dGzZscM4bYzRjxgydc845ateunXw+n3bs2BF2H/v371dBQYE8Ho/i4+M1evRoffvtt2FrPvroI/36179WbGysUlJS9Mgjjxy3l6VLlyotLU2xsbFKT0/XypUrm3zeY8eO6b777lOPHj3Url07nXfeeXrggQfC/i0aG2Z+55139Lvf/U7JyclyuVxavnx52PmWNGNj9vJLZ66trdWUKVOUnp6us846S8nJyRoxYoT27t3bqmc+2dw/dfvtt8vlcmnWrFmtfu5fxKBJLF682MTExJjnnnvObNmyxdx2220mPj7eVFRUNPfWjpOXl2eef/55U1ZWZjZv3myuueYak5qaar799ltnze23325SUlJMSUmJ2bBhgxkwYIAZOHCgc/7o0aOmb9++xufzmU2bNpmVK1eaxMREM23aNGfNp59+atq3b28KCwvN1q1bzVNPPWXatGljVq1a5axpjudt3bp1pnv37uaiiy4yEyZMsHrm/fv3m3PPPdfccsstZu3atebTTz81b7zxhvnf//7nrHnooYdMXFycWb58ufnwww/Ntddea3r06GG+++47Z81VV11l+vXrZz744APz7rvvmvPPP9/k5+c756urq01SUpIpKCgwZWVl5sUXXzTt2rUzf//73501//3vf02bNm3MI488YrZu3WqmT59u2rZtaz7++OMmnfnBBx80CQkJZsWKFeazzz4zS5cuNR06dDCzZ8+2auaVK1eae++91yxbtsxIMq+88krY+ZY0Y2P28ktnrqqqMj6fzyxZssRs377d+P1+k5WVZTIyMsLuo7XNfLK5f2zZsmWmX79+Jjk52TzxxBOtfu5fgrhpIllZWWbs2LHOn48dO2aSk5NNUVFRM+6qcSorK40k8/bbbxtjvv8h0bZtW7N06VJnzbZt24wk4/f7jTHf/8cWFRVlAoGAs2bu3LnG4/GYmpoaY4wxd999t+nTp0/YYw0bNszk5eU5fz7dz9uBAwdMr169THFxsRk0aJATN7bOPGXKFHP55Zef8HwoFDJer9c8+uijzrGqqirjdrvNiy++aIwxZuvWrUaSWb9+vbPmP//5j3G5XGbPnj3GGGOeeeYZc/bZZzvPQ91jX3DBBc6fb7zxRjN48OCwx8/OzjZ//OMff9mQPzF48GBz6623hh27/vrrTUFBgTHGzpl/+oLXkmZszF6aYub6rFu3zkgyO3fuNMa0/pmNOfHcX3zxhenataspKysz5557bljc2DD3qeKvpZrAkSNHVFpaKp/P5xyLioqSz+eT3+9vxp01TnV1tSSpU6dOkqTS0lLV1taGzZOWlqbU1FRnHr/fr/T0dCUlJTlr8vLyFAwGtWXLFmfNj++jbk3dfTTH8zZ27FgNHjz4uH3ZOvOrr76qzMxM/eEPf1CXLl108cUX6x//+Idz/rPPPlMgEAjbT1xcnLKzs8Pmjo+PV2ZmprPG5/MpKipKa9euddb85je/UUxMTNjc5eXl+uabb5w1DT03TWXgwIEqKSnRJ598Ikn68MMP9d577+nqq6+2duafakkzNmYvkVJdXS2Xy6X4+HhnrzbOHAqFNHz4cE2ePFl9+vQ57rytczeEuGkC+/bt07Fjx8Je9CQpKSlJgUCgmXbVOKFQSBMnTtRll12mvn37SpICgYBiYmKcHwh1fjxPIBCod966cw2tCQaD+u67707787Z48WJt3LhRRUVFx52zdeZPP/1Uc+fOVa9evfTGG2/ojjvu0J133ql//vOfYftuaD+BQEBdunQJOx8dHa1OnTo1yXPT1HNPnTpVN910k9LS0tS2bVtdfPHFmjhxogoKCsL2Y9PMP9WSZmzMXiLh8OHDmjJlivLz851/ENLWmR9++GFFR0frzjvvrPe8rXM35Iz8V8Hxg7Fjx6qsrEzvvfdec28lonbv3q0JEyaouLhYsbGxzb2d0yYUCikzM1N//etfJUkXX3yxysrKNG/ePI0cObKZdxcZL730khYuXKhFixapT58+2rx5syZOnKjk5GRrZ0a42tpa3XjjjTLGaO7cuc29nYgqLS3V7NmztXHjRrlcrubeTovBOzdNIDExUW3atDnumzUVFRXyer3NtKuTGzdunFasWKE1a9aoW7duznGv16sjR46oqqoqbP2P5/F6vfXOW3euoTUej0ft2rU7rc9baWmpKisrdckllyg6OlrR0dF6++239eSTTyo6OlpJSUnWzSxJ55xzji688MKwY71799auXbvC9t3QfrxeryorK8POHz16VPv372+S56ap5548ebLz7k16erqGDx+uu+66y3nHzsaZf6olzdiYvTSlurDZuXOniouLnXdt6vZi28zvvvuuKisrlZqa6vxs27lzpyZNmqTu3bs7+7Ft7pMhbppATEyMMjIyVFJS4hwLhUIqKSlRTk5OM+6sfsYYjRs3Tq+88opWr16tHj16hJ3PyMhQ27Ztw+YpLy/Xrl27nHlycnL08ccfh/0HU/eDpO7FNCcnJ+w+6tbU3cfpfN5yc3P18ccfa/Pmzc4tMzNTBQUFzv+2bWZJuuyyy477mv8nn3yic889V5LUo0cPeb3esP0Eg0GtXbs2bO6qqiqVlpY6a1avXq1QKKTs7GxnzTvvvKPa2lpnTXFxsS644AKdffbZzpqGnpumcujQIUVFhf9oa9OmjUKhkCQ7Z/6pljRjY/bSVOrCZseOHXrzzTeVkJAQdt7GmYcPH66PPvoo7GdbcnKyJk+erDfeeMPauU/qtH582WKLFy82brfbzJ8/32zdutWMGTPGxMfHh32zpqW44447TFxcnHnrrbfMl19+6dwOHTrkrLn99ttNamqqWb16tdmwYYPJyckxOTk5zvm6r0VfeeWVZvPmzWbVqlWmc+fO9X4tevLkyWbbtm1mzpw59X4turmetx9/W8rWmdetW2eio6PNgw8+aHbs2GEWLlxo2rdvbxYsWOCseeihh0x8fLz597//bT766CNz3XXX1fuV4YsvvtisXbvWvPfee6ZXr15hXyOtqqoySUlJZvjw4aasrMwsXrzYtG/f/rivkUZHR5u//e1vZtu2bWbmzJkR+Sr4yJEjTdeuXZ2vgi9btswkJiaau+++26qZDxw4YDZt2mQ2bdpkJJnHH3/cbNq0yflmUEuasTF7+aUzHzlyxFx77bWmW7duZvPmzWE/2378DaDWNvPJ5q7PT78t1Vrn/iWImyb01FNPmdTUVBMTE2OysrLMBx980Nxbqpekem/PP/+8s+a7774zf/rTn8zZZ59t2rdvb37/+9+bL7/8Mux+Pv/8c3P11Vebdu3amcTERDNp0iRTW1sbtmbNmjWmf//+JiYmxvTs2TPsMeo01/P207ixdebXXnvN9O3b17jdbpOWlmaeffbZsPOhUMjcd999JikpybjdbpObm2vKy8vD1nz99dcmPz/fdOjQwXg8HjNq1Chz4MCBsDUffvihufzyy43b7TZdu3Y1Dz300HF7eemll8yvfvUrExMTY/r06WNef/31Jp83GAyaCRMmmNTUVBMbG2t69uxp7r333rAXOBtmXrNmTb3/HY8cObLFzdiYvfzSmT/77LMT/mxbs2ZNq535ZHPXp764aY1z/xIuY370azsBAABaOT5zAwAArELcAAAAqxA3AADAKsQNAACwCnEDAACsQtwAAACrEDcAAMAqxA0AALAKcQMAAKxC3AAAAKsQNwAAwCrEDQAAsMr/A5eCRx4pbREKAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "plt.plot(test_dropped.to_numpy()[:, 7])\n", + "#plt.fill_between(np.arange(test_labels.shape[0]), test_labels, color='red', alpha=0.3, linestyle='dashed', linewidth=0.3)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(172803,)" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test_labels.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "test_dropped = test_clipped.drop(['Row', 'Date', 'Time', 'Attack LABLE (1:No Attack, -1:Attack)'], axis=1)\n", + "validation_dropped = validation.drop(['Row', 'Date', 'Time', 'Attack LABLE (1:No Attack, -1:Attack)'], axis=1)\n", + "train_dropped = train.drop(['Row', 'Date', 'Time'], axis=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "metadata": {}, + "outputs": [], + "source": [ + "missing_test = test_dropped.isna().sum()\n", + "missing_val = validation_dropped.isna().sum()\n", + "missing_train = train_dropped.isna().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(784571, 123)" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train_dropped.shape" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for x in missing_train:\n", + " print(x)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "train_dropped = train_dropped.interpolate(method='linear', limit_direction='forward', axis=0)\n", + "train_dropped = train_dropped.fillna(0)\n", + "test_dropped = test_dropped.interpolate(method='linear', limit_direction='forward', axis=0)\n", + "test_dropped = test_dropped.fillna(0)\n", + "validation_dropped = validation_dropped.interpolate(method='linear', limit_direction='forward', axis=0)\n", + "validation_dropped = validation_dropped.fillna(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
1_AIT_001_PV1_AIT_002_PV1_AIT_003_PV1_AIT_004_PV1_AIT_005_PV1_FIT_001_PV1_LS_001_AL1_LS_002_AL1_LT_001_PV1_MV_001_STATUS...3_MV_001_STATUS3_MV_002_STATUS3_MV_003_STATUS3_P_001_STATUS3_P_002_STATUS3_P_003_STATUS3_P_004_STATUSLEAK_DIFF_PRESSUREPLANT_START_STOP_LOGTOTAL_CONS_REQUIRED_FLOW
120963179.5570.70346311.8693457.2620.2991320.001140.00.052.29841.0...1.01.01.01.01.01.01.063.88291.00.83
120964179.5570.70346311.8693457.2620.2991320.001140.00.052.29841.0...1.01.01.01.01.01.01.063.88291.00.83
120965179.5570.70346311.8693457.2620.2991320.001140.00.052.29841.0...1.01.01.01.01.01.01.063.88291.00.83
120966179.5570.70346311.8693457.2620.2991320.001140.00.052.29841.0...1.01.01.01.01.01.01.063.88291.00.83
120967179.5570.70346311.8693457.2620.2991320.001140.00.052.29841.0...1.01.01.01.01.01.01.063.88291.00.83
\n", + "

5 rows × 123 columns

\n", + "
" + ], + "text/plain": [ + " 1_AIT_001_PV 1_AIT_002_PV 1_AIT_003_PV 1_AIT_004_PV 1_AIT_005_PV \\\n", + "120963 179.557 0.703463 11.8693 457.262 0.299132 \n", + "120964 179.557 0.703463 11.8693 457.262 0.299132 \n", + "120965 179.557 0.703463 11.8693 457.262 0.299132 \n", + "120966 179.557 0.703463 11.8693 457.262 0.299132 \n", + "120967 179.557 0.703463 11.8693 457.262 0.299132 \n", + "\n", + " 1_FIT_001_PV 1_LS_001_AL 1_LS_002_AL 1_LT_001_PV 1_MV_001_STATUS \\\n", + "120963 0.00114 0.0 0.0 52.2984 1.0 \n", + "120964 0.00114 0.0 0.0 52.2984 1.0 \n", + "120965 0.00114 0.0 0.0 52.2984 1.0 \n", + "120966 0.00114 0.0 0.0 52.2984 1.0 \n", + "120967 0.00114 0.0 0.0 52.2984 1.0 \n", + "\n", + " ... 3_MV_001_STATUS 3_MV_002_STATUS 3_MV_003_STATUS \\\n", + "120963 ... 1.0 1.0 1.0 \n", + "120964 ... 1.0 1.0 1.0 \n", + "120965 ... 1.0 1.0 1.0 \n", + "120966 ... 1.0 1.0 1.0 \n", + "120967 ... 1.0 1.0 1.0 \n", + "\n", + " 3_P_001_STATUS 3_P_002_STATUS 3_P_003_STATUS 3_P_004_STATUS \\\n", + "120963 1.0 1.0 1.0 1.0 \n", + "120964 1.0 1.0 1.0 1.0 \n", + "120965 1.0 1.0 1.0 1.0 \n", + "120966 1.0 1.0 1.0 1.0 \n", + "120967 1.0 1.0 1.0 1.0 \n", + "\n", + " LEAK_DIFF_PRESSURE PLANT_START_STOP_LOG TOTAL_CONS_REQUIRED_FLOW \n", + "120963 63.8829 1.0 0.83 \n", + "120964 63.8829 1.0 0.83 \n", + "120965 63.8829 1.0 0.83 \n", + "120966 63.8829 1.0 0.83 \n", + "120967 63.8829 1.0 0.83 \n", + "\n", + "[5 rows x 123 columns]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "validation_dropped.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAACWUAAADFCAYAAAA2LQKkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAqtElEQVR4nO3dfZTXZZ0//ucMN4N3MyMqM46OiemKNyQKMo61W8asY3K2KNqEQ2lGUgYmYt7Qpra1hTdrN6ZJN7/N2jTNrdxCo53Am2NOqCAViuRuKt4NaMSMonI3798fffnUxI1QnwHUx+Oc95HPdb3e1/u6xnNeh8M8z/tTURRFEQAAAAAAAAAAAMqickdvAAAAAAAAAAAA4LVEKAsAAAAAAAAAAKCMhLIAAAAAAAAAAADKSCgLAAAAAAAAAACgjISyAAAAAAAAAAAAykgoCwAAAAAAAAAAoIyEsgAAAAAAAAAAAMqo747ewM6qu7s7Tz/9dPbYY49UVFTs6O0AAAAAAAAAAAA7WFEUef7559PQ0JDKys2/D0soazOefvrpNDY27uhtAAAAAAAAAAAAO5knnngi+++//2bnhbI2Y4899kjyxx9gdXX1Dt4NAAAAAAAAAACwo3V1daWxsbGULdocoazN2PCVhdXV1UJZAAAAAAAAAABAyYZs0eZs/osNAQAAAAAAAAAA2GbbJZR1zTXX5MADD8yAAQPS1NSUe++9d4v1N998c4YMGZIBAwZk6NChue2223rMf/CDH0xFRUWP66STTupRs2LFikyYMCHV1dWpra3NxIkT88ILL5T9bAAAAAAAAAAAAH+u10NZN910U6ZNm5ZLLrkkCxYsyFFHHZXW1tYsX758k/X33HNPxo8fn4kTJ+aBBx7ImDFjMmbMmCxatKhH3UknnZRnnnmmdH3ve9/rMT9hwoQ8+OCDaWtry6xZs3LXXXdl0qRJvXZOAAAAAAAAAACAJKkoiqLozQc0NTXl2GOPzdVXX50k6e7uTmNjY84666xceOGFG9WfcsopWbVqVWbNmlUaO+644zJs2LDMnDkzyR/flLVy5crccsstm3zm4sWLc/jhh+e+++7LiBEjkiSzZ8/OySefnCeffDINDQ0b3bN69eqsXr269LmrqyuNjY3p7OxMdXX1X31+AAAAAAAAAADgtaGrqys1NTWvmCnq1TdlrVmzJvPnz09LS8ufHlhZmZaWlrS3t2/ynvb29h71SdLa2rpR/R133JFBgwbl0EMPzZlnnpnf//73Pdaora0tBbKSpKWlJZWVlZk3b94mnztjxozU1NSUrsbGxm0+LwAAAAAAAAAAQK+Gsp577rmsX78+dXV1Pcbr6urS0dGxyXs6Ojpesf6kk07Kd77zncyZMyeXXXZZ7rzzzrzjHe/I+vXrS2sMGjSoxxp9+/bNwIEDN/vc6dOnp7Ozs3Q98cQT23xeAAAAAAAAAACAvjt6A3+NcePGlf48dOjQvOlNb8ob3/jG3HHHHRk1atRftWZVVVWqqqrKtUUAAAAAAAAAAOB1qlfflLX33nunT58+WbZsWY/xZcuWpb6+fpP31NfXb1N9khx00EHZe++987//+7+lNZYvX96jZt26dVmxYsUW1wEAAAAAAAAAAPhb9Wooq3///hk+fHjmzJlTGuvu7s6cOXPS3Ny8yXuam5t71CdJW1vbZuuT5Mknn8zvf//77LvvvqU1Vq5cmfnz55dq5s6dm+7u7jQ1Nf0tRwIAAAAAAAAAANiiXg1lJcm0adPyjW98I9/+9rezePHinHnmmVm1alVOP/30JMmpp56a6dOnl+rPPvvszJ49O1deeWUefvjhfPrTn87999+fKVOmJEleeOGFnHfeefnlL3+Zxx57LHPmzMm73vWuHHzwwWltbU2SHHbYYTnppJNyxhln5N57780vfvGLTJkyJePGjUtDQ0NvHxkAAAAAAAAAAHgd69vbDzjllFPy7LPP5uKLL05HR0eGDRuW2bNnp66uLkmydOnSVFb+KRt2/PHH54YbbsinPvWpfPKTn8whhxySW265JUceeWSSpE+fPvn1r3+db3/721m5cmUaGhpy4okn5rOf/WyqqqpK61x//fWZMmVKRo0alcrKyowdOzZXXXVVbx8XAAAAAAAAAAB4nasoiqLY0ZvYGXV1daWmpiadnZ2prq7e0dsBAAAAAAAAAAB2sK3NFPX61xcCAAAAAAAAAAC8nghlAQAAAAAAAAAAlJFQFgAAAAAAAAAAQBkJZQEAAAAAAAAAAJSRUBYAAAAAAAAAAEAZCWUBAAAAAAAAAACUkVAWAAAAAAAAAABAGQllAQAAAAAAAAAAlJFQFgAAAAAAAAAAQBkJZQEAAAAAAAAAAJSRUBYAAAAAAAAAAEAZCWUBAAAAAAAAAACUkVAWAAAAAAAAAABAGQllAQAAAAAAAAAAlJFQFgAAAAAAAAAAQBkJZQEAAAAAAAAAAJSRUBYAAAAAAAAAAEAZCWUBAAAAAAAAAACUkVAWAAAAAAAAAABAGQllAQAAAAAAAAAAlJFQFgAAAAAAAAAAQBkJZQEAAAAAAAAAAJSRUBYAAAAAAAAAAEAZCWUBAAAAAAAAAACU0XYJZV1zzTU58MADM2DAgDQ1NeXee+/dYv3NN9+cIUOGZMCAARk6dGhuu+220tzatWtzwQUXZOjQodltt93S0NCQU089NU8//XSPNQ488MBUVFT0uC699NJeOR8AAAAAAAAAAMAGvR7KuummmzJt2rRccsklWbBgQY466qi0trZm+fLlm6y/5557Mn78+EycODEPPPBAxowZkzFjxmTRokVJkhdffDELFizIRRddlAULFuSHP/xhlixZkne+850brfWZz3wmzzzzTOk666yzevWsAAAAAAAAAAAAFUVRFL35gKamphx77LG5+uqrkyTd3d1pbGzMWWedlQsvvHCj+lNOOSWrVq3KrFmzSmPHHXdchg0blpkzZ27yGffdd19GjhyZxx9/PAcccECSP74pa+rUqZk6depW7XP16tVZvXp16XNXV1caGxvT2dmZ6urqrT0uAAAAAAAAAADwGtXV1ZWamppXzBT16puy1qxZk/nz56elpeVPD6ysTEtLS9rb2zd5T3t7e4/6JGltbd1sfZJ0dnamoqIitbW1PcYvvfTS7LXXXjn66KNzxRVXZN26dZtdY8aMGampqSldjY2NW3FCAAAAAAAAAACAnvr25uLPPfdc1q9fn7q6uh7jdXV1efjhhzd5T0dHxybrOzo6Nln/8ssv54ILLsj48eN7pM8+/vGP55hjjsnAgQNzzz33ZPr06XnmmWfyhS98YZPrTJ8+PdOmTSt93vCmLAAAAAAAAAAAgG3Rq6Gs3rZ27dq8733vS1EUufbaa3vM/XnA6k1velP69++fj3zkI5kxY0aqqqo2WquqqmqT4wAAAAAAAAAAANuiV7++cO+9906fPn2ybNmyHuPLli1LfX39Ju+pr6/fqvoNgazHH388bW1tW/yOxiRpamrKunXr8thjj237QQAAAAAAAAAAALZSr4ay+vfvn+HDh2fOnDmlse7u7syZMyfNzc2bvKe5ublHfZK0tbX1qN8QyHrkkUfy85//PHvttdcr7mXhwoWprKzMoEGD/srTAAAAAAAAAAAAvLJe//rCadOm5bTTTsuIESMycuTIfOlLX8qqVaty+umnJ0lOPfXU7LfffpkxY0aS5Oyzz85b3/rWXHnllRk9enRuvPHG3H///fn617+e5I+BrPe+971ZsGBBZs2alfXr16ejoyNJMnDgwPTv3z/t7e2ZN29eTjjhhOyxxx5pb2/POeeck/e///3Zc889e/vIAAAAAAAAAADA61ivh7JOOeWUPPvss7n44ovT0dGRYcOGZfbs2amrq0uSLF26NJWVf3ph1/HHH58bbrghn/rUp/LJT34yhxxySG655ZYceeSRSZKnnnoqP/7xj5Mkw4YN6/Gs22+/PW9729tSVVWVG2+8MZ/+9KezevXqDB48OOecc06mTZvW28cFAAAAAAAAAABe5yqKoih29CZ2Rl1dXampqUlnZ2eqq6t39HYAAAAAAAAAAIAdbGszRZWbnQEAAAAAAAAAAGCbCWUBAAAAAAAAAACUkVAWAAAAAAAAAABAGQllAQAAAAAAAAAAlJFQFgAAAAAAAAAAQBkJZQEAAAAAAAAAAJSRUBYAAAAAAAAAAEAZCWUBAAAAAAAAAACUkVAWAAAAAAAAAABAGQllAQAAAAAAAAAAlJFQFgAAAAAAAAAAQBkJZQEAAAAAAAAAAJSRUBYAAAAAAAAAAEAZCWUBAAAAAAAAAACUkVAWAAAAAAAAAABAGQllAQAAAAAAAAAAlJFQFgAAAAAAAAAAQBkJZQEAAAAAAAAAAJSRUBYAAAAAAAAAAEAZCWUBAAAAAAAAAACUkVAWAAAAAAAAAABAGQllAQAAAAAAAAAAlJFQFgAAAAAAAAAAQBkJZQEAAAAAAAAAAJTRdgllXXPNNTnwwAMzYMCANDU15d57791i/c0335whQ4ZkwIABGTp0aG677bYe80VR5OKLL86+++6bXXbZJS0tLXnkkUd61KxYsSITJkxIdXV1amtrM3HixLzwwgtlPxsAAAAAAAAAAMCf6/VQ1k033ZRp06blkksuyYIFC3LUUUeltbU1y5cv32T9Pffck/Hjx2fixIl54IEHMmbMmIwZMyaLFi0q1Vx++eW56qqrMnPmzMybNy+77bZbWltb8/LLL5dqJkyYkAcffDBtbW2ZNWtW7rrrrkyaNKm3jwsAAAAAAAAAALzOVRRFUfTmA5qamnLsscfm6quvTpJ0d3ensbExZ511Vi688MKN6k855ZSsWrUqs2bNKo0dd9xxGTZsWGbOnJmiKNLQ0JBzzz03n/jEJ5IknZ2dqaury3XXXZdx48Zl8eLFOfzww3PfffdlxIgRSZLZs2fn5JNPzpNPPpmGhoaNnrt69eqsXr269LmrqyuNjY3p7OxMdXV1WX8mlMdVcx7JXb99dkdvAwAAAAAAAACgbP6/045Nza79dvQ22Iyurq7U1NS8Yqaob29uYs2aNZk/f36mT59eGqusrExLS0va29s3eU97e3umTZvWY6y1tTW33HJLkuTRRx9NR0dHWlpaSvM1NTVpampKe3t7xo0bl/b29tTW1pYCWUnS0tKSysrKzJs3L+9+97s3eu6MGTPyr//6r3/LcdnOHn1uVe5//A87ehsAAAAAAAAAAGWzrrt7R2+BMujVUNZzzz2X9evXp66ursd4XV1dHn744U3e09HRscn6jo6O0vyGsS3VDBo0qMd83759M3DgwFLNX5o+fXqPMNiGN2Wx8/rg8Qem9Yi6Vy4EAAAAAAAAAHiV2H1Ar8Z52E78X/x/qqqqUlVVtaO3wTY4qrE2RzXW7uhtAAAAAAAAAABAD5W9ufjee++dPn36ZNmyZT3Gly1blvr6+k3eU19fv8X6Df99pZrly5f3mF+3bl1WrFix2ecCAAAAAAAAAACUQ6+Gsvr375/hw4dnzpw5pbHu7u7MmTMnzc3Nm7ynubm5R32StLW1leoHDx6c+vr6HjVdXV2ZN29eqaa5uTkrV67M/PnzSzVz585Nd3d3mpqaynY+AAAAAAAAAACAv9TrX184bdq0nHbaaRkxYkRGjhyZL33pS1m1alVOP/30JMmpp56a/fbbLzNmzEiSnH322XnrW9+aK6+8MqNHj86NN96Y+++/P1//+teTJBUVFZk6dWr+7d/+LYccckgGDx6ciy66KA0NDRkzZkyS5LDDDstJJ52UM844IzNnzszatWszZcqUjBs3Lg0NDb19ZAAAAAAAAAAA4HWs10NZp5xySp599tlcfPHF6ejoyLBhwzJ79uzU1dUlSZYuXZrKyj+9sOv444/PDTfckE996lP55Cc/mUMOOSS33HJLjjzyyFLN+eefn1WrVmXSpElZuXJl3vKWt2T27NkZMGBAqeb666/PlClTMmrUqFRWVmbs2LG56qqrevu4AAAAAAAAAADA61xFURTFjt7Ezqirqys1NTXp7OxMdXX1jt4OAAAAAAAAAACwg21tpqhyszMAAAAAAAAAAABsM6EsAAAAAAAAAACAMhLKAgAAAAAAAAAAKCOhLAAAAAAAAAAAgDISygIAAAAAAAAAACgjoSwAAAAAAAAAAIAyEsoCAAAAAAAAAAAoI6EsAAAAAAAAAACAMhLKAgAAAAAAAAAAKCOhLAAAAAAAAAAAgDISygIAAAAAAAAAACgjoSwAAAAAAAAAAIAyEsoCAAAAAAAAAAAoI6EsAAAAAAAAAACAMhLKAgAAAAAAAAAAKCOhLAAAAAAAAAAAgDISygIAAAAAAAAAACgjoSwAAAAAAAAAAIAyEsoCAAAAAAAAAAAoI6EsAAAAAAAAAACAMhLKAgAAAAAAAAAAKCOhLAAAAAAAAAAAgDISygIAAAAAAAAAACgjoSwAAAAAAAAAAIAy6rVQ1ooVKzJhwoRUV1entrY2EydOzAsvvLDFe15++eVMnjw5e+21V3bfffeMHTs2y5YtK83/6le/yvjx49PY2Jhddtklhx12WL785S/3WOOOO+5IRUXFRldHR0evnBMAAAAAAAAAAODP9e2thSdMmJBnnnkmbW1tWbt2bU4//fRMmjQpN9xww2bvOeecc3Lrrbfm5ptvTk1NTaZMmZL3vOc9+cUvfpEkmT9/fgYNGpTvfve7aWxszD333JNJkyalT58+mTJlSo+1lixZkurq6tLnQYMG9c5BAQAAAAAAAAAA/kxFURRFuRddvHhxDj/88Nx3330ZMWJEkmT27Nk5+eST8+STT6ahoWGjezo7O7PPPvvkhhtuyHvf+94kycMPP5zDDjss7e3tOe644zb5rMmTJ2fx4sWZO3dukj++KeuEE07IH/7wh9TW1m71nlevXp3Vq1eXPnd1daWxsTGdnZ09wl0AAAAAAAAAAMDrU1dXV2pqal4xU9QrX1/Y3t6e2traUiArSVpaWlJZWZl58+Zt8p758+dn7dq1aWlpKY0NGTIkBxxwQNrb2zf7rM7OzgwcOHCj8WHDhmXffffNP/7jP5betLUlM2bMSE1NTelqbGx8xXsAAAAAAAAAAAD+Uq+Esjo6Ojb6usC+fftm4MCB6ejo2Ow9/fv33+jtVnV1dZu955577slNN92USZMmlcb23XffzJw5Mz/4wQ/ygx/8II2NjXnb296WBQsWbHHP06dPT2dnZ+l64okntuKkAAAAAAAAAAAAPfXdluILL7wwl1122RZrFi9e/DdtaGstWrQo73rXu3LJJZfkxBNPLI0feuihOfTQQ0ufjz/++Pzf//1fvvjFL+Y///M/N7teVVVVqqqqenXPAAAAAAAAAADAa982hbLOPffcfPCDH9xizUEHHZT6+vosX768x/i6deuyYsWK1NfXb/K++vr6rFmzJitXruzxtqxly5ZtdM9DDz2UUaNGZdKkSfnUpz71ivseOXJk7r777lesAwAAAAAAAAAA+FttUyhrn332yT777POKdc3NzVm5cmXmz5+f4cOHJ0nmzp2b7u7uNDU1bfKe4cOHp1+/fpkzZ07Gjh2bJFmyZEmWLl2a5ubmUt2DDz6Yt7/97TnttNPyuc99bqv2vXDhwuy7775bVQsAAAAAAAAAAPC32KZQ1tY67LDDctJJJ+WMM87IzJkzs3bt2kyZMiXjxo1LQ0NDkuSpp57KqFGj8p3vfCcjR45MTU1NJk6cmGnTpmXgwIGprq7OWWedlebm5hx33HFJ/viVhW9/+9vT2tqaadOmpaOjI0nSp0+fUljsS1/6UgYPHpwjjjgiL7/8cr75zW9m7ty5+Z//+Z/eOCoAAAAAAAAAAEAPvRLKSpLrr78+U6ZMyahRo1JZWZmxY8fmqquuKs2vXbs2S5YsyYsvvlga++IXv1iqXb16dVpbW/PVr361NP9f//VfefbZZ/Pd73433/3ud0vjb3jDG/LYY48lSdasWZNzzz03Tz31VHbddde86U1vys9//vOccMIJvXVUAAAAAAAAAACAkoqiKIodvYmdUVdXV2pqatLZ2Znq6uodvR0AAAAAAAAAAGAH29pMUeV23BMAAAAAAAAAAMBrnlAWAAAAAAAAAABAGQllAQAAAAAAAAAAlJFQFgAAAAAAAAAAQBkJZQEAAAAAAAAAAJSRUBYAAAAAAAAAAEAZCWUBAAAAAAAAAACUkVAWAAAAAAAAAABAGQllAQAAAAAAAAAAlJFQFgAAAAAAAAAAQBkJZQEAAAAAAAAAAJSRUBYAAAAAAAAAAEAZCWUBAAAAAAAAAACUkVAWAAAAAAAAAABAGQllAQAAAAAAAAAAlJFQFgAAAAAAAAAAQBkJZQEAAAAAAAAAAJSRUBYAAAAAAAAAAEAZCWUBAAAAAAAAAACUkVAWAAAAAAAAAABAGQllAQAAAAAAAAAAlJFQFgAAAAAAAAAAQBkJZQEAAAAAAAAAAJSRUBYAAAAAAAAAAEAZ9Vooa8WKFZkwYUKqq6tTW1ubiRMn5oUXXtjiPS+//HImT56cvfbaK7vvvnvGjh2bZcuW9aipqKjY6Lrxxht71Nxxxx055phjUlVVlYMPPjjXXXdduY8HAAAAAAAAAACwSb0WypowYUIefPDBtLW1ZdasWbnrrrsyadKkLd5zzjnn5Cc/+Uluvvnm3HnnnXn66afznve8Z6O6b33rW3nmmWdK15gxY0pzjz76aEaPHp0TTjghCxcuzNSpU/PhD384P/vZz8p9RAAAAAAAAAAAgI1UFEVRlHvRxYsX5/DDD899992XESNGJElmz56dk08+OU8++WQaGho2uqezszP77LNPbrjhhrz3ve9Nkjz88MM57LDD0t7enuOOO+6PG66oyI9+9KMeQaw/d8EFF+TWW2/NokWLSmPjxo3LypUrM3v27M3uefXq1Vm9enXpc1dXVxobG9PZ2Znq6upt/hkAAAAAAAAAAACvLV1dXampqXnFTFGvvCmrvb09tbW1pUBWkrS0tKSysjLz5s3b5D3z58/P2rVr09LSUhobMmRIDjjggLS3t/eonTx5cvbee++MHDky//Ef/5E/z5W1t7f3WCNJWltbN1rjL82YMSM1NTWlq7GxcavPCwAAAAAAAAAAsEGvhLI6OjoyaNCgHmN9+/bNwIED09HRsdl7+vfvn9ra2h7jdXV1Pe75zGc+k+9///tpa2vL2LFj87GPfSxf+cpXeqxTV1e30RpdXV156aWXNrvn6dOnp7Ozs3Q98cQTW3tcAAAAAAAAAACAkr7bUnzhhRfmsssu22LN4sWL/6YNvZKLLrqo9Oejjz46q1atyhVXXJGPf/zjf9O6VVVVqaqq+lu3BwAAAAAAAAAAvM5tUyjr3HPPzQc/+MEt1hx00EGpr6/P8uXLe4yvW7cuK1asSH19/Sbvq6+vz5o1a7Jy5coeb8tatmzZZu9Jkqampnz2s5/N6tWrU1VVlfr6+ixbtqxHzbJly1JdXZ1ddtllywcEAAAAAAAAAAD4G21TKGufffbJPvvs84p1zc3NWblyZebPn5/hw4cnSebOnZvu7u40NTVt8p7hw4enX79+mTNnTsaOHZskWbJkSZYuXZrm5ubNPmvhwoXZc889S2+5am5uzm233dajpq2tbYtrAAAAAAAAAAAAlMs2hbK21mGHHZaTTjopZ5xxRmbOnJm1a9dmypQpGTduXBoaGpIkTz31VEaNGpXvfOc7GTlyZGpqajJx4sRMmzYtAwcOTHV1dc4666w0NzfnuOOOS5L85Cc/ybJly3LcccdlwIABaWtry+c///l84hOfKD37ox/9aK6++uqcf/75+dCHPpS5c+fm+9//fm699dbeOCoAAAAAAAAAAEAPvRLKSpLrr78+U6ZMyahRo1JZWZmxY8fmqquuKs2vXbs2S5YsyYsvvlga++IXv1iqXb16dVpbW/PVr361NN+vX79cc801Oeecc1IURQ4++OB84QtfyBlnnFGqGTx4cG699dacc845+fKXv5z9998/3/zmN9Pa2rpN+y+KIknS1dX11/4IAAAAAAAAAACA15ANWaIN2aLNqSheqeJ16sknn0xjY+OO3gYAAAAAAAAAALCTeeKJJ7L//vtvdl4oazO6u7vz9NNPZ4899khFRcWO3g6b0NXVlcbGxjzxxBOprq7e0dsBeM3TdwG2Hz0XYPvSdwG2Hz0XYPvSdwG2Hz339aMoijz//PNpaGhIZWXlZut67esLX+0qKyu3mGZj51FdXa2hAWxH+i7A9qPnAmxf+i7A9qPnAmxf+i7A9qPnvj7U1NS8Ys3m41oAAAAAAAAAAABsM6EsAAAAAAAAAACAMhLK4lWrqqoql1xySaqqqnb0VgBeF/RdgO1HzwXYvvRdgO1HzwXYvvRdgO1Hz+UvVRRFUezoTQAAAAAAAAAAALxWeFMWAAAAAAAAAABAGQllAQAAAAAAAAAAlJFQFgAAAAAAAAAAQBkJZQEAAAAAAAAAAJSRUBYAAAAAAAAAAEAZCWXxqnXNNdfkwAMPzIABA9LU1JR77713R28JYKcyY8aMHHvssdljjz0yaNCgjBkzJkuWLOlR8/LLL2fy5MnZa6+9svvuu2fs2LFZtmxZj5qlS5dm9OjR2XXXXTNo0KCcd955WbduXY+aO+64I8ccc0yqqqpy8MEH57rrrttoP/o28Hpy6aWXpqKiIlOnTi2N6bkA5fXUU0/l/e9/f/baa6/ssssuGTp0aO6///7SfFEUufjii7Pvvvtml112SUtLSx555JEea6xYsSITJkxIdXV1amtrM3HixLzwwgs9an7961/n7//+7zNgwIA0Njbm8ssv32gvN998c4YMGZIBAwZk6NChue2223rn0AA7wPr163PRRRdl8ODB2WWXXfLGN74xn/3sZ1MURalGzwX469111135p3/6pzQ0NKSioiK33HJLj/mdqcduzV4AdmZb6rlr167NBRdckKFDh2a33XZLQ0NDTj311Dz99NM91tBz2RZCWbwq3XTTTZk2bVouueSSLFiwIEcddVRaW1uzfPnyHb01gJ3GnXfemcmTJ+eXv/xl2trasnbt2px44olZtWpVqeacc87JT37yk9x8882588478/TTT+c973lPaX79+vUZPXp01qxZk3vuuSff/va3c9111+Xiiy8u1Tz66KMZPXp0TjjhhCxcuDBTp07Nhz/84fzsZz8r1ejbwOvJfffdl6997Wt505ve1GNczwUonz/84Q9585vfnH79+uWnP/1pHnrooVx55ZXZc889SzWXX355rrrqqsycOTPz5s3LbrvtltbW1rz88sulmgkTJuTBBx9MW1tbZs2albvuuiuTJk0qzXd1deXEE0/MG97whsyfPz9XXHFFPv3pT+frX/96qeaee+7J+PHjM3HixDzwwAMZM2ZMxowZk0WLFm2fHwZAL7vsssty7bXX5uqrr87ixYtz2WWX5fLLL89XvvKVUo2eC/DXW7VqVY466qhcc801m5zfmXrs1uwFYGe2pZ774osvZsGCBbnooouyYMGC/PCHP8ySJUvyzne+s0ednss2KeBVaOTIkcXkyZNLn9evX180NDQUM2bM2IG7Ati5LV++vEhS3HnnnUVRFMXKlSuLfv36FTfffHOpZvHixUWSor29vSiKorjtttuKysrKoqOjo1Rz7bXXFtXV1cXq1auLoiiK888/vzjiiCN6POuUU04pWltbS5/1beD14vnnny8OOeSQoq2trXjrW99anH322UVR6LkA5XbBBRcUb3nLWzY7393dXdTX1xdXXHFFaWzlypVFVVVV8b3vfa8oiqJ46KGHiiTFfffdV6r56U9/WlRUVBRPPfVUURRF8dWvfrXYc889S314w7MPPfTQ0uf3ve99xejRo3s8v6mpqfjIRz7ytx0SYCcxevTo4kMf+lCPsfe85z3FhAkTiqLQcwHKKUnxox/9qPR5Z+qxW7MXgFeTv+y5m3LvvfcWSYrHH3+8KAo9l23nTVm86qxZsybz589PS0tLaayysjItLS1pb2/fgTsD2Ll1dnYmSQYOHJgkmT9/ftauXdujnw4ZMiQHHHBAqZ+2t7dn6NChqaurK9W0tramq6srDz74YKnmz9fYULNhDX0beD2ZPHlyRo8evVFf1HMByuvHP/5xRowYkX/+53/OoEGDcvTRR+cb3/hGaf7RRx9NR0dHj35YU1OTpqamHn23trY2I0aMKNW0tLSksrIy8+bNK9X8wz/8Q/r371+qaW1tzZIlS/KHP/yhVLOl3gzwanf88cdnzpw5+e1vf5sk+dWvfpW7774773jHO5LouQC9aWfqsVuzF4DXms7OzlRUVKS2tjaJnsu2E8riVee5557L+vXre/yyKknq6urS0dGxg3YFsHPr7u7O1KlT8+Y3vzlHHnlkkqSjoyP9+/cv/UVygz/vpx0dHZvstxvmtlTT1dWVl156Sd8GXjduvPHGLFiwIDNmzNhoTs8FKK/f/e53ufbaa3PIIYfkZz/7Wc4888x8/OMfz7e//e0kf+qbW+qHHR0dGTRoUI/5vn37ZuDAgWXpzfou8Fpx4YUXZty4cRkyZEj69euXo48+OlOnTs2ECROS6LkAvWln6rFbsxeA15KXX345F1xwQcaPH5/q6uokei7bru+O3gAA0PsmT56cRYsW5e67797RWwF4TXriiSdy9tlnp62tLQMGDNjR2wF4zevu7s6IESPy+c9/Pkly9NFHZ9GiRZk5c2ZOO+20Hbw7gNeW73//+7n++utzww035IgjjsjChQszderUNDQ06LkAALwmrV27Nu973/tSFEWuvfbaHb0dXsW8KYtXnb333jt9+vTJsmXLeowvW7Ys9fX1O2hXADuvKVOmZNasWbn99tuz//77l8br6+uzZs2arFy5skf9n/fT+vr6TfbbDXNbqqmurs4uu+yibwOvC/Pnz8/y5ctzzDHHpG/fvunbt2/uvPPOXHXVVenbt2/q6ur0XIAy2nfffXP44Yf3GDvssMOydOnSJH/qm1vqh/X19Vm+fHmP+XXr1mXFihVl6c36LvBacd5555XeljV06NB84AMfyDnnnFN6Q6yeC9B7dqYeuzV7AXgt2BDIevzxx9PW1lZ6S1ai57LthLJ41enfv3+GDx+eOXPmlMa6u7szZ86cNDc378CdAexciqLIlClT8qMf/Shz587N4MGDe8wPHz48/fr169FPlyxZkqVLl5b6aXNzc37zm9/0+Avmhr+AbvglWHNzc481NtRsWEPfBl4PRo0ald/85jdZuHBh6RoxYkQmTJhQ+rOeC1A+b37zm7NkyZIeY7/97W/zhje8IUkyePDg1NfX9+iHXV1dmTdvXo++u3LlysyfP79UM3fu3HR3d6epqalUc9ddd2Xt2rWlmra2thx66KHZc889SzVb6s0Ar3YvvvhiKit7/iqhT58+6e7uTqLnAvSmnanHbs1eAF7tNgSyHnnkkfz85z/PXnvt1WNez2WbFfAqdOONNxZVVVXFddddVzz00EPFpEmTitra2qKjo2NHbw1gp3HmmWcWNTU1xR133FE888wzpevFF18s1Xz0ox8tDjjggGLu3LnF/fffXzQ3NxfNzc2l+XXr1hVHHnlkceKJJxYLFy4sZs+eXeyzzz7F9OnTSzW/+93vil133bU477zzisWLFxfXXHNN0adPn2L27NmlGn0beD1661vfWpx99tmlz3ouQPnce++9Rd++fYvPfe5zxSOPPFJcf/31xa677lp897vfLdVceumlRW1tbfHf//3fxa9//eviXe96VzF48ODipZdeKtWcdNJJxdFHH13MmzevuPvuu4tDDjmkGD9+fGl+5cqVRV1dXfGBD3ygWLRoUXHjjTcWu+66a/G1r32tVPOLX/yi6Nu3b/Hv//7vxeLFi4tLLrmk6NevX/Gb3/xm+/wwAHrZaaedVuy3337FrFmzikcffbT44Q9/WOy9997F+eefX6rRcwH+es8//3zxwAMPFA888ECRpPjCF75QPPDAA8Xjjz9eFMXO1WO3Zi8AO7Mt9dw1a9YU73znO4v999+/WLhwYY/fra1evbq0hp7LthDK4lXrK1/5SnHAAQcU/fv3L0aOHFn88pe/3NFbAtipJNnk9a1vfatU89JLLxUf+9jHij333LPYddddi3e/+93FM88802Odxx57rHjHO95R7LLLLsXee+9dnHvuucXatWt71Nx+++3FsGHDiv79+xcHHXRQj2dsoG8Drzd/GcrScwHK6yc/+Ulx5JFHFlVVVcWQIUOKr3/96z3mu7u7i4suuqioq6srqqqqilGjRhVLlizpUfP73/++GD9+fLH77rsX1dXVxemnn148//zzPWp+9atfFW95y1uKqqqqYr/99isuvfTSjfby/e9/v/i7v/u7on///sURRxxR3HrrreU/MMAO0tXVVZx99tnFAQccUAwYMKA46KCDin/5l3/p8YspPRfgr3f77bdv8t9xTzvttKIodq4euzV7AdiZbannPvroo5v93drtt99eWkPPZVtUFEVRbL/3cgEAAAAAAAAAALy2Vb5yCQAAAAAAAAAAAFtLKAsAAAAAAAAAAKCMhLIAAAAAAAAAAADKSCgLAAAAAAAAAACgjISyAAAAAAAAAAAAykgoCwAAAAAAAAAAoIyEsgAAAAAAAAAAAMpIKAsAAAAAAAAAAKCMhLIAAAAAAAAAAADKSCgLAAAAAAAAAACgjISyAAAAAAAAAAAAyuj/B7mjexRE2hbCAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# plt.rcParams['figure.figsize'] = 30, 2\n", + "plt.plot(test_dropped.to_numpy()[:, 7])" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.preprocessing import MinMaxScaler\n", + "\n", + "def scale_data(train, test, validation):\n", + " scaler = MinMaxScaler(feature_range=(0, 1), clip=True).fit(train)\n", + "\n", + " train_scaled = scaler.transform(train)\n", + " test_scaled = scaler.transform(test)\n", + " validation_scaled = scaler.transform(validation)\n", + "\n", + " # train_scaled = scaler.fit_transform(train)\n", + " # validation_scaled = scaler.fit_transform(validation)\n", + " # test_scaled = scaler.fit_transform(test)\n", + "\n", + " return train_scaled, test_scaled, validation_scaled" + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "metadata": {}, + "outputs": [], + "source": [ + "train_values = train_dropped.values\n", + "test_values = test_dropped.values\n", + "validation_values = validation_dropped.values" + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "metadata": {}, + "outputs": [], + "source": [ + "train_norm, test_norm, val_norm = scale_data(train_values, test_values, validation_values)" + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(784571, 123)" + ] + }, + "execution_count": 110, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train_norm.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(146883, 123)" + ] + }, + "execution_count": 111, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "labels_reshaped = np.zeros_like(test_values)\n", + "labels_reshaped.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(25920,)" + ] + }, + "execution_count": 112, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "validation_labels.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": {}, + "outputs": [], + "source": [ + "for idx in range(0, len(test_labels_clipped)):\n", + " if test_labels_clipped[idx]:\n", + " # labels_reshaped.shape[1] == 51 aka num_feats\n", + " labels_reshaped[idx][0:labels_reshaped.shape[1]] = 1" + ] + }, + { + "cell_type": "code", + "execution_count": 114, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(25920, 123)" + ] + }, + "execution_count": 114, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "validation_labels_reshaped = np.zeros_like(validation_values)\n", + "validation_labels_reshaped.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": {}, + "outputs": [], + "source": [ + "for idx in range(0, len(validation_labels)):\n", + " if validation_labels[idx]:\n", + " # labels_reshaped.shape[1] == 51 aka num_feats\n", + " validation_labels_reshaped[idx][0:validation_labels_reshaped.shape[1]] = 1" + ] + }, + { + "cell_type": "code", + "execution_count": 119, + "metadata": {}, + "outputs": [], + "source": [ + "np.save('labels.npy', labels_reshaped)\n", + "np.save('labels_validation.npy', validation_labels_reshaped)\n", + "np.save('train.npy', train_norm)\n", + "np.save('test.npy', test_norm)\n", + "np.save('validation.npy', val_norm)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "val = np.load('../processed/WADI/validation.npy')\n", + "test = np.load('../processed/WADI/test.npy')\n", + "validation_labels = np.load('../processed/WADI/labels_validation.npy')\n", + "test_labels = np.load('../processed/WADI/labels.npy')" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(146883, 123)" + ] + }, + "execution_count": 80, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "validation_labels = (np.sum(validation_labels, axis=1) >= 1) + 0\n", + "test_labels = (np.sum(test_labels, axis=1) >= 1) + 0" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "plt.rcParams['figure.figsize'] = 30, 2" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAACVEAAADFCAYAAABXNSDmAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAACr5UlEQVR4nOz9eXxjZ302/l9H+2JJlnd7xrPvk5lJMkkmk4SENEMmkELCDi2lpIU+pU1bmv6gze9poUD7hNIW6BIKBfIQHloIUMKWkG3IJCGZzCSzZPZ9sT3eN8mSrP18/7glWbIlnVvjY1mSr/fr5Zdt6Ug6sqWjcz7nc1+3oqqqCiIiIiIiIiIiIiIiIiIiIiIiogXKMN8rQERERERERERERERERERERERENJ/YREVERERERERERERERERERERERAsam6iIiIiIiIiIiIiIiIiIiIiIiGhBYxMVEREREREREREREREREREREREtaGyiIiIiIiIiIiIiIiIiIiIiIiKiBY1NVEREREREREREREREREREREREtKCxiYqIiIiIiIiIiIiIiIiIiIiIiBY003yvgB6SySR6e3vhcrmgKMp8rw4REREREREREREREREREREREc0zVVUxMTGBjo4OGAzFs6Zqoomqt7cXnZ2d870aRERERERERERERERERERERERUYbq7u7F48eKiy9REE5XL5QIgnrDb7Z7ntSEiIiIiIiIiIiIiIiIiIiIiovnm9/vR2dmZ6S0qpiaaqNJT+LndbjZRERERERERERERERERERERERFRRrq3qJjik/0RERERERERERERERERERERERHVuJKbqF588UW8/e1vR0dHBxRFwU9+8hPN2+zevRvXXnstrFYrVq1ahW9/+9szlnn44YexbNky2Gw2bNu2Dfv27St11YiIiIiIiIiIiIiIiIiIiIiIiEpWchNVMBjEli1b8PDDD0stf+HCBdx99924/fbbcejQIXziE5/ARz/6UTz99NOZZR577DE88MAD+MxnPoMDBw5gy5Yt2LlzJwYHB0tdPSIiIiIiIiIiIiIiIiIiIiIiopIoqqqqV3xjRcHjjz+Oe++9t+Ayf/mXf4knnngCR48ezVz2gQ98AOPj43jqqacAANu2bcP111+Pf//3fwcAJJNJdHZ24k/+5E/wV3/1VzPuMxKJIBKJZH73+/3o7OyE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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(test[:, 3])\n", + "plt.fill_between(np.arange(test_labels.shape[0]), test_labels, color='red', alpha=0.3, linestyle='dashed', linewidth=0.3)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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y6p4rF+/fjalAQAATDU66ncFqIZUyu8KAAAAAAAAAAAAUKNmHKJ64IEHtHnzZm3btk1PP/201qxZo97eXh05cmTa9rt27dINN9ygRx55RLt371Z3d7euvvpqvf322xXt1q9fr8OHD3uP73//+7PbIwAAgMliMb8rQDW0tcmS5XcVAAAAAAAAAAAAqEEzDlF94xvf0M0336xNmzbpggsu0N133614PK577rln2vb/8i//oj/90z/VJZdcovPPP1//9E//pGKxqL6+vop20WhUnZ2d3qOtre2ENWQyGSWTyYoHAADACRWLfleAahga8rsCAAAAAAAAAAAA1KgZhaiy2az27t2rnp6e0gYCAfX09Gj37t2ntI3x8XHlcjktWrSoYvmuXbu0ZMkSrVq1SrfeeqsGBwdPuI3t27erpaXFe3R3d89kNwAAwEJTKPhdAarhJCF8AAAAAAAAAAAA4GRmFKI6duyYCoWCOjo6KpZ3dHSov7//lLbx+c9/Xl1dXRVBrPXr1+t73/ue+vr69LWvfU2PPvqorrnmGhVO0OG5ZcsWjYyMeI8DBw7MZDcAAMBCE436XQGqgZGoAAAAAAAAAAAAMEuhar7ZnXfeqfvvv1+7du1SLBbzll9//fXe96tXr9bFF1+sc889V7t27dJVV101ZTvRaFRROkMBAMCpGhuTyq49UKdaWiQxdSMAAAAAAAAAAABmbkYjUbW3tysYDGpgYKBi+cDAgDo7O0+67t/8zd/ozjvv1L//+7/r4osvPmnbc845R+3t7XrttddmUh4AAMD0Wlv9rgDVMDrqdwUAAAAAAAAAAACoUTMKUUUiEV122WXq6+vzlhWLRfX19WndunUnXO+uu+7SV7/6Ve3cuVOXX375O77PwYMHNTg4qKVLl86kPAAAgOkND/tdAaqB0cYAAAAAAAAAAAAwSzMKUUnS5s2b9Z3vfEf33XefXnrpJd16661KpVLatGmTJOnGG2/Uli1bvPZf+9rX9KUvfUn33HOPli9frv7+fvX392tsbEySNDY2pttvv11PPPGE3nzzTfX19em6667TypUr1dvbe5p2EwAALGiMRLUw5PN+VwAAAAAAAAAAAIAaFZrpChs3btTRo0e1detW9ff365JLLtHOnTvV0dEhSdq/f78CgVI26+///u+VzWb1h3/4hxXb2bZtm7785S8rGAzqueee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Fa8bY7R161YtXbpUDQ0N6unp0auvvlrR5vjx4/rYxz6mRCKh1tZWfeITn9DY2FhFm+eee05XXnmlYrGYuru7ddddd02p5cEHH9T555+vWCym1atX66c//elp318AQHW80/nl4x//+JS/Z9avX1/RhvMLAKDc9u3b9d73vlfNzc1asmSJNmzYoFdeeaWiTTU/D6PvBgDqw6mcX373d393yt8vn/rUpyracH7BQkeIClXxwAMPaPPmzdq2bZuefvpprVmzRr29vTpy5IjfpQEA5oELL7xQhw8f9h6/+MUvvNc++9nP6t/+7d/04IMP6tFHH9WhQ4f0kY98xHu9UCjo2muvVTab1eOPP6777rtP9957r7Zu3eq12bdvn6699lp9+MMf1rPPPqvbbrtNn/zkJ/Wzn/2sqvsJAJg7qVRKa9as0Y4dO6Z9/a677tK3vvUt3X333dqzZ48aGxvV29urdDrttfnYxz6mF154QQ8//LB+/OMf67HHHtMtt9zivZ5MJnX11Vfr7LPP1t69e/X1r39dX/7yl/WP//iPXpvHH39cN9xwgz7xiU/omWee0YYNG7RhwwY9//zzc7fzAIA5807nF0lav359xd8z3//+9yte5/wCACj36KOP6tOf/rSeeOIJPfzww8rlcrr66quVSqW8NtX6PIy+GwCoH6dyfpGkm2++ueLvl/IbODi/AJIMUAVXXHGF+fSnP+09LxQKpqury2zfvt3HqgAA88G2bdvMmjVrpn1teHjYhMNh8+CDD3rLXnrpJSPJ7N692xhjzE9/+lMTCARMf3+/1+bv//7vTSKRMJlMxhhjzB133GEuvPDCim1v3LjR9Pb2nua9AQDMB5LMD3/4Q+95sVg0nZ2d5utf/7q3bHh42ESjUfP973/fGGPMiy++aCSZX/3qV16b//N//o+xLMu8/fbbxhhjvv3tb5u2tjbv/GKMMZ///OfNqlWrvOcf/ehHzbXXXltRz9q1a82f/MmfnNZ9BABU3+TzizHG3HTTTea666474TqcXwAA7+TIkSNGknn00UeNMdX9PIy+GwCoX5PPL8YY8zu/8zvmz//8z0+4DucXwBhGosKcy2az2rt3r3p6erxlgUBAPT092r17t4+VAQDmi1dffVVdXV0655xz9LGPfUz79++XJO3du1e5XK7iHHL++efrrLPO8s4hu3fv1urVq9XR0eG16e3tVTKZ1AsvvOC1Kd+G24bzEAAsDPv27VN/f3/FuaClpUVr166tOJ+0trbq8ssv99r09PQoEAhoz549XpsPfehDikQiXpve3l698sorGhoa8tpwzgGAhWXXrl1asmSJVq1apVtvvVWDg4Pea5xfAADvZGRkRJK0aNEiSdX7PIy+GwCob5PPL65/+Zd/UXt7uy666CJt2bJF4+Pj3mucXwAp5HcBqH/Hjh1ToVCoONhKUkdHh15++WWfqgIAzBdr167Vvffeq1WrVunw4cP6yle+oiuvvFLPP/+8+vv7FYlE1NraWrFOR0eH+vv7JUn9/f3TnmPc107WJplMamJiQg0NDXO0dwCA+cA9H0x3Lig/VyxZsqTi9VAopEWLFlW0WbFixZRtuK+1tbWd8JzjbgMAUF/Wr1+vj3zkI1qxYoVef/11/eVf/qWuueYa7d69W8FgkPMLAOCkisWibrvtNn3gAx/QRRddJElV+zxsaGiIvhsAqFPTnV8k6b/8l/+is88+W11dXXruuef0+c9/Xq+88or+9V//VRLnF0AiRAUAAHx2zTXXeN9ffPHFWrt2rc4++2z94Ac/INwEAAAAYF67/vrrve9Xr16tiy++WOeee6527dqlq666ysfKAAC14NOf/rSef/55/eIXv/C7FABAHTnR+eWWW27xvl+9erWWLl2qq666Sq+//rrOPffcapcJzEtM54c5197ermAwqIGBgYrlAwMD6uzs9KkqAMB81draqve85z167bXX1NnZqWw2q+Hh4Yo25eeQzs7Oac8x7msna5NIJAhqAcAC4J4PTvY3SWdnp44cOVLxej6f1/Hjx0/LOYe/fQBgYTjnnHPU3t6u1157TRLnFwDAif3Zn/2ZfvzjH+uRRx7RmWee6S2v1udh9N0AQH060fllOmvXrpWkir9fOL9goSNEhTkXiUR02WWXqa+vz1tWLBbV19endevW+VgZAGA+Ghsb0+uvv66lS5fqsssuUzgcrjiHvPLKK9q/f793Dlm3bp1+85vfVHRMPPzww0okErrgggu8NuXbcNtwHgKAhWHFihXq7OysOBckk0nt2bOn4nwyPDysvXv3em1+/vOfq1gseh8orVu3To899phyuZzX5uGHH9aqVavU1tbmteGcAwAL18GDBzU4OKilS5dK4vwCAJjKGKM/+7M/0w9/+EP9/Oc/nzKla7U+D6PvBgDqyzudX6bz7LPPSlLF3y+cX7DgGaAK7r//fhONRs29995rXnzxRXPLLbeY1tZW09/f73dpAACffe5znzO7du0y+/btM7/85S9NT0+PaW9vN0eOHDHGGPOpT33KnHXWWebnP/+5eeqpp8y6devMunXrvPXz+by56KKLzNVXX22effZZs3PnTnPGGWeYLVu2eG3eeOMNE4/Hze23325eeukls2PHDhMMBs3OnTurvr8AgLkxOjpqnnnmGfPMM88YSeYb3/iGeeaZZ8xbb71ljDHmzjvvNK2treZHP/qRee6558x1111nVqxYYSYmJrxtrF+/3vz2b/+22bNnj/nFL35hzjvvPHPDDTd4rw8PD5uOjg7zx3/8x+b55583999/v4nH4+Yf/uEfvDa//OUvTSgUMn/zN39jXnrpJbNt2zYTDofNb37zm+r9MAAAp83Jzi+jo6PmL/7iL8zu3bvNvn37zP/9v//XXHrppea8884z6XTa2wbnFwBAuVtvvdW0tLSYXbt2mcOHD3uP8fFxr021Pg+j7wYA6sc7nV9ee+0181d/9VfmqaeeMvv27TM/+tGPzDnnnGM+9KEPedvg/AIYQ4gKVfPf//t/N2eddZaJRCLmiiuuME888YTfJQEA5oGNGzeapUuXmkgkYpYtW2Y2btxoXnvtNe/1iYkJ86d/+qemra3NxONx85/+038yhw8frtjGm2++aa655hrT0NBg2tvbzec+9zmTy+Uq2jzyyCPmkksuMZFIxJxzzjnmn//5n6uxewCAKnnkkUeMpCmPm266yRhjTLFYNF/60pdMR0eHiUaj5qqrrjKvvPJKxTYGBwfNDTfcYJqamkwikTCbNm0yo6OjFW1+/etfmw9+8IMmGo2aZcuWmTvvvHNKLT/4wQ/Me97zHhOJRMyFF15ofvKTn8zZfgMA5tbJzi/j4+Pm6quvNmeccYYJh8Pm7LPPNjfffPOUjgHOLwCActOdVyRVfFZVzc/D6LsBgPrwTueX/fv3mw996ENm0aJFJhqNmpUrV5rbb7/djIyMVGyH8wsWOssYY6o37hUAAAAAAAAAAAAAAAAAzC8BvwsAAAAAAAAAAAAAAAAAAD8RogIAAAAAAAAAAAAAAACwoBGiAgAAAAAAAAAAAAAAALCgEaICAAAAAAAAAAAAAAAAsKARogIAAAAAAAAAAAAAAACwoBGiAgAAAAAAAAAAAAAAALCgEaICAAAAAAAAAAAAAAAAsKARogIAAAAAAAAAAAAAAACwoBGiAgAAAAAAAAAAAAAAALCgEaICAAAAAAAAAAAAAAAAsKARogIAAAAAAAAAAAAAAACwoP3/ixKvrMcdqXoAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(val[:, 3])\n", + "plt.fill_between(np.arange(validation_labels.shape[0]), validation_labels, color='red', alpha=0.3, linestyle='dashed', linewidth=0.3)" + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3139" + ] + }, + "execution_count": 120, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.sum(validation_labels)" + ] + }, + { + "cell_type": "code", + "execution_count": 121, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "6838" + ] + }, + "execution_count": 121, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.sum(test_labels_clipped)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "test = np.load('../processed/WADI/test.npy')\n", + "train = np.load('../processed/WADI/train.npy')" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(146883, 123)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "test.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(784571, 123)" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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9fWZOnVqnnnmmbKan//85/nbv/3bDBkyJM3NzfnUpz61xV5uvPHGjBgxIkOGDMnIkSNzyy239M2hgX63adOmXHjhhRk+fHh22223vPKVr8zHP/7xFEVRqtF/gEq444478g//8A9pampKVVVVbrrpprL5nanX7MhegJeG7fWeDRs25Pzzz8/IkSPzile8Ik1NTTnttNPy+OOPl62h9wB/ief7u8+fet/73peqqqpcfvnlZeP6D7z4hLJ4Sbrhhhsya9asXHzxxVmyZEmOOeaYtLe3Z9WqVf29NWAndPvtt2f69On56U9/mo6OjmzYsCEnn3xy1q5dW6o555xz8v3vfz833nhjbr/99jz++ON561vfWprftGlTxo8fn/Xr1+fOO+/M1772tVxzzTW56KKLSjUPPvhgxo8fn5NOOilLly7NzJkz8573vCc//OEPSzX6F+y67r777nzxi1/Mq171qrJx/QfoC7/73e/ymte8JoMGDcoPfvCD/PKXv8xnPvOZ7LXXXqWaT33qU7niiisyd+7cLFq0KK94xSvS3t6e5557rlQzZcqU3Hfffeno6Mi8efNyxx13ZNq0aaX5np6enHzyyTnooIOyePHifPrTn85HP/rRfOlLXyrV3HnnnZk8eXKmTp2ae++9NxMmTMiECROybNmyF+eHAbyoLr300lx99dW58sors3z58lx66aX51Kc+lc9//vOlGv0HqIS1a9fmmGOOyVVXXbXV+Z2p1+zIXoCXhu31nmeffTZLlizJhRdemCVLluQ73/lOVqxYkTe96U1ldXoP8Jd4vr/7bPbd7343P/3pT9PU1LTFnP4D/aCAl6CxY8cW06dPL33etGlT0dTUVMyZM6cfdwW8VKxatapIUtx+++1FURTFmjVrikGDBhU33nhjqWb58uVFkqKzs7MoiqK45ZZbiurq6qKrq6tUc/XVVxe1tbXFunXriqIoig996EPFUUcdVfasU089tWhvby991r9g1/T0008Xhx12WNHR0VGceOKJxdlnn10Uhf4D9J3zzz+/eO1rX7vN+d7e3qKxsbH49Kc/XRpbs2ZNUVNTU3zzm98siqIofvnLXxZJirvvvrtU84Mf/KCoqqoqHnvssaIoiuILX/hCsddee5X60eZnH3744aXPb3/724vx48eXPb+lpaV473vf+9cdEtgpjR8/vnj3u99dNvbW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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "plt.rcParams['figure.figsize'] = 30, 2\n", + "plt.plot(test[:, 7])\n", + "#plt.fill_between(np.arange(validation_labels.shape[0]), validation_labels, color='red', alpha=0.3, linestyle='dashed', linewidth=0.3)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "py3.9test", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "27efe6010b91a164a18a011cd71b7afbe2f076e5b83b7f8099f414d97e11e710" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/subject1-4/AdaDiff/denoising_diffusion_pytorch_1d.py b/subject1-4/AdaDiff/denoising_diffusion_pytorch_1d.py new file mode 100644 index 0000000..d310545 --- /dev/null +++ b/subject1-4/AdaDiff/denoising_diffusion_pytorch_1d.py @@ -0,0 +1,829 @@ +import math +from pathlib import Path +from random import random +from functools import partial +from collections import namedtuple +from multiprocessing import cpu_count + +import torch +from torch import nn, einsum, Tensor +import torch.nn.functional as F +from torch.cuda.amp import autocast +from torch.optim import Adam +from torch.utils.data import Dataset, DataLoader + +from einops import rearrange, reduce +from einops.layers.torch import Rearrange + +from accelerate import Accelerator +from ema_pytorch import EMA + +from tqdm.auto import tqdm + + +# constants + +ModelPrediction = namedtuple('ModelPrediction', ['pred_noise', 'pred_x_start']) + +# helpers functions + +def exists(x): + return x is not None + +def default(val, d): + if exists(val): + return val + return d() if callable(d) else d + +def identity(t, *args, **kwargs): + return t + +def cycle(dl): + while True: + for data in dl: + yield data + +def has_int_squareroot(num): + return (math.sqrt(num) ** 2) == num + +def num_to_groups(num, divisor): + groups = num // divisor + remainder = num % divisor + arr = [divisor] * groups + if remainder > 0: + arr.append(remainder) + return arr + +def convert_image_to_fn(img_type, image): + if image.mode != img_type: + return image.convert(img_type) + return image + +# normalization functions + +def normalize_to_neg_one_to_one(img): + return img * 2 - 1 + +def unnormalize_to_zero_to_one(t): + return (t + 1) * 0.5 + +# data + +class Dataset1D(Dataset): + def __init__(self, tensor: Tensor): + super().__init__() + self.tensor = tensor.clone() + + def __len__(self): + return len(self.tensor) + + def __getitem__(self, idx): + return self.tensor[idx].clone() + +# small helper modules + +class Residual(nn.Module): + def __init__(self, fn): + super().__init__() + self.fn = fn + + def forward(self, x, *args, **kwargs): + return self.fn(x, *args, **kwargs) + x + +def Upsample(dim, dim_out = None): + return nn.Sequential( + nn.Upsample(scale_factor = 2, mode = 'nearest'), + nn.Conv1d(dim, default(dim_out, dim), 3, padding = 1) + ) + +def Downsample(dim, dim_out = None): + return nn.Conv1d(dim, default(dim_out, dim), 4, 2, 1) + +class RMSNorm(nn.Module): + def __init__(self, dim): + super().__init__() + self.g = nn.Parameter(torch.ones(1, dim, 1)) + + def forward(self, x): + return F.normalize(x, dim = 1) * self.g * (x.shape[1] ** 0.5) + +class PreNorm(nn.Module): + def __init__(self, dim, fn): + super().__init__() + self.fn = fn + self.norm = RMSNorm(dim) + + def forward(self, x): + x = self.norm(x) + return self.fn(x) + +# sinusoidal positional embeds + +class SinusoidalPosEmb(nn.Module): + def __init__(self, dim, theta = 10000): + super().__init__() + self.dim = dim + self.theta = theta + + def forward(self, x): + device = x.device + half_dim = self.dim // 2 + emb = math.log(self.theta) / (half_dim - 1) + emb = torch.exp(torch.arange(half_dim, device=device) * -emb) + emb = x[:, None] * emb[None, :] + emb = torch.cat((emb.sin(), emb.cos()), dim=-1) + return emb + +class RandomOrLearnedSinusoidalPosEmb(nn.Module): + """ following @crowsonkb 's lead with random (learned optional) sinusoidal pos emb """ + """ https://github.com/crowsonkb/v-diffusion-jax/blob/master/diffusion/models/danbooru_128.py#L8 """ + + def __init__(self, dim, is_random = False): + super().__init__() + assert (dim % 2) == 0 + half_dim = dim // 2 + self.weights = nn.Parameter(torch.randn(half_dim), requires_grad = not is_random) + + def forward(self, x): + x = rearrange(x, 'b -> b 1') + freqs = x * rearrange(self.weights, 'd -> 1 d') * 2 * math.pi + fouriered = torch.cat((freqs.sin(), freqs.cos()), dim = -1) + fouriered = torch.cat((x, fouriered), dim = -1) + return fouriered + +# building block modules + +class Block(nn.Module): + def __init__(self, dim, dim_out, groups = 8): + super().__init__() + self.proj = nn.Conv1d(dim, dim_out, 3, padding = 1) + self.norm = nn.GroupNorm(groups, dim_out) + self.act = nn.SiLU() + + def forward(self, x, scale_shift = None): + x = self.proj(x) + x = self.norm(x) + + if exists(scale_shift): + scale, shift = scale_shift + x = x * (scale + 1) + shift + + x = self.act(x) + return x + +class ResnetBlock(nn.Module): + def __init__(self, dim, dim_out, *, time_emb_dim = None, groups = 8): + super().__init__() + self.mlp = nn.Sequential( + nn.SiLU(), + nn.Linear(time_emb_dim, dim_out * 2) + ) if exists(time_emb_dim) else None + + self.block1 = Block(dim, dim_out, groups = groups) + self.block2 = Block(dim_out, dim_out, groups = groups) + self.res_conv = nn.Conv1d(dim, dim_out, 1) if dim != dim_out else nn.Identity() + + def forward(self, x, time_emb = None): + + scale_shift = None + if exists(self.mlp) and exists(time_emb): + time_emb = self.mlp(time_emb) + time_emb = rearrange(time_emb, 'b c -> b c 1') + scale_shift = time_emb.chunk(2, dim = 1) + + h = self.block1(x, scale_shift = scale_shift) + + h = self.block2(h) + + return h + self.res_conv(x) + +class LinearAttention(nn.Module): + def __init__(self, dim, heads = 4, dim_head = 32): + super().__init__() + self.scale = dim_head ** -0.5 + self.heads = heads + hidden_dim = dim_head * heads + self.to_qkv = nn.Conv1d(dim, hidden_dim * 3, 1, bias = False) + + self.to_out = nn.Sequential( + nn.Conv1d(hidden_dim, dim, 1), + RMSNorm(dim) + ) + + def forward(self, x): + b, c, n = x.shape + qkv = self.to_qkv(x).chunk(3, dim = 1) + q, k, v = map(lambda t: rearrange(t, 'b (h c) n -> b h c n', h = self.heads), qkv) + + q = q.softmax(dim = -2) + k = k.softmax(dim = -1) + + q = q * self.scale + + context = torch.einsum('b h d n, b h e n -> b h d e', k, v) + + out = torch.einsum('b h d e, b h d n -> b h e n', context, q) + out = rearrange(out, 'b h c n -> b (h c) n', h = self.heads) + return self.to_out(out) + +class Attention(nn.Module): + def __init__(self, dim, heads = 4, dim_head = 32): + super().__init__() + self.scale = dim_head ** -0.5 + self.heads = heads + hidden_dim = dim_head * heads + + self.to_qkv = nn.Conv1d(dim, hidden_dim * 3, 1, bias = False) + self.to_out = nn.Conv1d(hidden_dim, dim, 1) + + def forward(self, x): + b, c, n = x.shape + qkv = self.to_qkv(x).chunk(3, dim = 1) + q, k, v = map(lambda t: rearrange(t, 'b (h c) n -> b h c n', h = self.heads), qkv) + + q = q * self.scale + + sim = einsum('b h d i, b h d j -> b h i j', q, k) + attn = sim.softmax(dim = -1) + out = einsum('b h i j, b h d j -> b h i d', attn, v) + + out = rearrange(out, 'b h n d -> b (h d) n') + return self.to_out(out) + +# model + +class Unet1D(nn.Module): + def __init__( + self, + dim, + init_dim = None, + out_dim = None, + dim_mults=(1, 2, 4, 8), + channels = 3, + self_condition = False, + resnet_block_groups = 8, + learned_variance = False, + learned_sinusoidal_cond = False, + random_fourier_features = False, + learned_sinusoidal_dim = 16, + sinusoidal_pos_emb_theta = 10000, + attn_dim_head = 32, + attn_heads = 4 + ): + super().__init__() + + # determine dimensions + + self.channels = channels + self.self_condition = self_condition + input_channels = channels * (2 if self_condition else 1) + + init_dim = default(init_dim, dim) + self.init_conv = nn.Conv1d(input_channels, init_dim, 7, padding = 3) + + dims = [init_dim, *map(lambda m: dim * m, dim_mults)] + in_out = list(zip(dims[:-1], dims[1:])) + + block_klass = partial(ResnetBlock, groups = resnet_block_groups) + + # time embeddings + + time_dim = dim * 4 + + self.random_or_learned_sinusoidal_cond = learned_sinusoidal_cond or random_fourier_features + + if self.random_or_learned_sinusoidal_cond: + sinu_pos_emb = RandomOrLearnedSinusoidalPosEmb(learned_sinusoidal_dim, random_fourier_features) + fourier_dim = learned_sinusoidal_dim + 1 + else: + sinu_pos_emb = SinusoidalPosEmb(dim, theta = sinusoidal_pos_emb_theta) + fourier_dim = dim + + self.time_mlp = nn.Sequential( + sinu_pos_emb, + nn.Linear(fourier_dim, time_dim), + nn.GELU(), + nn.Linear(time_dim, time_dim) + ) + + # layers + + self.downs = nn.ModuleList([]) + self.ups = nn.ModuleList([]) + num_resolutions = len(in_out) + + for ind, (dim_in, dim_out) in enumerate(in_out): + is_last = ind >= (num_resolutions - 1) + + self.downs.append(nn.ModuleList([ + block_klass(dim_in, dim_in, time_emb_dim = time_dim), + block_klass(dim_in, dim_in, time_emb_dim = time_dim), + Residual(PreNorm(dim_in, LinearAttention(dim_in))), + Downsample(dim_in, dim_out) if not is_last else nn.Conv1d(dim_in, dim_out, 3, padding = 1) + ])) + + mid_dim = dims[-1] + self.mid_block1 = block_klass(mid_dim, mid_dim, time_emb_dim = time_dim) + self.mid_attn = Residual(PreNorm(mid_dim, Attention(mid_dim, dim_head = attn_dim_head, heads = attn_heads))) + self.mid_block2 = block_klass(mid_dim, mid_dim, time_emb_dim = time_dim) + + for ind, (dim_in, dim_out) in enumerate(reversed(in_out)): + is_last = ind == (len(in_out) - 1) + + self.ups.append(nn.ModuleList([ + block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim), + block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim), + Residual(PreNorm(dim_out, LinearAttention(dim_out))), + Upsample(dim_out, dim_in) if not is_last else nn.Conv1d(dim_out, dim_in, 3, padding = 1) + ])) + + default_out_dim = channels * (1 if not learned_variance else 2) + self.out_dim = default(out_dim, default_out_dim) + + self.final_res_block = block_klass(dim * 2, dim, time_emb_dim = time_dim) + self.final_conv = nn.Conv1d(dim, self.out_dim, 1) + + def forward(self, x, time, x_self_cond = None): + if self.self_condition: + x_self_cond = default(x_self_cond, lambda: torch.zeros_like(x)) + x = torch.cat((x_self_cond, x), dim = 1) + + x = self.init_conv(x) + r = x.clone() + + t = self.time_mlp(time) + + h = [] + + for block1, block2, attn, downsample in self.downs: + x = block1(x, t) + h.append(x) + + x = block2(x, t) + x = attn(x) + h.append(x) + + x = downsample(x) + + x = self.mid_block1(x, t) + x = self.mid_attn(x) + x = self.mid_block2(x, t) + + for block1, block2, attn, upsample in self.ups: + x = torch.cat((x, h.pop()), dim = 1) + x = block1(x, t) + + x = torch.cat((x, h.pop()), dim = 1) + x = block2(x, t) + x = attn(x) + + x = upsample(x) + + x = torch.cat((x, r), dim = 1) + + x = self.final_res_block(x, t) + return self.final_conv(x) + +# gaussian diffusion trainer class + +def extract(a, t, x_shape): + b, *_ = t.shape + out = a.gather(-1, t) + return out.reshape(b, *((1,) * (len(x_shape) - 1))) + +def linear_beta_schedule(timesteps): + scale = 1000 / timesteps + beta_start = scale * 0.0001 + beta_end = scale * 0.02 + return torch.linspace(beta_start, beta_end, timesteps, dtype = torch.float64) + +def cosine_beta_schedule(timesteps, s = 0.008): + """ + cosine schedule + as proposed in https://openreview.net/forum?id=-NEXDKk8gZ + """ + steps = timesteps + 1 + x = torch.linspace(0, timesteps, steps, dtype = torch.float64) + alphas_cumprod = torch.cos(((x / timesteps) + s) / (1 + s) * math.pi * 0.5) ** 2 + alphas_cumprod = alphas_cumprod / alphas_cumprod[0] + betas = 1 - (alphas_cumprod[1:] / alphas_cumprod[:-1]) + return torch.clip(betas, 0, 0.999) + +class GaussianDiffusion1D(nn.Module): + def __init__( + self, + model, + *, + seq_length, + timesteps = 1000, + sampling_timesteps = None, + objective = 'pred_noise', + beta_schedule = 'cosine', + ddim_sampling_eta = 0., + auto_normalize = True + ): + super().__init__() + self.model = model + self.channels = self.model.channels + self.self_condition = self.model.self_condition + + self.seq_length = seq_length + + self.objective = objective + + assert objective in {'pred_noise', 'pred_x0', 'pred_v'}, 'objective must be either pred_noise (predict noise) or pred_x0 (predict image start) or pred_v (predict v [v-parameterization as defined in appendix D of progressive distillation paper, used in imagen-video successfully])' + + if beta_schedule == 'linear': + betas = linear_beta_schedule(timesteps) + elif beta_schedule == 'cosine': + betas = cosine_beta_schedule(timesteps) + else: + raise ValueError(f'unknown beta schedule {beta_schedule}') + + alphas = 1. - betas + alphas_cumprod = torch.cumprod(alphas, dim=0) + alphas_cumprod_prev = F.pad(alphas_cumprod[:-1], (1, 0), value = 1.) + + timesteps, = betas.shape + self.num_timesteps = int(timesteps) + + # sampling related parameters + + self.sampling_timesteps = default(sampling_timesteps, timesteps) # default num sampling timesteps to number of timesteps at training + + assert self.sampling_timesteps <= timesteps + self.is_ddim_sampling = self.sampling_timesteps < timesteps + self.ddim_sampling_eta = ddim_sampling_eta + + # helper function to register buffer from float64 to float32 + + register_buffer = lambda name, val: self.register_buffer(name, val.to(torch.float32)) + + register_buffer('betas', betas) + register_buffer('alphas_cumprod', alphas_cumprod) + register_buffer('alphas_cumprod_prev', alphas_cumprod_prev) + + # calculations for diffusion q(x_t | x_{t-1}) and others + + register_buffer('sqrt_alphas_cumprod', torch.sqrt(alphas_cumprod)) + register_buffer('sqrt_one_minus_alphas_cumprod', torch.sqrt(1. - alphas_cumprod)) + register_buffer('log_one_minus_alphas_cumprod', torch.log(1. - alphas_cumprod)) + register_buffer('sqrt_recip_alphas_cumprod', torch.sqrt(1. / alphas_cumprod)) + register_buffer('sqrt_recipm1_alphas_cumprod', torch.sqrt(1. / alphas_cumprod - 1)) + + # calculations for posterior q(x_{t-1} | x_t, x_0) + + posterior_variance = betas * (1. - alphas_cumprod_prev) / (1. - alphas_cumprod) + + # above: equal to 1. / (1. / (1. - alpha_cumprod_tm1) + alpha_t / beta_t) + + register_buffer('posterior_variance', posterior_variance) + + # below: log calculation clipped because the posterior variance is 0 at the beginning of the diffusion chain + + register_buffer('posterior_log_variance_clipped', torch.log(posterior_variance.clamp(min =1e-20))) + register_buffer('posterior_mean_coef1', betas * torch.sqrt(alphas_cumprod_prev) / (1. - alphas_cumprod)) + register_buffer('posterior_mean_coef2', (1. - alphas_cumprod_prev) * torch.sqrt(alphas) / (1. - alphas_cumprod)) + + # calculate loss weight + + snr = alphas_cumprod / (1 - alphas_cumprod) + + if objective == 'pred_noise': + loss_weight = torch.ones_like(snr) + elif objective == 'pred_x0': + loss_weight = snr + elif objective == 'pred_v': + loss_weight = snr / (snr + 1) + + register_buffer('loss_weight', loss_weight) + + # whether to autonormalize + + self.normalize = normalize_to_neg_one_to_one if auto_normalize else identity + self.unnormalize = unnormalize_to_zero_to_one if auto_normalize else identity + + def predict_start_from_noise(self, x_t, t, noise): + return ( + extract(self.sqrt_recip_alphas_cumprod, t, x_t.shape) * x_t - + extract(self.sqrt_recipm1_alphas_cumprod, t, x_t.shape) * noise + ) + + def predict_noise_from_start(self, x_t, t, x0): + return ( + (extract(self.sqrt_recip_alphas_cumprod, t, x_t.shape) * x_t - x0) / \ + extract(self.sqrt_recipm1_alphas_cumprod, t, x_t.shape) + ) + + def predict_v(self, x_start, t, noise): + return ( + extract(self.sqrt_alphas_cumprod, t, x_start.shape) * noise - + extract(self.sqrt_one_minus_alphas_cumprod, t, x_start.shape) * x_start + ) + + def predict_start_from_v(self, x_t, t, v): + return ( + extract(self.sqrt_alphas_cumprod, t, x_t.shape) * x_t - + extract(self.sqrt_one_minus_alphas_cumprod, t, x_t.shape) * v + ) + + def q_posterior(self, x_start, x_t, t): + posterior_mean = ( + extract(self.posterior_mean_coef1, t, x_t.shape) * x_start + + extract(self.posterior_mean_coef2, t, x_t.shape) * x_t + ) + posterior_variance = extract(self.posterior_variance, t, x_t.shape) + posterior_log_variance_clipped = extract(self.posterior_log_variance_clipped, t, x_t.shape) + return posterior_mean, posterior_variance, posterior_log_variance_clipped + + def model_predictions(self, x, t, x_self_cond = None, clip_x_start = False, rederive_pred_noise = False): + model_output = self.model(x, t, x_self_cond) + maybe_clip = partial(torch.clamp, min = -1., max = 1.) if clip_x_start else identity + + if self.objective == 'pred_noise': + pred_noise = model_output + x_start = self.predict_start_from_noise(x, t, pred_noise) + x_start = maybe_clip(x_start) + + if clip_x_start and rederive_pred_noise: + pred_noise = self.predict_noise_from_start(x, t, x_start) + + elif self.objective == 'pred_x0': + x_start = model_output + x_start = maybe_clip(x_start) + pred_noise = self.predict_noise_from_start(x, t, x_start) + + elif self.objective == 'pred_v': + v = model_output + x_start = self.predict_start_from_v(x, t, v) + x_start = maybe_clip(x_start) + pred_noise = self.predict_noise_from_start(x, t, x_start) + + return ModelPrediction(pred_noise, x_start) + + def p_mean_variance(self, x, t, x_self_cond = None, clip_denoised = True): + preds = self.model_predictions(x, t, x_self_cond) + x_start = preds.pred_x_start + + if clip_denoised: + x_start.clamp_(-1., 1.) + + model_mean, posterior_variance, posterior_log_variance = self.q_posterior(x_start = x_start, x_t = x, t = t) + return model_mean, posterior_variance, posterior_log_variance, x_start + + @torch.no_grad() + def p_sample(self, x, t: int, x_self_cond = None, clip_denoised = True): + b, *_, device = *x.shape, x.device + batched_times = torch.full((b,), t, device = x.device, dtype = torch.long) + model_mean, _, model_log_variance, x_start = self.p_mean_variance(x = x, t = batched_times, x_self_cond = x_self_cond, clip_denoised = clip_denoised) + noise = torch.randn_like(x) if t > 0 else 0. # no noise if t == 0 + pred_img = model_mean + (0.5 * model_log_variance).exp() * noise + return pred_img, x_start + + @torch.no_grad() + def p_sample_loop(self, shape): + batch, device = shape[0], self.betas.device + + img = torch.randn(shape, device=device) + + x_start = None + + for t in tqdm(reversed(range(0, self.num_timesteps)), desc = 'sampling loop time step', total = self.num_timesteps): + self_cond = x_start if self.self_condition else None + img, x_start = self.p_sample(img, t, self_cond) + + img = self.unnormalize(img) + return img + + @torch.no_grad() + def ddim_sample(self, shape, clip_denoised = True): + batch, device, total_timesteps, sampling_timesteps, eta, objective = shape[0], self.betas.device, self.num_timesteps, self.sampling_timesteps, self.ddim_sampling_eta, self.objective + + times = torch.linspace(-1, total_timesteps - 1, steps=sampling_timesteps + 1) # [-1, 0, 1, 2, ..., T-1] when sampling_timesteps == total_timesteps + times = list(reversed(times.int().tolist())) + time_pairs = list(zip(times[:-1], times[1:])) # [(T-1, T-2), (T-2, T-3), ..., (1, 0), (0, -1)] + + img = torch.randn(shape, device = device) + + x_start = None + + for time, time_next in tqdm(time_pairs, desc = 'sampling loop time step'): + time_cond = torch.full((batch,), time, device=device, dtype=torch.long) + self_cond = x_start if self.self_condition else None + pred_noise, x_start, *_ = self.model_predictions(img, time_cond, self_cond, clip_x_start = clip_denoised) + + if time_next < 0: + img = x_start + continue + + alpha = self.alphas_cumprod[time] + alpha_next = self.alphas_cumprod[time_next] + + sigma = eta * ((1 - alpha / alpha_next) * (1 - alpha_next) / (1 - alpha)).sqrt() + c = (1 - alpha_next - sigma ** 2).sqrt() + + noise = torch.randn_like(img) + + img = x_start * alpha_next.sqrt() + \ + c * pred_noise + \ + sigma * noise + + img = self.unnormalize(img) + return img + + @torch.no_grad() + def sample(self, batch_size = 16): + seq_length, channels = self.seq_length, self.channels + sample_fn = self.p_sample_loop if not self.is_ddim_sampling else self.ddim_sample + return sample_fn((batch_size, channels, seq_length)) + + @torch.no_grad() + def interpolate(self, x1, x2, t = None, lam = 0.5): + b, *_, device = *x1.shape, x1.device + t = default(t, self.num_timesteps - 1) + + assert x1.shape == x2.shape + + t_batched = torch.full((b,), t, device = device) + xt1, xt2 = map(lambda x: self.q_sample(x, t = t_batched), (x1, x2)) + + img = (1 - lam) * xt1 + lam * xt2 + + x_start = None + + for i in tqdm(reversed(range(0, t)), desc = 'interpolation sample time step', total = t): + self_cond = x_start if self.self_condition else None + img, x_start = self.p_sample(img, i, self_cond) + + return img + + @autocast(enabled = False) + def q_sample(self, x_start, t, noise=None): + noise = default(noise, lambda: torch.randn_like(x_start)) + + return ( + extract(self.sqrt_alphas_cumprod, t, x_start.shape) * x_start + + extract(self.sqrt_one_minus_alphas_cumprod, t, x_start.shape) * noise + ) + + def p_losses(self, x_start, t, noise = None): + b, c, n = x_start.shape + noise = default(noise, lambda: torch.randn_like(x_start)) + + # noise sample + + x = self.q_sample(x_start = x_start, t = t, noise = noise) + + # if doing self-conditioning, 50% of the time, predict x_start from current set of times + # and condition with unet with that + # this technique will slow down training by 25%, but seems to lower FID significantly + + x_self_cond = None + if self.self_condition and random() < 0.5: + with torch.no_grad(): + x_self_cond = self.model_predictions(x, t).pred_x_start + x_self_cond.detach_() + + # predict and take gradient step + + model_out = self.model(x, t, x_self_cond) + + if self.objective == 'pred_noise': + target = noise + elif self.objective == 'pred_x0': + target = x_start + elif self.objective == 'pred_v': + v = self.predict_v(x_start, t, noise) + target = v + else: + raise ValueError(f'unknown objective {self.objective}') + + loss = F.mse_loss(model_out, target, reduction = 'none') + loss = reduce(loss, 'b ... -> b', 'mean') + + loss = loss * extract(self.loss_weight, t, loss.shape) + return loss.mean() + + def forward(self, img, *args, **kwargs): + b, c, n, device, seq_length, = *img.shape, img.device, self.seq_length + assert n == seq_length, f'seq length must be {seq_length}' + t = torch.randint(0, self.num_timesteps, (b,), device=device).long() + + img = self.normalize(img) + return self.p_losses(img, t, *args, **kwargs) + +# trainer class + +class Trainer1D(object): + def __init__( + self, + diffusion_model: GaussianDiffusion1D, + dataset: Dataset, + *, + train_batch_size = 16, + gradient_accumulate_every = 1, + train_lr = 1e-4, + train_num_steps = 100000, + ema_update_every = 10, + ema_decay = 0.995, + adam_betas = (0.9, 0.99), + save_and_sample_every = 1000, + num_samples = 25, + results_folder = './results', + amp = False, + mixed_precision_type = 'fp16', + split_batches = True, + max_grad_norm = 1. + ): + super().__init__() + + # accelerator + + self.accelerator = Accelerator( + split_batches = split_batches, + mixed_precision = mixed_precision_type if amp else 'no' + ) + + # model + + self.model = diffusion_model + self.channels = diffusion_model.channels + + # sampling and training hyperparameters + + assert has_int_squareroot(num_samples), 'number of samples must have an integer square root' + self.num_samples = num_samples + self.save_and_sample_every = save_and_sample_every + + self.batch_size = train_batch_size + self.gradient_accumulate_every = gradient_accumulate_every + self.max_grad_norm = max_grad_norm + + self.train_num_steps = train_num_steps + + # dataset and dataloader + + dl = DataLoader(dataset, batch_size = train_batch_size, shuffle = True, pin_memory = True, num_workers = cpu_count()) + + dl = self.accelerator.prepare(dl) + self.dl = cycle(dl) + + # optimizer + + self.opt = Adam(diffusion_model.parameters(), lr = train_lr, betas = adam_betas) + + # for logging results in a folder periodically + + if self.accelerator.is_main_process: + self.ema = EMA(diffusion_model, beta = ema_decay, update_every = ema_update_every) + self.ema.to(self.device) + + self.results_folder = Path(results_folder) + self.results_folder.mkdir(exist_ok = True) + + # step counter state + + self.step = 0 + + # prepare model, dataloader, optimizer with accelerator + + self.model, self.opt = self.accelerator.prepare(self.model, self.opt) + + @property + def device(self): + return self.accelerator.device + + def save(self, milestone): + if not self.accelerator.is_local_main_process: + return + + data = { + 'step': self.step, + 'model': self.accelerator.get_state_dict(self.model), + 'opt': self.opt.state_dict(), + 'ema': self.ema.state_dict(), + 'scaler': self.accelerator.scaler.state_dict() if exists(self.accelerator.scaler) else None, + 'version': __version__ + } + + torch.save(data, str(self.results_folder / f'model-{milestone}.pt')) + + def load(self, milestone): + accelerator = self.accelerator + device = accelerator.device + + data = torch.load(str(self.results_folder / f'model-{milestone}.pt'), map_location=device) + + model = self.accelerator.unwrap_model(self.model) + model.load_state_dict(data['model']) + + self.step = data['step'] + self.opt.load_state_dict(data['opt']) + if self.accelerator.is_main_process: + self.ema.load_state_dict(data["ema"]) + + if 'version' in data: + print(f"loading from version {data['version']}") + + if exists(self.accelerator.scaler) and exists(data['scaler']): + self.accelerator.scaler.load_state_dict(data['scaler']) diff --git a/subject1-4/AdaDiff/diffusion_module2.py b/subject1-4/AdaDiff/diffusion_module2.py new file mode 100644 index 0000000..6159947 --- /dev/null +++ b/subject1-4/AdaDiff/diffusion_module2.py @@ -0,0 +1,159 @@ +import torch +import torch.nn.functional as F +from tqdm import tqdm + +def cosine_beta_schedule(timesteps, s=0.008): + """ + cosine schedule as proposed in https://arxiv.org/abs/2102.09672 + """ + steps = timesteps + 1 + x = torch.linspace(0, timesteps, steps) + alphas_cumprod = torch.cos(((x / timesteps) + s) / (1 + s) * torch.pi * 0.5) ** 2 + alphas_cumprod = alphas_cumprod / alphas_cumprod[0] + betas = 1 - (alphas_cumprod[1:] / alphas_cumprod[:-1]) + return torch.clip(betas, 0.0001, 0.9999) + +def linear_beta_schedule(timesteps): + beta_start = 0.0001 + beta_end = 0.02 + return torch.linspace(beta_start, beta_end, timesteps) + +def quadratic_beta_schedule(timesteps): + beta_start = 0.0001 + beta_end = 0.02 + return torch.linspace(beta_start**0.5, beta_end**0.5, timesteps) ** 2 + +def sigmoid_beta_schedule(timesteps): + beta_start = 0.0001 + beta_end = 0.02 + betas = torch.linspace(-6, 6, timesteps) + return torch.sigmoid(betas) * (beta_end - beta_start) + beta_start + +timesteps = 300 + +# define beta schedule +betas = linear_beta_schedule(timesteps=timesteps) + +# define alphas +alphas = 1. - betas +alphas_cumprod = torch.cumprod(alphas, axis=0) +alphas_cumprod_prev = F.pad(alphas_cumprod[:-1], (1, 0), value=1.0) +sqrt_recip_alphas = torch.sqrt(1.0 / alphas) + +# calculations for diffusion q(x_t | x_{t-1}) and others +sqrt_alphas_cumprod = torch.sqrt(alphas_cumprod) +sqrt_one_minus_alphas_cumprod = torch.sqrt(1. - alphas_cumprod) + +# calculations for posterior q(x_{t-1} | x_t, x_0) +posterior_variance = betas * (1. - alphas_cumprod_prev) / (1. - alphas_cumprod) + +def extract(a, t, x_shape): + batch_size = t.shape[0] + out = a.gather(-1, t.cpu()) + return out.reshape(batch_size, *((1,) * (len(x_shape) - 1))).to(t.device) + + +# forward diffusion (using the nice property) +def q_sample(x_start, t, noise=None): + if noise is None: + noise = torch.randn_like(x_start) + + sqrt_alphas_cumprod_t = extract(sqrt_alphas_cumprod, t, x_start.shape) + sqrt_one_minus_alphas_cumprod_t = extract( + sqrt_one_minus_alphas_cumprod, t, x_start.shape + ) + + return sqrt_alphas_cumprod_t * x_start + sqrt_one_minus_alphas_cumprod_t * noise + +def p_losses(denoise_model, x_start, t, noise=None, loss_type="l2"): + if noise is None: + noise = torch.randn_like(x_start) + + x_noisy = q_sample(x_start=x_start, t=t, noise=noise) + predicted_noise = denoise_model(x_noisy, t) + #if train: + if loss_type == 'l1': + loss = F.l1_loss(noise, predicted_noise) + elif loss_type == 'l2': + loss = F.mse_loss(noise, predicted_noise) + elif loss_type == "huber": + loss = F.smooth_l1_loss(noise, predicted_noise) + else: + raise NotImplementedError() + # else: + # x_recon = (x_noisy - extract(sqrt_one_minus_alphas_cumprod, t, x_noisy.shape) * predicted_noise) / extract(sqrt_alphas_cumprod, t, x_noisy.shape) + # loss = F.mse_loss(predicted_noise, noise, reduction='none') + return loss + + +##### SAMPLING ####### + +@torch.no_grad() +def p_sample(model, x, t, t_index): + betas_t = extract(betas, t, x.shape) + sqrt_one_minus_alphas_cumprod_t = extract( + sqrt_one_minus_alphas_cumprod, t, x.shape + ) + sqrt_recip_alphas_t = extract(sqrt_recip_alphas, t, x.shape) + + # Equation 11 in the paper + # Use our model (noise predictor) to predict the mean + model_mean = sqrt_recip_alphas_t * ( + x - betas_t * model(x, t) / sqrt_one_minus_alphas_cumprod_t + ) + + if t_index == 0: + return model_mean + else: + posterior_variance_t = extract(posterior_variance, t, x.shape) + noise = torch.randn_like(x) + # Algorithm 2 line 4: + return model_mean + torch.sqrt(posterior_variance_t) * noise + +# Algorithm 2 (including returning all images) +@torch.no_grad() +def p_sample_loop(model, shape, x_start, denoise_steps): + #device = next(model.parameters()).device + #timesteps = 200 + timesteps = denoise_steps + device = 'cuda' + + b = shape[0] + # start from pure noise (for each example in the batch) + #img = torch.randn(shape, device=device) + noise = torch.randn_like(x_start) + img = q_sample(x_start=x_start, t=torch.full((b,), timesteps, device=device, dtype=torch.long), noise=noise) + # imgs = [] + + for i in tqdm(reversed(range(0, timesteps)), desc='sampling loop time step', total=timesteps): + img = p_sample(model, img, torch.full((b,), i, device=device, dtype=torch.long), i) + #imgs.append(img.cpu().numpy()) + return img + +@torch.no_grad() +def sample(model, shape, x_start, denoise_steps): + return p_sample_loop(model, shape=shape, x_start=x_start, denoise_steps=denoise_steps) +@torch.no_grad() +def sample(model, shape, x_start, denoise_steps, Tstart, Tend): + return p_sample_loop_withStartAndEnd(model, shape, x_start, denoise_steps, Tstart, Tend) + +@torch.no_grad() +def p_sample_loop_withStartAndEnd(model, shape, x_start, denoise_steps, Tstart, Tend): + #device = next(model.parameters()).device + #timesteps = 200 + timesteps = denoise_steps + device = 'cuda' + + b = shape[0] + # start from pure noise (for each example in the batch) + #img = torch.randn(shape, device=device) + if Tstart == 0: + noise = torch.randn_like(x_start) + img = q_sample(x_start=x_start, t=torch.full((b,), timesteps, device=device, dtype=torch.long), noise=noise) + else: + img = x_start + + for i in tqdm(reversed(range(timesteps - Tend, timesteps - Tstart)), desc='sampling loop time step', total=Tend - Tstart): + img = p_sample(model, img, torch.full((b,), i, device=device, dtype=torch.long), i) + #imgs.append(img.cpu().numpy()) + return img \ No newline at end of file diff --git a/subject1-4/AdaDiff/huigui.ipynb b/subject1-4/AdaDiff/huigui.ipynb new file mode 100644 index 0000000..3164575 --- /dev/null +++ b/subject1-4/AdaDiff/huigui.ipynb @@ -0,0 +1,234 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "\n", + "# 假设你的数据是一个CSV文件,可以通过read_csv加载\n", + "# 如果数据不是CSV格式,可以根据实际情况使用其他read_函数\n", + "data = pd.read_csv('../alpha=0.1.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
prf1time
00.1500.771.47
10.1450.741.45
20.1350.701.43
30.1300.681.40
40.1250.631.39
\n", + "
" + ], + "text/plain": [ + " p r f1 time\n", + "0 0.1 50 0.77 1.47\n", + "1 0.1 45 0.74 1.45\n", + "2 0.1 35 0.70 1.43\n", + "3 0.1 30 0.68 1.40\n", + "4 0.1 25 0.63 1.39" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "特征 X:\n", + " p r\n", + "0 0.1 50\n", + "1 0.1 45\n", + "2 0.1 35\n", + "3 0.1 30\n", + "4 0.1 25\n", + "目标 y:\n", + " 0 0.77\n", + "1 0.74\n", + "2 0.70\n", + "3 0.68\n", + "4 0.63\n", + "Name: f1, dtype: float64\n" + ] + } + ], + "source": [ + "X = data.iloc[:, :-2] # 选择除最后一列之外的所有列作为特征\n", + "f1 = data.iloc[:, -2] # 选择最后一列作为目标变量\n", + "time = data.iloc[:,-1]\n", + "# 打印 X 和 y,确保提取正确\n", + "print(\"特征 X:\\n\", X.head())\n", + "print(\"目标 y:\\n\", f1.head())" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "回归系数: [-0.92813953 0.00513953]\n", + "截距: 0.6066511627906976\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from sklearn.linear_model import LinearRegression\n", + "import matplotlib.pyplot as plt\n", + "\n", + "# 生成一些示例数据\n", + "# np.random.seed(0)\n", + "# X = 2 * np.random.rand(100, 2) # 有两个特征\n", + "# y = 4 + 3 * X[:, 0] + 2 * X[:, 1] + np.random.randn(100)\n", + "\n", + "# 创建线性回归模型\n", + "model = LinearRegression()\n", + "\n", + "# 将数据拟合到模型中\n", + "model.fit(X, f1)\n", + "\n", + "# 打印回归系数和截距\n", + "print(\"回归系数:\", model.coef_)\n", + "print(\"截距:\", model.intercept_)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "回归系数: [-0.53418605 0.00318605]\n", + "截距: 1.36353488372093\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from sklearn.linear_model import LinearRegression\n", + "import matplotlib.pyplot as plt\n", + "\n", + "# 生成一些示例数据\n", + "# np.random.seed(0)\n", + "# X = 2 * np.random.rand(100, 2) # 有两个特征\n", + "# y = 4 + 3 * X[:, 0] + 2 * X[:, 1] + np.random.randn(100)\n", + "\n", + "# 创建线性回归模型\n", + "model = LinearRegression()\n", + "\n", + "# 将数据拟合到模型中\n", + "model.fit(X, time)\n", + "\n", + "# 打印回归系数和截距\n", + "print(\"回归系数:\", model.coef_)\n", + "print(\"截距:\", model.intercept_)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "diffusionA", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.18" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/subject1-4/AdaDiff/models2.py b/subject1-4/AdaDiff/models2.py new file mode 100644 index 0000000..506a11b --- /dev/null +++ b/subject1-4/AdaDiff/models2.py @@ -0,0 +1,273 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.optim as optim +import pickle +from torch.nn import TransformerEncoder, TransformerEncoderLayer, TransformerDecoderLayer +from torch.nn import TransformerDecoder +from src.dlutils import * +from unet2 import Unet +from scipy import stats +from diffusion_module2 import p_losses, sample +from denoising_diffusion_pytorch_1d import Unet1D +device = 'cuda' + + +class Autoencoder_Diffusion(nn.Module): + def __init__(self, feats, lr, window_size, batch_size, p1, p2): + super().__init__() + self.name = 'AutoencoderDiffusion' + self.lr = lr + self.batch = batch_size + self.n_feats = feats + self.n_window = window_size + self.p1 = p1 + self.p2 = p2 + self.bottleneck_s1 = int(p1 * self.n_feats * self.n_window) + self.bottleneck_s2 = int(p2 * self.n_feats * self.n_window) + self.bottleneck = 32 + + self.encoder = torch.nn.Sequential( + torch.nn.Linear(self.n_feats * self.n_window, self.bottleneck_s1), + torch.nn.ReLU(), + torch.nn.Linear(self.bottleneck_s1, self.bottleneck_s2), + ) + + #self.encoder = torch.nn.Linear(self.n_feats * self.n_window, self.bottleneck) + + self.decoder = torch.nn.Sequential( + torch.nn.Linear(self.bottleneck_s2, self.bottleneck_s1), + torch.nn.ReLU(), + torch.nn.Linear(self.bottleneck_s1, self.n_feats * self.n_window), + ) + + self.activation_fn = torch.nn.ReLU() + + #self.decoder = torch.nn.Linear(self.bottleneck, self.n_feats * self.n_window) + + + def forward(self, x): + encoded = self.encoder(x) + decoded = self.decoder(encoded) + return decoded + + +class ConditionalDiffusionTrainingNetwork(nn.Module): + + def __init__(self,nr_feats, window_size, batch_size, noise_steps, denoise_steps, train=True): + super().__init__() + self.dim = min(nr_feats, 16) + self.nr_feats = nr_feats + self.window_size = window_size + self.batch_size = batch_size + + self.training = train + self.timesteps = noise_steps + self.denoise_steps = denoise_steps + + # self.denoise_fn = Unet(dim=self.dim, channels=1, resnet_block_groups=1, init_size=torch.Size([self.dim, self.window_size, self.nr_feats])) + self.denoise_fn = model = Unet1D( + dim = 64, + dim_mults = (1, 2, 4, 8), + channels = nr_feats + ) + + def forward(self, x, Tstart = None, Tend = None): + + diffusion_loss = None + x_recon = None + if Tstart == None: + Tstart = 0 + if Tend == None: + Tend = self.denoise_steps + + # x = x.reshape(-1, 1, self.window_size, self.nr_feats) + # print(self.nr_feats) + x = x.transpose(2,1) + # print(np.shape(x)) + if self.training: + t = torch.randint(0, self.timesteps, (x.shape[0],), device=device).long() + diffusion_loss = p_losses(self.denoise_fn, x, t) + else: + # x_recon = sample(self.denoise_fn, shape=(x.shape[0], 1, self.window_size, self.nr_feats), x_start=x, denoise_steps=self.denoise_steps) + x_recon = sample(self.denoise_fn, shape=(x.shape[0], 1, self.window_size, self.nr_feats), x_start=x, denoise_steps=self.denoise_steps, Tstart = Tstart, Tend = Tend) + return diffusion_loss, x_recon + + + +class TransformerBasic(nn.Module): + def __init__(self, feats): + super().__init__() + self.name = 'TransformerBasic' + self.lr = 0.1 + self.batch = 128 + self.n_feats = feats + self.n_window = 10 + + self.lin = nn.Linear(1, feats) + self.out_lin = nn.Linear(feats, 1) + self.pos_encoder = PositionalEncoding(feats, 0.1, feats*self.n_window) + encoder_layers = TransformerEncoderLayer(d_model=feats, nhead=feats, dim_feedforward=16, dropout=0.1) + self.transformer_encoder = TransformerEncoder(encoder_layers, 1) + decoder_layers = TransformerDecoderLayer(d_model=feats, nhead=feats, dim_feedforward=16, dropout=0.1) + self.transformer_decoder = TransformerDecoder(decoder_layers, 1) + self.fcn = nn.Sigmoid() + + def forward(self, src, tgt): + # bs x (ws x features) x features + src = src * math.sqrt(self.n_feats) + src = self.lin(src.unsqueeze(2)) + src = self.pos_encoder(src) + memory = self.transformer_encoder(src) + + tgt = tgt * math.sqrt(self.n_feats) + tgt = self.lin(tgt.unsqueeze(2)) + tgt = self.pos_encoder(tgt) + x = self.transformer_decoder(tgt, memory) + x = self.out_lin(x) + x = self.fcn(x) + return x + +class TransformerBasicv2(nn.Module): + def __init__(self, feats, lr, window_size): + super(TransformerBasicv2, self).__init__() + self.name = 'TransformerBasicv2' + self.lr = lr + self.batch = 128 + self.n_feats = feats + self.n_window = window_size + self.scale = 16 + self.linear_layer = nn.Linear(feats, self.scale*feats) + self.output_layer = nn.Linear(self.scale*feats, feats) + self.pos_encoder = PositionalEncoding(self.scale*feats, 0.1, self.n_window, batch_first=True) + encoder_layers = TransformerEncoderLayer(d_model=feats*self.scale, nhead=feats, batch_first=True, dim_feedforward=256, dropout=0.1) + self.transformer_encoder = TransformerEncoder(encoder_layers, 1) + decoder_layers = TransformerDecoderLayer(d_model=feats*self.scale, nhead=feats, batch_first=True, dim_feedforward=256, dropout=0.1) + self.transformer_decoder = TransformerDecoder(decoder_layers, 1) + self.fcn = nn.Sigmoid() + + def forward(self, src, tgt): + src = src * math.sqrt(self.n_feats) + src = self.linear_layer(src) + src = self.pos_encoder(src) + memory = self.transformer_encoder(src) + + tgt = tgt * math.sqrt(self.n_feats) + tgt = self.linear_layer(tgt) + + x = self.transformer_decoder(tgt, memory) + x = self.output_layer(x) + x = self.fcn(x) + return x + +class TransformerBasicv2Scaling(nn.Module): + def __init__(self, feats, lr, window_size): + super(TransformerBasicv2Scaling, self).__init__() + self.name = 'TransformerBasicv2Scaling' + self.lr = lr + self.batch = 128 + self.n_feats = feats + self.n_window = window_size + self.scale = 16 + self.linear_layer = nn.Linear(feats, self.scale*feats) + self.output_layer = nn.Linear(self.scale*feats, feats) + self.pos_encoder = PositionalEncoding(self.scale*feats, 0.1, self.n_window, batch_first=True) + encoder_layers = TransformerEncoderLayer(d_model=feats*self.scale, nhead=feats, batch_first=True, dim_feedforward=256, dropout=0.1) + self.transformer_encoder = TransformerEncoder(encoder_layers, 1) + decoder_layers = TransformerDecoderLayer(d_model=feats*self.scale, nhead=feats, batch_first=True, dim_feedforward=256, dropout=0.1) + self.transformer_decoder = TransformerDecoder(decoder_layers, 1) + self.fcn = nn.Sigmoid() + + def forward(self, src, tgt): + model_dim = self.scale * self.n_feats + + src = self.linear_layer(src) + src = src * math.sqrt(model_dim) + src = self.pos_encoder(src) + memory = self.transformer_encoder(src) + + tgt = self.linear_layer(tgt) + tgt = tgt * math.sqrt(model_dim) + + x = self.transformer_decoder(tgt, memory) + x = self.output_layer(x) + x = self.fcn(x) + return x + + + +class TransformerBasicBottleneck(nn.Module): + def __init__(self, feats, lr, window_size): + super(TransformerBasicBottleneck, self).__init__() + self.name = 'TransformerBasicBottleneck' + self.lr = lr + self.batch = 16 + self.n_feats = feats + self.n_window = window_size + self.scale = 16 + self.linear_layer = nn.Linear(feats, self.scale*feats) + self.output_layer = nn.Linear(self.scale*feats, feats) + self.pos_encoder = PositionalEncoding(self.scale*feats, 0.1, self.n_window, batch_first=True) + encoder_layers = TransformerEncoderLayer(d_model=feats*self.scale, nhead=feats, batch_first=True, dim_feedforward=256, dropout=0.1) + self.transformer_encoder = TransformerEncoder(encoder_layers, 1) + decoder_layers = TransformerDecoderLayer(d_model=feats*self.scale, nhead=feats, batch_first=True, dim_feedforward=256, dropout=0.1) + self.transformer_decoder = TransformerDecoder(decoder_layers, 1) + self.fcn = nn.Sigmoid() + + def forward(self, src, tgt): + src = src * math.sqrt(self.n_feats) + src = self.linear_layer(src) + src = self.pos_encoder(src) + # batch x t x d + memory = self.transformer_encoder(src) + # batch x 1 x d + z = torch.mean(memory, dim=1, keepdim=True) + + + tgt = tgt * math.sqrt(self.n_feats) + tgt = self.linear_layer(tgt) + + x = self.transformer_decoder(tgt, z) + x = self.output_layer(x) + x = self.fcn(x) + return x + +class TransformerBasicBottleneckScaling(nn.Module): + def __init__(self, feats, lr, window_size, batch_size): + super(TransformerBasicBottleneckScaling, self).__init__() + self.name = 'TransformerBasicBottleneckScaling' + self.lr = lr + self.batch = batch_size + self.n_feats = feats + self.n_window = window_size + self.scale = 16 + self.linear_layer = nn.Linear(feats, self.scale*feats) + self.output_layer = nn.Linear(self.scale*feats, feats) + self.pos_encoder = PositionalEncoding(self.scale*feats, 0.1, self.n_window, batch_first=True) + encoder_layers = TransformerEncoderLayer(d_model=feats*self.scale, nhead=feats, batch_first=True, dim_feedforward=256, dropout=0.1) + self.transformer_encoder = TransformerEncoder(encoder_layers, 1) + decoder_layers = TransformerDecoderLayer(d_model=feats*self.scale, nhead=feats, batch_first=True, dim_feedforward=256, dropout=0.1) + self.transformer_decoder = TransformerDecoder(decoder_layers, 1) + self.fcn = nn.Sigmoid() + + def forward(self, src, tgt): + model_dim = self.scale * self.n_feats + + src = self.linear_layer(src) + src = src * math.sqrt(model_dim) + src = self.pos_encoder(src) + # batch x t x d + memory = self.transformer_encoder(src) + # batch x 1 x d + z = torch.mean(memory, dim=1, keepdim=True) + + tgt = self.linear_layer(tgt) + tgt = tgt * math.sqrt(model_dim) + + x = self.transformer_decoder(tgt, z) + x = self.output_layer(x) + x = self.fcn(x) + return x + + + diff --git a/subject1-4/AdaDiff/server.py b/subject1-4/AdaDiff/server.py new file mode 100644 index 0000000..edc5ce5 --- /dev/null +++ b/subject1-4/AdaDiff/server.py @@ -0,0 +1,151 @@ +import socket +import threading +import os +import ast +import time +import csv +import diffusion_module2 +import train_diffusion_val +import torch +from torch.utils.data import Dataset, DataLoader, TensorDataset +import torch.nn as nn +import numpy as np +import time +import pickle +device = "cuda" +class Server: + def __init__(self, address, model): + self.address = address + self.clients = [] + self.real_anomalies = set() + self.model = model + + # timestamp = time.strftime("%Y%m%d%H%M%S", time.localtime()) + + # # 将时间戳添加到 CSV 文件名中 + # self.log_file_name = f"server_log_{timestamp}.csv" + + # # 创建 CSV 文件并写入表头 + # with open(self.log_file_name, 'w', newline='') as csvfile: + # fieldnames = ['Node ID', 'Anomaly Data ID', 'Is Real Anomaly'] + # writer = csv.DictWriter(csvfile, fieldnames=fieldnames) + # writer.writeheader() + + + def start_server(self): + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket: + server_socket.bind(self.address) + server_socket.listen() + + print(f"Server listening on {self.address}") + + while True: + client_socket, client_address = server_socket.accept() + client_thread = threading.Thread(target=self.handle_client, args=(client_socket, client_address)) + client_thread.start() + self.clients.append(client_thread) + + def handle_client(self, client_socket, client_address): + print(f"Accepted connection from {client_address}") + + length = int(client_socket.recv(1024).decode()) + print("收到长度",length) + client_socket.sendall('go'.encode()) + serialized_data = b'' + while True: + chunk = client_socket.recv(1024) # 接收数据块(这里假设每次接收1KB) + + serialized_data += chunk + if len(serialized_data) == length: # 如果接收到的数据为空,表示传输完毕 + break + # print(len(serialized_data)) + deserialized_data = pickle.loads(serialized_data) + # 处理反序列化后的数据... + ratio = deserialized_data["ratio"] + data_fragment = deserialized_data["data"] + print(f"Received ratio: {ratio}") + + # 进行进一步的异常检测 + data = self.denoising(data_fragment, ratio) + + serialized_data = pickle.dumps(data) + chunk_size = 1024 + + client_socket.sendall(str(len(serialized_data)).encode()) + point = client_socket.recv(1024) + print("收到信号", point.decode()) + print(np.shape(data)) + print(len(serialized_data)) + for i in range(0, len(serialized_data), chunk_size): + chunk = serialized_data[i:i+chunk_size] + client_socket.sendall(chunk) + print(f"Connection from {client_address} closed") + client_socket.close() + def denoising(self, data, ratio): + # print(np.shape(data)) + data.to(device) + return self.model(data,int(self.model.denoise_steps* ratio),self.model.denoise_steps)[1].transpose(2,1) + + +if __name__ == "__main__": + server_address = ('localhost', 8892) # 中心服务器地址和端口 + + + training_mode = "diffusion" + lr = 1e-3 + window_size = 128 + p1 = 1 + p2 = 1 + dataset_name = "point_global" + batch_size = 32 + noise_steps = 100 + denoise_steps = 50 + diff_lambda = 0.1 + part = None + device = "cuda" + + experiment = f'diffv4_{dataset_name}_{noise_steps}-{denoise_steps}_{diff_lambda}_1e-3_{batch_size}_{window_size}' + + train_loader, test_loader, validation_loader, labels, validation_labels = train_diffusion_val.load_dataset(dataset_name, part) + + model, diffusion_training_net, diffusion_prediction_net, optimizer, scheduler = \ + train_diffusion_val.load_model(training_mode ,lr, window_size, p1, p2, labels.shape[1], batch_size, noise_steps, denoise_steps) + model, diffusion_training_net = train_diffusion_val.load_from_checkpoint(training_mode, experiment, model, diffusion_training_net) + diffusion_training_net = diffusion_training_net.to(device) + diffusion_prediction_net = diffusion_prediction_net.to(device) + + diffusion_prediction_net.load_state_dict(diffusion_training_net.state_dict()) + diffusion_prediction_net.eval() + # diffusion_training_net.eval() + + # trainD, testD, validationD = next(iter(train_loader)), next(iter(test_loader)), next(iter(validation_loader)) + # testD = train_diffusion_val.convert_to_windows(testD, window_size) + # data_x = torch.tensor(testD, dtype=torch.float32); + # dataset = TensorDataset(data_x, data_x) + # dataloader = DataLoader(dataset, batch_size = batch_size) + + # STime = time.time() + # l1s = [] + # feats=labels.shape[1] + # for window, _ in dataloader: + # window = window.to(device) + # _, x_recon = diffusion_prediction_net(window, 0,50) + # x_recon = x_recon.transpose(2,1) + # l = nn.MSELoss(reduction = 'none') + # loss = l(x_recon, window) + # l1s.append(loss) + # ETime = time.time() + # loss0 = torch.cat(l1s).detach().cpu().numpy() + # loss0 = loss0.reshape(-1,feats) + + # lossFinal = np.mean(np.array(loss0), axis=1) + # labelsFinal = (np.sum(labels, axis=1) >= 1) + 0 + # validation_thresh = 0 + # result, fprs, tprs = train_diffusion_val.evaluate(lossFinal, labelsFinal, validation_thresh=validation_thresh) + # result_roc = result["ROC/AUC"] + # result_f1 = result["f1"] + + # print(result, ETime - STime) + + server = Server(server_address, diffusion_prediction_net) + server.start_server() diff --git a/subject1-4/AdaDiff/src/__pycache__/dlutils.cpython-38.pyc b/subject1-4/AdaDiff/src/__pycache__/dlutils.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f389758846b18d3e10b2ef86123539b5e3e0a18 GIT binary patch literal 1418 zcmZuxPmkO*6t|tf^LLk7L|e)MLDe!6+BtGTw1{>&Q6V7^$|cIi&TK}BliCjKtg_+voDBa2|V!h5ODI=7WZsheltnkYq3a+feDD15U(eQJ^9qwKb?h3jZ zJ$Irpr(cn|cL~wS(>b-_H;KxV<3gmU*&SF34*dZzK_bctWFNdB8RahbE(Vdqhdkin z1&!Pn#3hjjkwkmED4F zVrWaAvyN@xh{jpDE#veR=wh#Rf%_)t!q#c&hMjvRSPeL99hisQdF6B??r!Kg+Khp4 z5A3?(hL}k=<=%#lNK5aMHwjn;E%$V*bAH?>d-k8i^` z&Sh@m*fJ??@K{xK)fgM_D`9k;nDivha;1&+Or_Ej>zxTzY3nB{kxOB{tf&%W2aVLv z8X?Yvb;N0H-7+yJ)+wr`b#yMRlY-B{fRC;#E$p5W%Um0w;^QXEgqnxe)uPBCcU)Fn z6l#hE24!*@7ecB%SgAo@Gx+z{4WP@viy=h$n%Y4er$wT59KR-iJzShrrC6-3$4-xFB+2<`mkQB5hTK7`Zh2^r||h~OmEZsbOxVK$81K= z?%o96;dMj%i%7A_*8}AM=rbT40c**Ms1IAf*^0IdKH359HuM(x5g#4!jNKu($T^kw z{$mBWxM>BLK#byZbDk=M`4$cCPV-!y!}Vcn=Z<;@CQDDP107ZGp?%NZM|F@@>ib0T zJFw6gi@>SxvwQUH?f*ITl`+J`N38I<9nI-By^ko9Nhttj!x%5ODNr8A@v|l=wmW^t z)dTReldGFdMN!1@PF?R}Xe_SBF4m+mTS%w-y=FeKVGq$mDb*P5_JP@hYu#bi$aMRk zu)`gh9@**ECTUEyR0&rMz28D_Pc~(}hUZaR|BJr#KG#lJ|MV>Uczd`{@Y!jsU`#`R I3-XZt4Q>NvP5=M^ literal 0 HcmV?d00001 diff --git a/subject1-4/AdaDiff/src/__pycache__/eval.cpython-311.pyc b/subject1-4/AdaDiff/src/__pycache__/eval.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..01bea26bc418915413e11ae24808c26a36b7fbc6 GIT binary patch literal 5172 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 literal 0 HcmV?d00001 diff --git a/subject1-4/AdaDiff/src/__pycache__/my_plotting.cpython-38.pyc b/subject1-4/AdaDiff/src/__pycache__/my_plotting.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..53d43d591a64e146329206513692bcb33cc27ef4 GIT binary patch literal 3488 zcmcH*OKcm*b!K+CTv8-O$&_tLl%=?KQl=IeSx)m)?Yd5URD@dThe$!JI74!&J44gdrI{nWTanJt+{d_{qjR)CX93Go`~X$v zPe3l(u3+Wv(AJLEX5#*6MzVpd9tZ~i3OR9raPMEfTg7@L~=wAp~9px=Wot^$zg7{~Z2^kp&AJ4`qnu0leh)?G}#nc%Wq0a#=4QuCP^hZS97z4~a zv0*m5hyczQm@_bMV8K9G({e7N@r6&&C%8rEEG>TQN+a_Tc~@&$no#D>Q5GhY`E!(u zqf+d=aHdN?MPU&m{m~2K;?Ge?eujW6{Q}qJ7r5pUuDJNv;)Qt5!0cnfe=qHBik9dC zb?C(->q9bL{LmgRjhDye@k+eZb>a*361}X0A4ci8Ko{v!GCFptO&6X{C}8JhTBa-X z$`M?(czKGt4C^kPty}J9=qjvSqc0svrJUngpx*_$=Ba!m&qey`WS{R%c;?$U&X>^mO1uJE%%17G za-63(p6aMtIWExk1OtvMaMndyr8RxlkQ*Dm_JR$q#D>}qayGv72+N{|##(S*mgXU*GvB_INeSCNodScva4I=i^nlCvWKZ zm-g|6coj0kn{fuvOj+RUSogl2W!`>H(NK>?r%&DGzs{oiC+z~YkQDD6K?-TGLRj^ zd#g1{!`j;25AG?_+E8g8HT6cyX>FK4-fwE9PMdyq^mB6oy0`|QjbikR@)(k34C$Ab z4^i@`ka{To4f&=006imIzryBp=E-)(D0#zG5q5J975^J*|&-3p?n7l_+{oO1p*s*3Wos=TZj8+s%T{yJ=@R@F3+=0mqyvyt( zpUTdNtgp8>P5a9oWkHx#2!92Zs#G%yB3>brb$@>T_sIs&NA6&-F5pcMphU31<|@Az zamu(iV509){<2-2s!ROEUt1vmrn;NTT;ATzX2G<41C{?3=uTf7oSU+lZ8Y8>f?YAon zDg`F*GcX054X&ymN|j1fw)%lot~l5;Td53`cMa*wfGJzg00}0Bf!~9mXKfZzm23Gy z(AZ=0Bd`>o(b_v+vRPI$4-!ine3;-?&kvQQuPBM2QtNs9jQU)twD2A>C>z0*K_pmZ zO{H{Q7pOG#qz9YTb8Q|SgtQ^~f$XUKq*7}LZBG7@mYs%ta}Y>TcRkkN464BTjCO1T zD#bo{N#9Xrfmu{WAE=@0GL;y zmv{roH(-DMx(07(NyKA(-H6oZvb@2D1~=;fHZ{1V2pq&|MFE6ka%tD}Vv|79T0_Z9 z1c=|kw5})};$oK+aSlEgx(%O;-^5G$BLtVQgR^J<9E{3V0oLWnJjvmLU4->T`x=JN z$&v!j!dJ4EU|k8S)uP4|e(NgmJGe*+2{$fgPx{(?NJy1_ zQ}As)k&+Q_c2p`n==Fz5^trsb0|D3*{C(gs<+sr=v98IBU*%|b3nJ_wV7K)PA#|yp P*tLjV3oJtlBwPL$Ch=%y literal 0 HcmV?d00001 diff --git a/subject1-4/AdaDiff/src/__pycache__/parser.cpython-311.pyc b/subject1-4/AdaDiff/src/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5bcd450fc7b64e07210ae7ac05001bb24d02b766 GIT binary patch literal 3226 zcmbW3&u`R56vxM#&3b{RM##1gKRBtwc|`th_t38yElT*qabv znq$=yx2iq$L{-5*(Ep)_fRM1}RH>)jQqdEqzGv?`jtW)W+3eW!=6&Wn^WL*Jzf>wk z0`1#f#(pmo@+S_4EkC$<^?jC*9|$E>GRPWUGlpbl)-n>w5JtWp83J_VY4)*1$P@TR zZ7s{PKaUPa$txYDIhLa`&C|lu;^Q1p@QqqmlE_=R5-o?E^l$Dzs0yuy)EGUIO6@2; z7INcsA{BRhz)5s6755IE3iWFAL@MqieK+Jz(f3ku(^O$HWZ^VDlZtzv&J4KORNPrQ z$MT`xd@8O^7gzx}nJ%W{&OshfPo?KmaSh;5?E-D4;w}#KF44=WxDN*0hxDUV+{eJ- zQ}hYFl8U@2Wt*C@rQBj3>v+0tfoF*_x5IS@hkij-spe@e^ZblT z?})Nv>z3E*8FpJUgglt5j|$mjp0=TJk@dD5Ci0wp)7Lqp;KRCF-|$3sof(dwQ`N3+ zFj%eY%c^SHlo>EE#qpKCXEUn<2Hv`*ce{NTH&6^c6iYLiUsP3(Yr3UdJwRZ^w(YI^ z)yTuMm2lD@Q&lZGR?F?!ocWc(P>F_FRW-Ojf?c-B)XRR^U>w&}xaNVks&48QwKrR? z?lbV)bVa6l!7oKtCA7jCP7~&wrjVK<1NUgTh?a{m#2fVi?D2s=Y4y!E%<0 zHPbPeiw+y$up#6P#@n{b{IaUHHLtTC>h5ks-b8WVfcwG)T83t}sn+}HM{K_>L%Q~@ z=w#Wt%UZ6-9Cw%EBBg`{gF{)uu#2@MDhF(smmatKjwrfJ$Pml*zzaCxGNUhRH9VaT(N8qL!wiEnmu%&*i2@5icXa-Oqx&*Iz&O?eappj_n6o6 z);V+6{TaAdHZ((t#){U1gez^<(fTe!x@UW*>t&JGc+b(e%S7d&X>g}=zGLX1!SN?n zR9ASfkCI=a3m3W2m5Z`QX$#13PK>x77o%On);uu+WsL=88=@FGqnj(T*#Ami!J_2# z^~Snwvc{Hf=vHG;RE@Y)2hUQ%aJ%91P9u^&?`*x!FF}0z2D{GdupIvKyI0}=g}o6; zk^(Ze9ex6GdgtKZ9|h&RsTT!hN4>jKSbbJleNkB5&IKg*l8iqm(57B z0=k=k#)Dcth87W8ME`S9w-4=1%qA$<+I&ncAhm!%h%P4gcPFSE8wLTS=3=OhP#vL= zTu4G+Bp^^a8$A1#=>wP32LWeXd0nuR8pdD|4@(q7j!!j2vBOqN|#XS z5{g`ox`a{$Rm1Hadvjt3)iAYR4fhTz9WJ{NJ*c}l5QmFi1VzOPXF3#guq4I~TN25V ztsPS8(Q0_8IDChTIb=6}0;@soN}Q-AOwCK-$l;>Q{f2N~&^yKN$1^dVX9Z{uu?qU*6b$ zx@6p?ulYL+0tg_K!HNHE$S`S~G{OLbM@?u#>uGq>!q%f5*nu{-p#xpmh2GQlJS2_h zeTYgPZg@opuvgLxaIvO-0bVTmOYm}yU#fTr`!)UwyjtpCgV$^P4S2KUm*K4%zXA+9 zl;u^pR^xBO^@`u9@ps@|?3ViXYJ3Rq<1Xs|xI6?jpb&Q4`rz#P0#qOiUnT=IS%08f(={WOdvCBCKD-7DA!QmSh zWhzeXWFgg5NY|-+!yVU2(27%`UCXXAbX|=<kp3igR6X=x+mWl+69_LnzIE~WTF`-0!epfTw{E*=x-=1 zDaFXfb1JvsE`kW4?}k15B;#eSM6Q`Ah&8PK7a5lJS|c)=+NPF?2|^;8)w zBF?A6&X(oA>z}A@u6GW6UOvD?iew66@ypNt`Qr|i>zsN~s$zo^V=*&p@Im@p#9t2J z7FhfDha1$GuggNKJaavRLi>yop!16qrmS=neX0Z+J5i}z75nAAvlP$RrW8uER9Sx| zF%(zuNk+|{Lj$v6)yfT zbE$-NO=@f3P)fR9DfTksT7LXJ&^IV*Is9`pTB-y`t60YAsOqfIvwp4qP+Q>Zk= 1) + 0 + result, fprs, tprs = evaluate(lossFinal, labelsFinal) + result_roc = result["ROC/AUC"] + result_f1 = result["f1"] + wandb.log({'roc': result_roc, 'f1': result_f1}, step=e) + if result_f1 > f1_max: + save_model(None, experiment, diffusion_prediction_net, optimizer, None, -1, e, train_loss, None) + f1_max = result_f1 + validation_thresh = result['threshold'] + wandb.run.summary["best_f1"] = f1_max + wandb.run.summary["roc_for_best_f1"] = result_roc + wandb.run.summary["best_f1_epoch"] = e + wandb.run.summary["validation_thresh"] = validation_thresh + if result_roc > roc_max: + roc_max = result_roc + wandb.run.summary["f1_for_best_roc"] = result_f1 + wandb.run.summary["best_roc"] = roc_max + wandb.run.summary["best_roc_epoch"] = e + wandb.log({'roc': result_roc, 'f1': result_f1}, step=e) + if e % 100 == 0: + for dim in range(0, feats): + plotter(f'{experiment}_VAL', args.dataset, validationD.reshape(-1, feats), lossFinal, labelsFinal, result, None, samples.reshape(-1, feats), None, dim=dim, plot_test=True, epoch=e) + if args.v: + print(f"testing loss #{e}: {loss0.mean()}") + # print(f"training loss #{e}: {loss1.mean()}") + print(f"final ROC #{e}: {result_roc}") + print(f"F1 #{e}: {result_f1}") + + # TEST ON TEST SET + #load model from checkpoint + model, diffusion_training_net, diffusion_prediction_net, optimizer, scheduler = \ + load_model(training_mode ,args.lr, args.window_size, args.p1, args.p2, labels.shape[1], args.batch_size, args.noise_steps, args.denoise_steps) + model, diffusion_training_net = load_from_checkpoint(training_mode, experiment, model, diffusion_training_net) + if model: + model = model.to(device) + + diffusion_training_net = diffusion_training_net.to(device) + diffusion_prediction_net = diffusion_prediction_net.to(device) + # pass test set through the model + if model: + if args.test_only: + #test again on val for double check + get best thresh on validation set to use for test + loss0, val_loss, ae_loss_val, diff_loss_val, samples, recons = backprop(e, model, diffusion_training_net, diffusion_prediction_net, validationD, args.diff_lambda, optimizer, scheduler, training_mode, args.anomaly_score, args.k, training=False) + loss0 = loss0.reshape(-1,feats) + + lossFinal = np.mean(np.array(loss0), axis=1) + # lossFinal = np.max(np.array(loss0), axis=1) + labelsFinal = (np.sum(validation_labels, axis=1) >= 1) + 0 + + result, fprs, tprs = evaluate(lossFinal, labelsFinal) + validation_thresh = result['threshold'] + result_roc = result["ROC/AUC"] + result_f1 = result["f1"] + wandb.run.summary["f1_val"] = result_f1 + wandb.run.summary["roc_val"] = result_roc + wandb.run.summary["f1_pa_val"] = result['f1_max'] + wandb.run.summary["roc_pa_val"] = result['roc_max'] + wandb.run.summary["val_loss"] = val_loss + wandb.run.summary["ae_loss_val"] = ae_loss_val + wandb.run.summary["diff_loss_val"] = diff_loss_val + + # for dim in range(0, feats): + # fig = plotter(f'{experiment}_VAL', args.anomaly_score, validationD.reshape(-1, feats), lossFinal, labelsFinal, result, recons.reshape(-1, feats), samples.reshape(-1, feats), None, dim=dim, plot_test=True, epoch=e) + + loss0, test_loss, ae_loss_test, diff_loss_test, samples, recons = backprop(e, model, diffusion_training_net, diffusion_prediction_net, testD, args.diff_lambda, optimizer, scheduler, training_mode, args.anomaly_score, args.k, training=False) + loss0 = loss0.reshape(-1,feats) + + lossFinal = np.mean(np.array(loss0), axis=1) + # np.save(f'{args.dataset}_{args.anomaly_score}_score_scores.npy', lossFinal) + # np.save(f'{args.dataset}_{args.anomaly_score}_score_recons.npy', samples) + # # np.save('/root/Diff-Anomaly/TranAD/plots_for_paper/shapelet_scores_for_example.npy', lossFinal) + # lossFinal = np.max(np.array(loss0), axis=1) + labelsFinal = (np.sum(labels, axis=1) >= 1) + 0 + #validation_thresh = 0.0019 + result = evaluate(lossFinal, labelsFinal) + result_roc = result["ROC/AUC"] + result_f1 = result["f1"] + wandb.run.summary["f1_test"] = result_f1 + wandb.run.summary["roc_test"] = result_roc + wandb.run.summary["f1_pa_test"] = result['f1_max'] + #wandb.run.summary["roc_pa_test"] = result['roc_max'] + wandb.run.summary["test_loss"] = test_loss + wandb.run.summary["ae_loss_test"] = ae_loss_test + wandb.run.summary["diff_loss_test"] = diff_loss_test + wandb.run.summary["validation_thresh"] = validation_thresh + + #for dim in range(0, feats): + # fig = plotter(f'{experiment}_TEST', args.anomaly_score, testD.reshape(-1, feats), lossFinal, labelsFinal, result, recons.reshape(-1, feats), samples.reshape(-1, feats), None, dim=dim, plot_test=True, epoch=e) + + else: + if args.test_only: + loss0, _, _, val_loss, samples = backprop(e, model, diffusion_training_net, diffusion_prediction_net, validationD, args.diff_lambda, optimizer, scheduler, training_mode, args.anomaly_score, args.k, training=False) + loss0 = loss0.reshape(-1,feats) + + lossFinal = np.mean(np.array(loss0), axis=1) + labelsFinal = (np.sum(validation_labels, axis=1) >= 1) + 0 + + result, fprs, tprs = evaluate(lossFinal, labelsFinal) + result_roc = result["ROC/AUC"] + result_f1 = result["f1"] + validation_thresh = result['threshold'] + wandb.run.summary["f1_val"] = result_f1 + wandb.run.summary["roc_val"] = result_roc + wandb.run.summary["f1_pa_val"] = result['f1_max'] + #wandb.run.summary["roc_pa_val"] = result['roc_max'] + wandb.run.summary["val_loss"] = val_loss + wandb.run.summary["validation_thresh"] = validation_thresh + #for dim in range(0, feats): + # plotter(f'{experiment}_VAL', args.dataset, validationD.reshape(-1, feats), lossFinal, labelsFinal, result, None, samples.reshape(-1, feats), None, dim=dim, plot_test=True, epoch=e) + loss0, _, _, test_loss, samples = backprop(e, model, diffusion_training_net, diffusion_prediction_net, testD, args.diff_lambda, optimizer, scheduler, training_mode, args.anomaly_score, args.k, training=False) + loss0 = loss0.reshape(-1,feats) + + lossFinal = np.mean(np.array(loss0), axis=1) + # np.save(f'{args.dataset}_diff_only_scores.npy', lossFinal) + # np.save(f'{args.dataset}_diff_only_recons.npy', samples) + # labelsFinal = (np.sum(labels, axis=1) >= 1) + 0 + + result = evaluate(lossFinal, labelsFinal, validation_thresh=validation_thresh) + result_roc = result["ROC/AUC"] + result_f1 = result["f1"] + #for dim in range(0, feats): + # plotter(f'{experiment}_TEST', args.dataset, testD.reshape(-1, feats), lossFinal, labelsFinal, result, None, samples.reshape(-1, feats), None, dim=dim, plot_test=True, epoch=e) + wandb.run.summary["f1_test"] = result_f1 + wandb.run.summary["roc_test" ] = result_roc + wandb.run.summary["f1_pa_test"] = result['f1_max'] + wandb.run.summary["roc_pa_test"] = result['roc_max'] + wandb.run.summary["test_loss"] = test_loss + + wandb.finish() diff --git a/subject1-4/AdaDiff/unet2.py b/subject1-4/AdaDiff/unet2.py new file mode 100644 index 0000000..5a798f9 --- /dev/null +++ b/subject1-4/AdaDiff/unet2.py @@ -0,0 +1,399 @@ +import math +from inspect import isfunction +from functools import partial + +import matplotlib.pyplot as plt +from tqdm.auto import tqdm +from einops import rearrange, reduce +from einops.layers.torch import Rearrange + +import torch +from torch import nn, einsum +import torch.nn.functional as F +import math + + +def exists(x): + return x is not None + +def default(val, d): + if exists(val): + return val + return d() if isfunction(d) else d + + +def num_to_groups(num, divisor): + groups = num // divisor + remainder = num % divisor + arr = [divisor] * groups + if remainder > 0: + arr.append(remainder) + return arr + + +class Residual(nn.Module): + def __init__(self, fn): + super().__init__() + self.fn = fn + + def forward(self, x, *args, **kwargs): + return self.fn(x, *args, **kwargs) + x + + +# def Upsample(dim, dim_out=None): +# return nn.Sequential( +# nn.Upsample(scale_factor=2, mode="nearest"), +# nn.Conv2d(dim, default(dim_out, dim), 3, padding=1), +# ) + +def Upsample(dim_out, dim, size): + return nn.Sequential( + nn.Upsample(size=[size[0][1], size[0][2]], mode="nearest"), + nn.Conv2d(dim_out, default(dim, dim_out), 3, padding=1), + ) + + + +# def Downsample(dim, dim_out=None): +# # No More Strided Convolutions or Pooling +# return nn.Sequential( +# Rearrange("b c (h p1) (w p2) -> b (c p1 p2) h w", p1=2, p2=2), +# nn.Conv2d(dim * 4, default(dim_out, dim), 1), +# ) + +# class Downsample(nn.Module): +# def __init__(self, dim_in, dim_out, size): +# super().__init__() +# self.dim_in = dim_in +# self.dim_out = dim_out +# self.size = size +# self.original = self.size[0] * self.size[1] * self.size[2] +# self.left_out = int(self.original/((self.size[1] // 2) * (self.size[2]// 2)) - 4*self.size[0]) + +# #self.left_out = self.original // ((self.size[1] // 2) * (self.size[2]// 2)) - 4*self.size[0] +# self.conv = nn.Conv2d(dim_in * 4 + self.left_out, default(self.dim_out, self.dim_in), 1) + +# def forward(self, x): +# x = x.reshape(-1, self.dim_in*4 + self.left_out, self.size[1] // 2, self.size[2] // 2) +# x = self.conv(x) +# return x + +# class Downsample(nn.Module): +# def __init__(self, dim_in, dim_out, size): +# super().__init__() +# self.dim_in = dim_in +# self.dim_out = dim_out +# self.size = size +# self.intermediate_channels = F.interpolate(torch.rand(size).unsqueeze(0).cpu(), (self.size[1] // 2, self.size[2] // 2)).shape[1] +# self.conv = nn.Conv2d(self.intermediate_channels, default(self.dim_out, self.dim_in), 1) + +# def forward(self, x): +# x = F.interpolate(x, (self.size[1] // 2, self.size[2] // 2)) +# x = self.conv(x) +# return x + +class Downsample(nn.Module): + def __init__(self, dim_in, dim_out, size): + super().__init__() + self.dim_in = dim_in + self.dim_out = dim_out + self.size = size + self.pad = nn.ZeroPad2d((0, self.size[-1] % 2, 0, self.size[-2] % 2)) + self.conv = nn.Conv2d(dim_in * 4, default(self.dim_out, self.dim_in), 1) + self.padded_size = (self.size[0], self.size[1] + self.size[1] % 2, self.size[2] + self.size[2] % 2) + + def forward(self, x): + # h, w = self.size[-2], self.size[-1] + # h_pad, w_pad = h % 2, w % 2 + x = self.pad(x) + x = x.reshape(-1, self.dim_in*4, self.padded_size[1] // 2, self.padded_size[2] // 2) + x = self.conv(x) + return x + + + +class SinusoidalPositionEmbeddings(nn.Module): + def __init__(self, dim): + super().__init__() + self.dim = dim + + def forward(self, time): + device = time.device + half_dim = self.dim // 2 + embeddings = math.log(10000) / max((half_dim - 1), 1) + embeddings = torch.exp(torch.arange(half_dim, device=device) * -embeddings) + embeddings = time[:, None] * embeddings[None, :] + embeddings = torch.cat((embeddings.sin(), embeddings.cos()), dim=-1) + return embeddings + + +class WeightStandardizedConv2d(nn.Conv2d): + """ + https://arxiv.org/abs/1903.10520 + weight standardization purportedly works synergistically with group normalization + """ + + def forward(self, x): + eps = 1e-5 if x.dtype == torch.float32 else 1e-3 + + weight = self.weight + mean = reduce(weight, "o ... -> o 1 1 1", "mean") + var = reduce(weight, "o ... -> o 1 1 1", partial(torch.var, unbiased=False)) + normalized_weight = (weight - mean) * (var + eps).rsqrt() + + return F.conv2d( + x, + normalized_weight, + self.bias, + self.stride, + self.padding, + self.dilation, + self.groups, + ) + + +class Block(nn.Module): + def __init__(self, dim, dim_out, groups=8): + super().__init__() + self.proj = WeightStandardizedConv2d(dim, dim_out, 3, padding=1) + self.norm = nn.GroupNorm(groups, dim_out) + self.act = nn.SiLU() + + def forward(self, x, scale_shift=None): + x = self.proj(x) + x = self.norm(x) + + if exists(scale_shift): + scale, shift = scale_shift + x = x * (scale + 1) + shift + + x = self.act(x) + return x + + +class ResnetBlock(nn.Module): + """https://arxiv.org/abs/1512.03385""" + + def __init__(self, dim, dim_out, *, time_emb_dim=None, groups=8): + super().__init__() + self.mlp = ( + nn.Sequential(nn.SiLU(), nn.Linear(time_emb_dim, dim_out * 2)) + if exists(time_emb_dim) + else None + ) + + self.block1 = Block(dim, dim_out, groups=groups) + self.block2 = Block(dim_out, dim_out, groups=groups) + self.res_conv = nn.Conv2d(dim, dim_out, 1) if dim != dim_out else nn.Identity() + + def forward(self, x, time_emb=None): + scale_shift = None + if exists(self.mlp) and exists(time_emb): + time_emb = self.mlp(time_emb) + time_emb = rearrange(time_emb, "b c -> b c 1 1") + scale_shift = time_emb.chunk(2, dim=1) + + h = self.block1(x, scale_shift=scale_shift) + h = self.block2(h) + return h + self.res_conv(x) + +class Attention(nn.Module): + def __init__(self, dim, heads=4, dim_head=32): + super().__init__() + self.scale = dim_head**-0.5 + self.heads = heads + hidden_dim = dim_head * heads + self.to_qkv = nn.Conv2d(dim, hidden_dim * 3, 1, bias=False) + self.to_out = nn.Conv2d(hidden_dim, dim, 1) + + def forward(self, x): + b, c, h, w = x.shape + qkv = self.to_qkv(x).chunk(3, dim=1) + q, k, v = map( + lambda t: rearrange(t, "b (h c) x y -> b h c (x y)", h=self.heads), qkv + ) + q = q * self.scale + + sim = einsum("b h d i, b h d j -> b h i j", q, k) + sim = sim - sim.amax(dim=-1, keepdim=True).detach() + attn = sim.softmax(dim=-1) + + out = einsum("b h i j, b h d j -> b h i d", attn, v) + out = rearrange(out, "b h (x y) d -> b (h d) x y", x=h, y=w) + return self.to_out(out) + +class LinearAttention(nn.Module): + def __init__(self, dim, heads=4, dim_head=32): + super().__init__() + self.scale = dim_head**-0.5 + self.heads = heads + hidden_dim = dim_head * heads + self.to_qkv = nn.Conv2d(dim, hidden_dim * 3, 1, bias=False) + + self.to_out = nn.Sequential(nn.Conv2d(hidden_dim, dim, 1), + nn.GroupNorm(1, dim)) + + def forward(self, x): + b, c, h, w = x.shape + qkv = self.to_qkv(x).chunk(3, dim=1) + q, k, v = map( + lambda t: rearrange(t, "b (h c) x y -> b h c (x y)", h=self.heads), qkv + ) + + q = q.softmax(dim=-2) + k = k.softmax(dim=-1) + + q = q * self.scale + context = torch.einsum("b h d n, b h e n -> b h d e", k, v) + + out = torch.einsum("b h d e, b h d n -> b h e n", context, q) + out = rearrange(out, "b h c (x y) -> b (h c) x y", h=self.heads, x=h, y=w) + return self.to_out(out) + +class PreNorm(nn.Module): + def __init__(self, dim, fn): + super().__init__() + self.fn = fn + self.norm = nn.GroupNorm(1, dim) + + def forward(self, x): + x = self.norm(x) + return self.fn(x) + + +class Unet(nn.Module): + def __init__( + self, + dim, + init_size=None, + init_dim=None, + out_dim=None, + dim_mults=(1, 2, 4), + channels=3, + self_condition=False, + resnet_block_groups=4, + ): + super().__init__() + + # determine dimensions + self.init_size = init_size + self.channels = channels + self.self_condition = self_condition + input_channels = channels * (2 if self_condition else 1) + + init_dim = default(init_dim, dim) + # print(input_channels) + # print(init_dim) + # print(init_size) + self.init_conv = nn.Conv2d(input_channels, init_dim, 1, padding=0) # changed to 1 and 0 from 7,3 + + dims = [init_dim, *map(lambda m: dim * m, dim_mults)] + in_out = list(zip(dims[:-1], dims[1:])) + + block_klass = partial(ResnetBlock, groups=resnet_block_groups) + + # time embeddings + time_dim = dim * 4 + + self.time_mlp = nn.Sequential( + SinusoidalPositionEmbeddings(dim), + nn.Linear(dim-1, time_dim), + nn.GELU(), + nn.Linear(time_dim, time_dim), + ) + + # layers + self.downs = nn.ModuleList([]) + self.ups = nn.ModuleList([]) + num_resolutions = len(in_out) + sampling_sizes = [] + + for ind, (dim_in, dim_out) in enumerate(in_out): + is_last = ind >= (num_resolutions - 1) + size = init_size if ind == 0 else torch.Size([dim_in, (last_size[1] + last_size[1] % 2) // 2, (last_size[2] + last_size[2] % 2) // 2]) + last_size = size + sampling_sizes.append((size, dim_out)) + self.downs.append( + nn.ModuleList( + [ + block_klass(dim_in, dim_in, time_emb_dim=time_dim), + block_klass(dim_in, dim_in, time_emb_dim=time_dim), + Residual(PreNorm(dim_in, LinearAttention(dim_in))), + Downsample(dim_in, dim_out, size) + if not is_last + else nn.Conv2d(dim_in, dim_out, 3, padding=1), + ] + ) + ) + + mid_dim = dims[-1] + self.mid_block1 = block_klass(mid_dim, mid_dim, time_emb_dim=time_dim) + self.mid_attn = Residual(PreNorm(mid_dim, Attention(mid_dim))) + self.mid_block2 = block_klass(mid_dim, mid_dim, time_emb_dim=time_dim) + sampling_sizes = list(reversed(sampling_sizes))[1:] + for ind, (dim_in, dim_out) in enumerate(reversed(in_out)): + is_last = ind == (len(in_out) - 1) + + self.ups.append( + nn.ModuleList( + [ + block_klass(dim_out + dim_in, dim_out, time_emb_dim=time_dim), + block_klass(dim_out + dim_in, dim_out, time_emb_dim=time_dim), + Residual(PreNorm(dim_out, LinearAttention(dim_out))), + #Upsample(dim_out, dim_in) + Upsample(dim_out, dim_in, sampling_sizes[ind]) + if not is_last + else nn.Conv2d(dim_out, dim_in, 3, padding=1), + ] + ) + ) + + self.out_dim = default(out_dim, channels) + + self.final_res_block = block_klass(dim * 2, dim, time_emb_dim=time_dim) + self.final_conv = nn.Conv2d(dim, self.out_dim, 1) + + def forward(self, x, time, x_self_cond=None): + import numpy as np + # print(np.shape(x)) + if self.self_condition: + x_self_cond = default(x_self_cond, lambda: torch.zeros_like(x)) + x = torch.cat((x_self_cond, x), dim=1) + + x = self.init_conv(x) + r = x.clone() + + t = self.time_mlp(time) + + h = [] + + for block1, block2, attn, downsample in self.downs: + x = block1(x, t) + h.append(x) + + x = block2(x, t) + x = attn(x) + h.append(x) + + x = downsample(x) + + x = self.mid_block1(x, t) + #h.append(x) + x = self.mid_attn(x) + x = self.mid_block2(x, t) + #h.append(x) + + for block1, block2, attn, upsample in self.ups: + x = torch.cat((x, h.pop()), dim=1) + x = block1(x, t) + + x = torch.cat((x, h.pop()), dim=1) + x = block2(x, t) + x = attn(x) + + x = upsample(x) + + x = torch.cat((x, r), dim=1) + + x = self.final_res_block(x, t) + return self.final_conv(x) \ No newline at end of file -- Gitee From 03e53dec95974159e620cb9c3e3f972b0b207207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BA=E9=A3=8E?= <12348188+tailwind_123@user.noreply.gitee.com> Date: Fri, 9 May 2025 14:49:41 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=AD=90=E8=AF=BE=E9=A2=981.4=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/msl_time_test.json | 71 ++++ .../config/msl_time_train.json | 80 ++++ .../config/psm_time_test.json | 71 ++++ .../config/psm_time_train.json | 80 ++++ .../config/smap_time_test.json | 71 ++++ .../config/smap_time_train.json | 80 ++++ .../config/smd_time_test.json | 71 ++++ .../config/smd_time_train.json | 80 ++++ .../core/__pycache__/logger.cpython-311.pyc | Bin 0 -> 8065 bytes .../core/__pycache__/logger.cpython-37.pyc | Bin 0 -> 4147 bytes .../core/__pycache__/logger.cpython-38.pyc | Bin 0 -> 4171 bytes .../core/__pycache__/metrics.cpython-311.pyc | Bin 0 -> 8902 bytes .../core/__pycache__/metrics.cpython-37.pyc | Bin 0 -> 4340 bytes .../core/__pycache__/metrics.cpython-38.pyc | Bin 0 -> 4358 bytes .../02DiffAD-main_high/core/logger.py | 143 +++++++ .../02DiffAD-main_high/core/metrics.py | 169 +++++++++ .../02DiffAD-main_high/data/LRHR_dataset.py | 43 +++ .../02DiffAD-main_high/data/__init__.py | 42 ++ .../__pycache__/LRHR_dataset.cpython-311.pyc | Bin 0 -> 2619 bytes .../__pycache__/LRHR_dataset.cpython-37.pyc | Bin 0 -> 1611 bytes .../__pycache__/LRHR_dataset.cpython-38.pyc | Bin 0 -> 1609 bytes .../data/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 2140 bytes .../data/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1286 bytes .../data/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 1296 bytes .../prepare_time_data.cpython-311.pyc | Bin 0 -> 19630 bytes .../prepare_time_data.cpython-37.pyc | Bin 0 -> 8719 bytes .../prepare_time_data.cpython-38.pyc | Bin 0 -> 8676 bytes .../data/prepare_time_data.py | 355 +++++++++++++++++ .../02DiffAD-main_high/model/__init__.py | 10 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 696 bytes .../model/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 469 bytes .../model/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 447 bytes .../__pycache__/base_model.cpython-311.pyc | Bin 0 -> 3008 bytes .../__pycache__/base_model.cpython-37.pyc | Bin 0 -> 2041 bytes .../__pycache__/base_model.cpython-38.pyc | Bin 0 -> 2055 bytes .../model/__pycache__/model.cpython-311.pyc | Bin 0 -> 12814 bytes .../model/__pycache__/model.cpython-37.pyc | Bin 0 -> 5358 bytes .../model/__pycache__/model.cpython-38.pyc | Bin 0 -> 5434 bytes .../__pycache__/networks.cpython-311.pyc | Bin 0 -> 6830 bytes .../model/__pycache__/networks.cpython-37.pyc | Bin 0 -> 3177 bytes .../model/__pycache__/networks.cpython-38.pyc | Bin 0 -> 3165 bytes .../02DiffAD-main_high/model/base_model.py | 47 +++ .../02DiffAD-main_high/model/model.py | 175 +++++++++ .../02DiffAD-main_high/model/networks.py | 112 ++++++ .../__pycache__/diffusion.cpython-311.pyc | Bin 0 -> 16437 bytes .../__pycache__/diffusion.cpython-37.pyc | Bin 0 -> 7556 bytes .../__pycache__/diffusion.cpython-38.pyc | Bin 0 -> 7735 bytes .../__pycache__/unet.cpython-311.pyc | Bin 0 -> 16113 bytes .../__pycache__/unet.cpython-37.pyc | Bin 0 -> 8276 bytes .../__pycache__/unet.cpython-38.pyc | Bin 0 -> 8164 bytes .../model/sr3_modules/diffusion.py | 284 ++++++++++++++ .../model/sr3_modules/unet.py | 274 +++++++++++++ .../02DiffAD-main_high/requirements.txt | 7 + .../02DiffAD-main_high/server2.py | 44 +++ .../02DiffAD-main_high/test_split.py | 163 ++++++++ .../02DiffAD-main_high/time_test.py | 133 +++++++ .../02DiffAD-main_high/time_train.py | 87 +++++ .../dynamicSplit/02DiffAD-main_low/client2.py | 29 ++ .../config/msl_time_test.json | 71 ++++ .../config/msl_time_train.json | 80 ++++ .../config/psm_time_test.json | 71 ++++ .../config/psm_time_train.json | 80 ++++ .../config/smap_time_test.json | 71 ++++ .../config/smap_time_train.json | 80 ++++ .../config/smd_time_test.json | 71 ++++ .../config/smd_time_train.json | 80 ++++ .../core/__pycache__/logger.cpython-37.pyc | Bin 0 -> 4123 bytes .../core/__pycache__/logger.cpython-38.pyc | Bin 0 -> 4171 bytes .../core/__pycache__/metrics.cpython-37.pyc | Bin 0 -> 4324 bytes .../core/__pycache__/metrics.cpython-38.pyc | Bin 0 -> 4358 bytes .../02DiffAD-main_low/core/logger.py | 143 +++++++ .../02DiffAD-main_low/core/metrics.py | 169 +++++++++ .../02DiffAD-main_low/data/LRHR_dataset.py | 43 +++ .../02DiffAD-main_low/data/__init__.py | 42 ++ .../__pycache__/LRHR_dataset.cpython-37.pyc | Bin 0 -> 1587 bytes .../__pycache__/LRHR_dataset.cpython-38.pyc | Bin 0 -> 1609 bytes .../data/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1262 bytes .../data/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 1296 bytes .../prepare_time_data.cpython-37.pyc | Bin 0 -> 8695 bytes .../prepare_time_data.cpython-38.pyc | Bin 0 -> 8676 bytes .../data/prepare_time_data.py | 359 ++++++++++++++++++ .../02DiffAD-main_low/model/__init__.py | 10 + .../model/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 445 bytes .../model/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 447 bytes .../__pycache__/base_model.cpython-37.pyc | Bin 0 -> 2017 bytes .../__pycache__/base_model.cpython-38.pyc | Bin 0 -> 2055 bytes .../model/__pycache__/model.cpython-37.pyc | Bin 0 -> 5353 bytes .../model/__pycache__/model.cpython-38.pyc | Bin 0 -> 5434 bytes .../model/__pycache__/networks.cpython-37.pyc | Bin 0 -> 3153 bytes .../model/__pycache__/networks.cpython-38.pyc | Bin 0 -> 3165 bytes .../02DiffAD-main_low/model/base_model.py | 47 +++ .../02DiffAD-main_low/model/model.py | 175 +++++++++ .../02DiffAD-main_low/model/networks.py | 112 ++++++ .../__pycache__/diffusion.cpython-37.pyc | Bin 0 -> 7979 bytes .../__pycache__/diffusion.cpython-38.pyc | Bin 0 -> 7735 bytes .../__pycache__/unet.cpython-37.pyc | Bin 0 -> 8252 bytes .../__pycache__/unet.cpython-38.pyc | Bin 0 -> 8164 bytes .../model/sr3_modules/diffusion.py | 273 +++++++++++++ .../model/sr3_modules/unet.py | 274 +++++++++++++ .../02DiffAD-main_low/requirements.txt | 7 + .../dynamicSplit/02DiffAD-main_low/server2.py | 38 ++ .../02DiffAD-main_low/test_split.py | 164 ++++++++ .../02DiffAD-main_low/time_test.py | 133 +++++++ .../02DiffAD-main_low/time_train.py | 87 +++++ subject1-4/dynamicSplit/README.md | 69 ++++ 105 files changed, 5470 insertions(+) create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/config/msl_time_test.json create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/config/msl_time_train.json create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/config/psm_time_test.json create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/config/psm_time_train.json create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/config/smap_time_test.json create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/config/smap_time_train.json create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/config/smd_time_test.json create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/config/smd_time_train.json create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/core/__pycache__/logger.cpython-311.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/core/__pycache__/logger.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/core/__pycache__/logger.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/core/__pycache__/metrics.cpython-311.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/core/__pycache__/metrics.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/core/__pycache__/metrics.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/core/logger.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/core/metrics.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/data/LRHR_dataset.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/data/__init__.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/LRHR_dataset.cpython-311.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/LRHR_dataset.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/LRHR_dataset.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/__init__.cpython-311.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/__init__.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/__init__.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/prepare_time_data.cpython-311.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/prepare_time_data.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/prepare_time_data.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/data/prepare_time_data.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/__init__.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/__init__.cpython-311.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/__init__.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/__init__.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/base_model.cpython-311.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/base_model.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/base_model.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/model.cpython-311.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/model.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/model.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/networks.cpython-311.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/networks.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/networks.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/base_model.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/model.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/networks.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/diffusion.cpython-311.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/diffusion.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/diffusion.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/unet.cpython-311.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/unet.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/unet.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/diffusion.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/unet.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/requirements.txt create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/server2.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/test_split.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/time_test.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_high/time_train.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/client2.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/config/msl_time_test.json create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/config/msl_time_train.json create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/config/psm_time_test.json create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/config/psm_time_train.json create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/config/smap_time_test.json create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/config/smap_time_train.json create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/config/smd_time_test.json create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/config/smd_time_train.json create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/core/__pycache__/logger.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/core/__pycache__/logger.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/core/__pycache__/metrics.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/core/__pycache__/metrics.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/core/logger.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/core/metrics.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/data/LRHR_dataset.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/data/__init__.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/data/__pycache__/LRHR_dataset.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/data/__pycache__/LRHR_dataset.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/data/__pycache__/__init__.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/data/__pycache__/__init__.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/data/__pycache__/prepare_time_data.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/data/__pycache__/prepare_time_data.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/data/prepare_time_data.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/__init__.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/__init__.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/__init__.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/base_model.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/base_model.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/model.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/model.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/networks.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/networks.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/base_model.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/model.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/networks.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/__pycache__/diffusion.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/__pycache__/diffusion.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/__pycache__/unet.cpython-37.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/__pycache__/unet.cpython-38.pyc create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/diffusion.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/unet.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/requirements.txt create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/server2.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/test_split.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/time_test.py create mode 100644 subject1-4/dynamicSplit/02DiffAD-main_low/time_train.py create mode 100644 subject1-4/dynamicSplit/README.md diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/config/msl_time_test.json b/subject1-4/dynamicSplit/02DiffAD-main_high/config/msl_time_test.json new file mode 100644 index 0000000..bb9a3a7 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/config/msl_time_test.json @@ -0,0 +1,71 @@ +{ + "name": "MSL_TEST", + "phase": "test", + "gpu_ids": [ + 0 + ], + "path": { + "log": "logs", + "tb_logger": "tb_logger", + "results": "results", + "checkpoint": "checkpoint", + "resume_state": "//experiments/MSL_TRAIN_16_128_20/checkpoint/E100" + }, + "datasets": { + "test": { + "name": "msl_test", + "mode": "HR", + "dataroot": "//02DiffAD-main/tf_dataset/msl/msl_test.csv", + "datatype": "time", + "l_resolution": 16, + "r_resolution": 128, + "data_len": -1 + } + }, + "model": { + "which_model_G": "sr3", + "finetune_norm": false, + "unet": { + "in_channel": 2, + "out_channel": 1, + "inner_channel": 32, + "norm_groups": 16, + "channel_multiplier": [ + 1, + 2, + 4, + 8, + 16 + ], + "attn_res": [], + "res_blocks": 1, + "dropout": 0 + }, + "beta_schedule": { + "train": { + "schedule": "linear", + "n_timestep": 20, + "linear_start": 1e-6, + "linear_end": 1e-2 + }, + "test": { + "schedule": "linear", + "start_label": 1, + "end_label": 2001, + "step_label": 1, + "step_t": 1000, + "n_timestep": 100, + "linear_start": 1e-6, + "linear_end": 1e-2 + } + }, + "diffusion": { + "time_size": 128, + "channels": 1, + "conditional": true + } + }, + "wandb": { + "project": "distributed_time" + } +} \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/config/msl_time_train.json b/subject1-4/dynamicSplit/02DiffAD-main_high/config/msl_time_train.json new file mode 100644 index 0000000..8440faa --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/config/msl_time_train.json @@ -0,0 +1,80 @@ +{ + "name": "MSL_TRAIN", + "phase": "train", + "gpu_ids": [ + 1, + 3 + ], + "path": { + "log": "logs", + "tb_logger": "tb_logger", + "results": "results", + "checkpoint": "checkpoint", + "resume_state": null + }, + "datasets": { + "train": { + "name": "msl_train", + "mode": "HR", + "dataroot": "//02DiffAD-main/tf_dataset/msl/msl_train.csv", + "datatype": "time", + "l_resolution": 16, + "r_resolution": 128, + "batch_size": 32, + "num_workers": 4, + "use_shuffle": false, + "data_len": -1 + } + }, + "model": { + "which_model_G": "sr3", + "finetune_norm": false, + "unet": { + "in_channel": 2, + "out_channel": 1, + "inner_channel": 32, + "norm_groups": 16, + "channel_multiplier": [ + 1, + 2, + 4, + 8, + 16 + ], + "attn_res": [], + "res_blocks": 1, + "dropout": 0 + }, + "beta_schedule": { + "train": { + "schedule": "linear", + "n_timestep": 20, + "linear_start": 1e-6, + "linear_end": 1e-2 + } + }, + "diffusion": { + "time_size": 128, + "channels": 1, + "conditional": true + } + }, + "train": { + "n_epoch": 100, + "val_freq": 100, + "save_checkpoint_freq": 100, + "print_freq": 10, + "optimizer": { + "type": "adam", + "lr": 3e-6 + }, + "ema_scheduler": { + "step_start_ema": 5000, + "update_ema_every": 1, + "ema_decay": 0.9999 + } + }, + "wandb": { + "project": "distributed_time" + } +} \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/config/psm_time_test.json b/subject1-4/dynamicSplit/02DiffAD-main_high/config/psm_time_test.json new file mode 100644 index 0000000..a78f9da --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/config/psm_time_test.json @@ -0,0 +1,71 @@ +{ + "name": "PSM_TEST", + "phase": "test", + "gpu_ids": [ + 0 + ], + "path": { + "log": "logs", + "tb_logger": "tb_logger", + "results": "results", + "checkpoint": "checkpoint", + "resume_state": "experiments/PSM_TRAIN_16_128_100/checkpoint/E20" + }, + "datasets": { + "test": { + "name": "psm_test", + "mode": "HR", + "dataroot": "tf_dataset/psm/psm_test.csv", + "datatype": "time", + "l_resolution": 16, + "r_resolution": 128, + "data_len": -1 + } + }, + "model": { + "which_model_G": "sr3", + "finetune_norm": false, + "unet": { + "in_channel": 2, + "out_channel": 1, + "inner_channel": 32, + "norm_groups": 16, + "channel_multiplier": [ + 1, + 2, + 4, + 8, + 16 + ], + "attn_res": [], + "res_blocks": 1, + "dropout": 0 + }, + "beta_schedule": { + "train": { + "schedule": "linear", + "n_timestep": 100, + "linear_start": 1e-6, + "linear_end": 1e-2 + }, + "test": { + "schedule": "linear", + "start_label": 1, + "end_label": 2001, + "step_label": 1, + "step_t": 1000, + "n_timestep": 100, + "linear_start": 1e-6, + "linear_end": 1e-2 + } + }, + "diffusion": { + "time_size": 128, + "channels": 1, + "conditional": true + } + }, + "wandb": { + "project": "distributed_time" + } +} \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/config/psm_time_train.json b/subject1-4/dynamicSplit/02DiffAD-main_high/config/psm_time_train.json new file mode 100644 index 0000000..c9cd489 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/config/psm_time_train.json @@ -0,0 +1,80 @@ +{ + "name": "PSM_TRAIN", + "phase": "train", + "gpu_ids": [ + 0, + 1 + ], + "path": { + "log": "logs", + "tb_logger": "tb_logger", + "results": "results", + "checkpoint": "checkpoint", + "resume_state": null + }, + "datasets": { + "train": { + "name": "psm_train", + "mode": "HR", + "dataroot": "tf_dataset/psm/psm_train.csv", + "datatype": "time", + "l_resolution": 16, + "r_resolution": 128, + "batch_size": 32, + "num_workers": 4, + "use_shuffle": false, + "data_len": -1 + } + }, + "model": { + "which_model_G": "sr3", + "finetune_norm": false, + "unet": { + "in_channel": 2, + "out_channel": 1, + "inner_channel": 32, + "norm_groups": 16, + "channel_multiplier": [ + 1, + 2, + 4, + 8, + 16 + ], + "attn_res": [], + "res_blocks": 1, + "dropout": 0 + }, + "beta_schedule": { + "train": { + "schedule": "linear", + "n_timestep": 100, + "linear_start": 1e-6, + "linear_end": 1e-2 + } + }, + "diffusion": { + "time_size": 128, + "channels": 1, + "conditional": true + } + }, + "train": { + "n_epoch": 100, + "val_freq": 100, + "save_checkpoint_freq": 10, + "print_freq": 10, + "optimizer": { + "type": "adam", + "lr": 3e-6 + }, + "ema_scheduler": { + "step_start_ema": 5000, + "update_ema_every": 1, + "ema_decay": 0.9999 + } + }, + "wandb": { + "project": "distributed_time" + } +} \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/config/smap_time_test.json b/subject1-4/dynamicSplit/02DiffAD-main_high/config/smap_time_test.json new file mode 100644 index 0000000..c73f713 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/config/smap_time_test.json @@ -0,0 +1,71 @@ +{ + "name": "SMAP_TEST", + "phase": "test", + "gpu_ids": [ + 0 + ], + "path": { + "log": "logs", + "tb_logger": "tb_logger", + "results": "results", + "checkpoint": "checkpoint", + "resume_state": "//experiments/SMAP_TRAIN_128_2048_20/checkpoint/E100" + }, + "datasets": { + "test": { + "name": "smap_test", + "mode": "HR", + "dataroot": "//02DiffAD-main/tf_dataset/smap/smap_test.csv", + "datatype": "time", + "l_resolution": 128, + "r_resolution": 2048, + "data_len": -1 + } + }, + "model": { + "which_model_G": "sr3", + "finetune_norm": false, + "unet": { + "in_channel": 2, + "out_channel": 1, + "inner_channel": 32, + "norm_groups": 16, + "channel_multiplier": [ + 1, + 2, + 4, + 8, + 16 + ], + "attn_res": [], + "res_blocks": 1, + "dropout": 0 + }, + "beta_schedule": { + "train": { + "schedule": "linear", + "n_timestep": 20, + "linear_start": 1e-6, + "linear_end": 1e-2 + }, + "test": { + "schedule": "linear", + "start_label": 1, + "end_label": 3001, + "step_label": 1, + "step_t": 1000, + "n_timestep": 20, + "linear_start": 1e-6, + "linear_end": 1e-2 + } + }, + "diffusion": { + "time_size": 2048, + "channels": 1, + "conditional": true + } + }, + "wandb": { + "project": "distributed_time" + } +} \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/config/smap_time_train.json b/subject1-4/dynamicSplit/02DiffAD-main_high/config/smap_time_train.json new file mode 100644 index 0000000..d5d1909 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/config/smap_time_train.json @@ -0,0 +1,80 @@ +{ + "name": "SMAP_TRAIN", + "phase": "train", + "gpu_ids": [ + 1, + 3 + ], + "path": { + "log": "logs", + "tb_logger": "tb_logger", + "results": "results", + "checkpoint": "checkpoint", + "resume_state": null + }, + "datasets": { + "train": { + "name": "smap_train", + "mode": "HR", + "dataroot": "//02DiffAD-main/tf_dataset/smap/smap_train.csv", + "datatype": "time", + "l_resolution": 128, + "r_resolution": 2048, + "batch_size": 32, + "num_workers": 4, + "use_shuffle": false, + "data_len": -1 + } + }, + "model": { + "which_model_G": "sr3", + "finetune_norm": false, + "unet": { + "in_channel": 2, + "out_channel": 1, + "inner_channel": 32, + "norm_groups": 16, + "channel_multiplier": [ + 1, + 2, + 4, + 8, + 16 + ], + "attn_res": [], + "res_blocks": 1, + "dropout": 0 + }, + "beta_schedule": { + "train": { + "schedule": "linear", + "n_timestep": 20, + "linear_start": 1e-6, + "linear_end": 1e-2 + } + }, + "diffusion": { + "time_size": 2048, + "channels": 1, + "conditional": true + } + }, + "train": { + "n_epoch": 100, + "val_freq": 100, + "save_checkpoint_freq": 10, + "print_freq": 10, + "optimizer": { + "type": "adam", + "lr": 3e-6 + }, + "ema_scheduler": { + "step_start_ema": 5000, + "update_ema_every": 1, + "ema_decay": 0.9999 + } + }, + "wandb": { + "project": "distributed_time" + } +} \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/config/smd_time_test.json b/subject1-4/dynamicSplit/02DiffAD-main_high/config/smd_time_test.json new file mode 100644 index 0000000..0d93cbe --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/config/smd_time_test.json @@ -0,0 +1,71 @@ +{ + "name": "SMD_TEST", + "phase": "test", + "gpu_ids": [ + 2 + ], + "path": { + "log": "logs", + "tb_logger": "tb_logger", + "results": "results", + "checkpoint": "checkpoint", + "resume_state": "//experiments/SMD_TRAIN_128_2048_20/checkpoint/E100" + }, + "datasets": { + "test": { + "name": "smd_test", + "mode": "HR", + "dataroot": "//02DiffAD-main/tf_dataset/smd/smd_test.csv", + "datatype": "time", + "l_resolution": 128, + "r_resolution": 2048, + "data_len": -1 + } + }, + "model": { + "which_model_G": "sr3", + "finetune_norm": false, + "unet": { + "in_channel": 2, + "out_channel": 1, + "inner_channel": 32, + "norm_groups": 16, + "channel_multiplier": [ + 1, + 2, + 4, + 8, + 16 + ], + "attn_res": [], + "res_blocks": 1, + "dropout": 0 + }, + "beta_schedule": { + "train": { + "schedule": "linear", + "n_timestep": 20, + "linear_start": 1e-6, + "linear_end": 1e-2 + }, + "test": { + "schedule": "linear", + "start_label": 1, + "end_label": 1001, + "step_label": 1, + "step_t": 1000, + "n_timestep": 20, + "linear_start": 1e-6, + "linear_end": 1e-2 + } + }, + "diffusion": { + "time_size": 2048, + "channels": 1, + "conditional": true + } + }, + "wandb": { + "project": "distributed_time" + } +} \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/config/smd_time_train.json b/subject1-4/dynamicSplit/02DiffAD-main_high/config/smd_time_train.json new file mode 100644 index 0000000..12e176f --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/config/smd_time_train.json @@ -0,0 +1,80 @@ +{ + "name": "SMD_TRAIN", + "phase": "train", + "gpu_ids": [ + 0, + 1 + ], + "path": { + "log": "logs", + "tb_logger": "tb_logger", + "results": "results", + "checkpoint": "checkpoint", + "resume_state": null + }, + "datasets": { + "train": { + "name": "smd_train", + "mode": "HR", + "dataroot": "//02DiffAD-main/tf_dataset/smd/smd_train.csv", + "datatype": "time", + "l_resolution": 128, + "r_resolution": 2048, + "batch_size": 8, + "num_workers": 4, + "use_shuffle": false, + "data_len": -1 + } + }, + "model": { + "which_model_G": "sr3", + "finetune_norm": false, + "unet": { + "in_channel": 2, + "out_channel": 1, + "inner_channel": 32, + "norm_groups": 16, + "channel_multiplier": [ + 1, + 2, + 4, + 8, + 16 + ], + "attn_res": [], + "res_blocks": 1, + "dropout": 0 + }, + "beta_schedule": { + "train": { + "schedule": "linear", + "n_timestep": 20, + "linear_start": 1e-6, + "linear_end": 1e-2 + } + }, + "diffusion": { + "time_size": 2048, + "channels": 1, + "conditional": true + } + }, + "train": { + "n_epoch": 100, + "val_freq": 100, + "save_checkpoint_freq": 100, + "print_freq": 10, + "optimizer": { + "type": "adam", + "lr": 3e-6 + }, + "ema_scheduler": { + "step_start_ema": 5000, + "update_ema_every": 1, + "ema_decay": 0.9999 + } + }, + "wandb": { + "project": "distributed_time" + } +} \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/core/__pycache__/logger.cpython-311.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/core/__pycache__/logger.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a333c0111ab4934db4e3607384f137a62b48f4c GIT binary patch literal 8065 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 E0gO=I%>V!Z literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/core/__pycache__/logger.cpython-37.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/core/__pycache__/logger.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4b8153a73d945c91a502f976631af3d933396061 GIT binary patch literal 4147 zcma)9&vP6{74Ghtot>TiVM$rbk}+WkS>uIRmK}-&)y9=LvaunN3uNrDC^f9MXIHD; zomusaYuh*Xl@6?(8Of=p^34el0GRga_k$!oDCw(UFdHT( zn$gb;GK~z{rp!EH4NF=wi*Htzr7d$$c*FiSla9g`9o;I)@oem?<(mjPp)=b5xTZ)Mqbn%cr8vG_z9E@%G)U6 z3aW_3EaLk@osYz}5o0S-d?YyYFYKL<*(!T~Zp;%3pHg-z53n69YpmU)HN3rU7`Z{O zW@@J!cKtAF`YlfzVWhMOLTwM4Jx_L3SQ9!kY(`t5HtF+Qrt(nW-`_=bb7f=MJ)HdU zpTGItr=R@nAAkPC#?@=ful?)yPd@$R*Bi@MH=Cj74x2+yxvfBY8_U;LyY2Q{tCt7O zuD{U=l(*3jIvr0f4IgW3(4*CC+96epJA6hsTouu7(ZKX)pph7&ghs>;_=Ft@$tPq} zu{J7JA6Exe=~i!7->t6K3`P9f@PkL%#^%~&*klVQssgbTJ6_}x6{Z*rXD}3!-5FQZ zZY6Cr;8cuUEK%XF7>(IB8w=EYjFZ?FV-vM8&PYDCA~QCmkcKorGJd%<&hA}|vpAg> z$98NVWMpQ-rM1Xp_8h~A72B_|v9)vU0i(0}9{WCfk44sYHnt*L+8>E=4w7@~iOd~1 zaZWmmY{KbVXQ=a#Q|Jlxw z%a?lQ$3j{1E12_go%yz`rY(69Uz|+O0)0z<6+N>1r8<+fqxRR(rt#@1d>#E)(0}e6 zFn0L_&r+Q|p2O+CFfPRH~bJwyatGd~JP`47h6OaGI&2gWFD6#B06!l1t! zbpyXqP$zmiGe9iqH;S8H)O5qvmM3@nUc>Q^uC6!KW`rv|Doy34(iPoVJ#%7lR|P@T zu&~hXsZdLKVjU$cqw3&-zh6K&g$wWVUx^)aJq>}_ywUX|#7D8TtVLIz3MfyVdLJ>i z6%2;gDP||p#A2hxVN-?PQoSFvn*H!P8dI*P{1u(;40qkG44;er6v9F(^QfRsX{yeB zoc<0{7EX*KlPC-Hnouv|qxs%xg>v@p-Q0~lc}r&!hd8A58qQF`Xl`41 zJBPHbMmcOg^jw@{t2Yd$B<*ZAqt=!ic1PYJo!lYqEcFn#@Ab}*z{6m31ztYMQfE~RAN)@Hx!BSC{rU4STU^t{K3Dh-=_ zhP>$1YNyVh@;E$?oI2b?#kiIJ36swt-OllOQ8Fxi3m8AoOG!Cui2|SJWt4eg8xCLK zmRP`?f+%qZBPGl!KuVd<7y`3Ng2g|tWeY{AvqcI_e`M!3QIZSiF#=-%V!$+jQHC_& z-KMtJ0^cKqbexH47P%XV3+c`t-GgM?xRz$<_1o$O2&WB^cillZ1nTLyuB6!{it$l- zy2jE8hBaE;bt#m&u695PDCD4BaNV8VWwBkOyQl4X^` zey4(XR7ugZB1HO>S5yt(k+Je4N72qk;(cc%Rw|0_do7cilXj`zL4{BXdDkE;%^8{0 zu6Ea#NX%|u8-uW;c~A3)r!9LI(|1u)%OZBn!KMpI^ti+oQE#XK6)!3r13}qtf|X-M)7lDXvec42mDK z;~@hfq@H$~Qcih_>yh%BgQITEY2;G}NkW%43GSpRFq3ReTVYFi$b1}0Gfi($rIBRP zHkQ_+y`@FCb?W>RRd$DND*Hod8ZMw>c&nLkgfh|wT{7y~sFep=3Qou?YiHCq@lp4w zqGYP`t)Slrf&|h#O1K8m=-HP%ypn8@_-qmf(yL2erp-HRx9%qLPpEhtg0x*v1NC(Z YwFz>vp^;6A%CK$QbnebrcEKtB7d9Qyga7~l literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/core/__pycache__/logger.cpython-38.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/core/__pycache__/logger.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1a8816259b8e18c7623868a4476e80ed31657e93 GIT binary patch literal 4171 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 awjtgcur_AF^Fh;vMl}FU5OY7kdi!5bc52Q5 literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/core/__pycache__/metrics.cpython-37.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/core/__pycache__/metrics.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2e33c5e984edf893136343a236cecfacbfd45385 GIT binary patch literal 4340 zcmb7H%a0sK8SkooPS0a!XYKXIHWna(GQtjCC*Tk*5rMUdQ5e7uIBG47dZ&8UvpX+W z_gK48_i2NWkSuYsKnQ6!mxv38NI?Sr0sjG<>Iw>&BN7rf_t*qGzn#!t617qp$aKR3!%oy>asvX&5pc0cDqBl6J;ldD zmA3I=Z%ceM?Mlj);czcfcKiU&sVpH!V`WjaC^OuRncx`~O2|Xn!^uFd(dKq6 z+oBsdBiSQp_j9s0?1EIRr%JhYP|F@v&As{t+zd{%irwNbV<6vYKQJb1uMIm|eaA8>^g!3v+VLb9QqVW|w#KDA>umTc)kZT*q}w^1`K$F3*D(nBTv5OL>$BblO-UZ0?JzIx*(Iy7Km- zVIfS|f-o`Wg@dv#-FY$z8gsJkg10s=UNGNZ&8@hGxiePd%*1Om-rAHmC%Bp$wXpWg z;`y~x-fV5tlsD*}C$3G*CUw2VHV2 z6cz|SeP`dqTue#~W^tJLftbF)!Vkb_@kJ&MU#D`fW_0tM6lYhYF7};iqSA>sBSUr3#tqOKv%cq#F7Lre~ zig1QiPlZnuoV6uTv_&0YZUwG}-Oa$)2+Ca~g1W{F+t97Y%BP9= z!Kg3LaENZ3PNY~u+mV>E^+HMgf@1rM!)9-4X=!GklUubMNoz9FSB`sZ$BD$L_l|b4 zSGa6hdml_&FE63vSUhfFrCfDg@QB69ih`!klmv@}g>-n82}zpejc=8cS3Gu8Xvr zcld!%H&yr$b&A@NB(*U*e>W|B`B6ueX71r@$H`sANk;u%oHT9O!U|i$jF9~~*$EA$tWbeob+D#?mDTYVyR{qwd4 kBQfbmZ=y&UG373*bC*re@?7tdX9IfPm%Nv~8gM-S2Y!C&_5c6? literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/core/__pycache__/metrics.cpython-38.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/core/__pycache__/metrics.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1cdad6bde4bcab4d4ddfbbbe7becf97cae141ac4 GIT binary patch literal 4358 zcmbVP%WoV>8SkooPS3;Rv15C)*|6fJ3?ebk0=s}gAVN?e46B&s(E^RyT|M^LJw4;< zo@l-5IT@VnqAy{GrOhX=+fIP8Ac3_X3z!|xLJMsc=R10d% z5T>wxZv?)ug#%a@uJ8aGq9%O6rl^YsU`sSb3vf-Wi8f$ctcwody4Vn#fE{s5YyobF zZLtHmDc%sb0dI*n#T~#c!48b>Td$y<(d*jE8|?M7Xe?vZ3ZrN$!|1%C8#0c>t3Sf&GJc4bHP98trEz6kvMb}j_?Y#&T)CJX z#~;PYj3(1AQ%)YI*;syT$U5Zzv$uOZ9>u#!nBsqTbRLaGy!*9>kA{Q64<6kgg~N20 z6yF`ixg18>gUPvSRV(((l^oielrWfVqF+*w_!gR0@HUWA!5I@waC(g+t6+Ur(0$oG zN#}W`JDT{)M290-(HPsh(Kwlo(hQ6mU6}~;FjHI%^g+swu0U-}Cm4(SQTDu#IsG&o z#bi$zX=*T!wYa6g9^F6#Th4<^8!ZphH=5J*v!1)@QP#IaLkHh z-*Bvo;}lHTr>6WQHw#vnCzh}=!XFvGdo*)F+l5O;Dclz(GYV^kwpVCpnLazl3J&Ib zFId3^+ou)gGzV=j&?abSfwoA#Fn5eg_sUq{*Y*v4a-YtCb$!U0g|%bMyn+Ms1}2`Z z-c$VGnKFO=>`B0%0(sJVEL*tBUvy37B;jG4WXcLZ9A?TLrjsO$;x3b93(65Nvsfxy zOLaZPCqmU8;b9+3JeoEqWy>%)`ytE>MzoIAvM-|}+v$`a_t++D z>#xI0*ycN|%{?x^0?8%YT5^I8M#(w~qhLoI_5_zWFr*81m&>~V%8ABl6y_i|i1e%kFYXoTbB4fVqi; z0Rqer#}#abLlw)%G)vBBT!OVUx_SvVW;sij=9HYzSj}A;U0uy1_b2U2sS6H!arY?* zFyR3rb_)cF!Um+^KtZk!=mItXJ-{ZQSvWgnYc1eb;c9#hxLtS}Z)?7-@pUbaAOrc1 z#!LPNaJQ1*1nyMp+|qct&K7XWB-=f?jq8^0P`CW>atpk`{Mo^elt+<42a+|y7G7Po ziLv-EVPY%_2X&pc%kUC(7G(PsZ(~usVt%wZqD1JDr3Zb$m79uIWs&6oSe6g4Nn6(thD1hE%>i6MD zN5%{}Z)OTUvjA<-j*hU5q6o|gIT$_i?UjjKYn*V(v&fYkdCWU8f!AIz;4ZT9zh<@E zg5lOK_;1Y_pZT+TZs$(HFW3dc_@8Hu!Y>+#PW~yE2_nuMZwMc`u~{?)JGJFYj5RB{ zmzYC1!@-O(T zRkRB0)RIq&*32quGqb4A?82WpXHRp=*$!mZ@>+$pbHBpY;g)MfyI3DsI-{3`*njb- z>RBGjystB~s>P|OP(RD#Nr}rlc#_8msr>L9wOJNHYM34&%YPmNWxTB`o=y;R%Vb_h z1**+s8fU65;|#{4vyN(^1Qx@n+Ax!EV+Ca`G{Nv$^KyqiK= zwdc&T*6w!7`oNh$nNg;k^L{R;ao`-rS>Epju7-oXz}E@NyV0~Z*Uu@nTJ@g|8S5*@J@&I);?zgyhgd5k ze}Eg^e7AWEF5{V0gzUhT-bVA$zKGV~gq5-maC}_;2J@F3$_9g)PRjy_pft?)k%Xy6 z00l?dG5){>AAnoc4d4iCfZRYC>=N!(mNJ(dX}ro8mnLwmAt=8Qjv^C=#&wEz%W6OH z>9#66qN-6FlYBrJMeeSJ*B?i!Ha8Jp8&7F2PCibCS>Cnf`w&(pReuLGw@2MG>XrkO z{4sccM9bRfsG{3q9l9opI$Vz~U5*JMYWi|WzZ{1v82pGA{JL&ql0*6rUDfG~q`gR6i+)2%H!JD9lC)URRa>9Vh~EBaET&2P fJ^Fo{QK3(n?~dtNp6k8o*?^w+CGVcs0*>#0;6l{b literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/core/logger.py b/subject1-4/dynamicSplit/02DiffAD-main_high/core/logger.py new file mode 100644 index 0000000..672af18 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/core/logger.py @@ -0,0 +1,143 @@ +import json +import logging +import os +from collections import OrderedDict +from datetime import datetime + + +def mkdirs(paths): + if isinstance(paths, str): + os.makedirs(paths, exist_ok=True) + else: + for path in paths: + os.makedirs(path, exist_ok=True) + + +def get_timestamp(): + return datetime.now().strftime('%y%m%d_%H%M%S') + + +def parse(args, model_epoch=None): + phase = args.phase + opt_path = args.config + gpu_ids = args.gpu_ids + enable_wandb = args.enable_wandb + # remove comments starting with '//' + json_str = '' + with open(opt_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.split('//')[0] + '\n' + json_str += line + + opt = json.loads(json_str, object_pairs_hook=OrderedDict) + + # set log directory + if args.debug: + opt['name'] = 'debug_{}'.format(opt['name']) + if opt['phase'] == 'train': + experiments_root = os.path.join( + 'experiments', '{}_{}_{}_{}'.format(opt['name'], opt['datasets']['train']['l_resolution'], + opt['datasets']['train']['r_resolution'], + opt['model']['beta_schedule']['train']['n_timestep'])) + elif opt['phase'] == 'test': + experiments_root = os.path.join( + 'experiments', '{}_{}_{}_{}_{}'.format(opt['name'], opt['datasets']['test']['l_resolution'], + opt['datasets']['test']['r_resolution'], + opt['model']['beta_schedule']['test']['n_timestep'], model_epoch)) + + opt['path']['experiments_root'] = experiments_root + for key, path in opt['path'].items(): + if 'resume' not in key and 'experiments' not in key: + opt['path'][key] = os.path.join(experiments_root, path) + mkdirs(opt['path'][key]) + + opt['phase'] = phase + + # export CUDA_VISIBLE_DEVICES + if gpu_ids is not None: + opt['gpu_ids'] = [int(id) for id in gpu_ids.split(',')] + gpu_list = gpu_ids + else: + gpu_list = ','.join(str(x) for x in opt['gpu_ids']) + os.environ['CUDA_VISIBLE_DEVICES'] = gpu_list + print('export CUDA_VISIBLE_DEVICES=' + gpu_list) + + if len(gpu_list) > 1: + opt['distributed'] = True + else: + opt['distributed'] = False + + # debug + if 'debug' in opt['name']: + opt['train']['print_freq'] = 2 + opt['train']['save_checkpoint_freq'] = 3 + opt['datasets']['train']['batch_size'] = 2 + opt['model']['beta_schedule']['train']['n_timestep'] = 10 + opt['datasets']['train']['data_len'] = 6 + + # W&B Logging + try: + log_wandb_ckpt = args.log_wandb_ckpt + opt['log_wandb_ckpt'] = log_wandb_ckpt + except: + pass + try: + log_eval = args.log_eval + opt['log_eval'] = log_eval + except: + pass + try: + log_infer = args.log_infer + opt['log_infer'] = log_infer + except: + pass + opt['enable_wandb'] = enable_wandb + + return opt + + +class NoneDict(dict): + def __missing__(self, key): + return None + + +# convert to NoneDict, which return None for missing key. +def dict_to_nonedict(opt): + if isinstance(opt, dict): + new_opt = dict() + for key, sub_opt in opt.items(): + new_opt[key] = dict_to_nonedict(sub_opt) + return NoneDict(**new_opt) + elif isinstance(opt, list): + return [dict_to_nonedict(sub_opt) for sub_opt in opt] + else: + return opt + + +def dict2str(opt, indent_l=1): + '''dict to string for logger''' + msg = '' + for k, v in opt.items(): + if isinstance(v, dict): + msg += ' ' * (indent_l * 2) + k + ':[\n' + msg += dict2str(v, indent_l + 1) + msg += ' ' * (indent_l * 2) + ']\n' + else: + msg += ' ' * (indent_l * 2) + k + ': ' + str(v) + '\n' + return msg + + +def setup_logger(logger_name, root, phase, level=logging.INFO, screen=False): + '''set up logger''' + l = logging.getLogger(logger_name) + formatter = logging.Formatter( + '%(asctime)s.%(msecs)03d - %(levelname)s: %(message)s', datefmt='%y-%m-%d %H:%M:%S') + log_file = os.path.join(root, '{}.log'.format(phase)) + fh = logging.FileHandler(log_file, mode='w') + fh.setFormatter(formatter) + l.setLevel(level) + l.addHandler(fh) + if screen: + sh = logging.StreamHandler() + sh.setFormatter(formatter) + l.addHandler(sh) diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/core/metrics.py b/subject1-4/dynamicSplit/02DiffAD-main_high/core/metrics.py new file mode 100644 index 0000000..2691ae9 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/core/metrics.py @@ -0,0 +1,169 @@ +import numpy as np +import pandas as pd +from sklearn.metrics import f1_score, accuracy_score, recall_score, precision_score, mean_squared_error + + +def squeeze_tensor(tensor): + return tensor.squeeze().cpu() + + +def update_csv_col_name(all_datas): + df = all_datas.copy() + df.columns = [0, 1, 2, 3] + + return df + + +def tensor2allcsv(visuals, col_num): + df = pd.DataFrame() + sr_df = pd.DataFrame(squeeze_tensor(visuals['SR'])) + ori_df = pd.DataFrame(squeeze_tensor(visuals['ORI'])) + lr_df = pd.DataFrame(squeeze_tensor(visuals['LR'])) + inf_df = pd.DataFrame(squeeze_tensor(visuals['INF'])) + + if col_num != 1: + for i in range(col_num, sr_df.shape[1]): + sr_df.drop(labels=i, axis=1, inplace=True) + ori_df.drop(labels=i, axis=1, inplace=True) + lr_df.drop(labels=i, axis=1, inplace=True) + inf_df.drop(labels=i, axis=1, inplace=True) + + df['SR'] = sr_df.mean(axis=1) + df['ORI'] = ori_df.mean(axis=1) + df['LR'] = lr_df.mean(axis=1) + df['INF'] = inf_df.mean(axis=1) + + df['differ'] = (ori_df - sr_df).abs().mean(axis=1) + df['label'] = squeeze_tensor(visuals['label']) + + differ_df = (sr_df - ori_df) + + return df, sr_df, differ_df + + +def merge_all_csv(all_datas, all_data): + all_datas = pd.concat([all_datas, all_data]) + return all_datas + + +def save_csv(data, data_path): + data.to_csv(data_path, index=False) + + +def get_mean(df): + mean = df['value'].astype('float32').mean() + normal_mean = df['value'][df['label'] == 0].astype('float32').mean() + anomaly_mean = df['value'][df['label'] == 1].astype('float32').mean() + + return mean, normal_mean, anomaly_mean + + +def get_val_mean(df): + mean_dict = {} + + ori = 'ORI' + ori_mean = df[ori].astype('float32').mean() + ori_normal_mean = df[ori][df['label'] == 0].astype('float32').mean() + ori_anomaly_mean = df[ori][df['label'] == 1].astype('float32').mean() + + gen_mean = df['SR'].astype('float32').mean() + gen_normal_mean = df['SR'][df['label'] == 0].astype('float32').mean() + gen_anomaly_mean = df['SR'][df['label'] == 1].astype('float32').mean() + + mean_dict['MSE'] = mean_squared_error(df[ori], df['SR']) + + mean_dict['ori_mean'] = ori_mean + mean_dict['ori_normal_mean'] = ori_normal_mean + mean_dict['ori_anomaly_mean'] = ori_anomaly_mean + + mean_dict['gen_mean'] = gen_mean + mean_dict['gen_normal_mean'] = gen_normal_mean + mean_dict['gen_anomaly_mean'] = gen_anomaly_mean + + mean_dict['mean_differ'] = ori_mean - gen_mean + mean_dict['normal_mean_differ'] = ori_normal_mean - gen_normal_mean + mean_dict['anomaly_mean_differ'] = ori_anomaly_mean - gen_anomaly_mean + + mean_dict['ori_no-ano_differ'] = ori_normal_mean - ori_anomaly_mean + mean_dict['ori_mean-no_differ'] = ori_mean - ori_normal_mean + mean_dict['ori_mean-ano_differ'] = ori_mean - ori_anomaly_mean + + mean_dict['gen_no-ano_differ'] = gen_normal_mean - gen_anomaly_mean + mean_dict['gen_mean-no_differ'] = gen_mean - gen_normal_mean + mean_dict['gen_mean-ano_differ'] = gen_mean - gen_anomaly_mean + + return mean_dict + + +def relabeling_strategy(df, params): + y_true = [] + best_N = 0 + best_f1 = -1 + best_thred = 0 + best_predictions = [] + thresholds = np.arange(params['start_label'], params['end_label'], params['step_label']) + + df_sort = df.sort_values(by="differ", ascending=False) + df_sort = df_sort.reset_index(drop=False) + + for t in thresholds: + # if (t - 1) % params['step_t'] == 0: + # print("t: ", t) + y_true, y_pred, thred = predict_labels(df_sort, t) + for i in range(len(y_true)): + if y_pred[i] == 1 and y_true[i] == 1: + j = i - 1 + while j >= 0 and y_true[j] == 1 and y_pred[j] == 0: + y_pred[j] = 1 + j -= 1 + j = i + 1 + while j < len(y_pred) and y_true[j] == 1 and y_pred[j] == 0: + y_pred[j] = 1 + j += 1 + + f1 = calculate_f1(y_true, y_pred) + if f1 > best_f1: + best_f1 = f1 + best_N = t + best_thred = thred + best_predictions = y_pred + + accuracy = calculate_accuracy(y_true, best_predictions) + precision = calculate_precision(y_true, best_predictions) + recall = calculate_recall(y_true, best_predictions) + + return best_f1,accuracy,precision,recall + + +def predict_labels(df_sort, num): + df_sort['pred_label'] = 0 + df_sort.loc[0:num - 1, 'pred_label'] = 1 + thred = df_sort.loc[num - 1, 'differ'] + + df_sort = df_sort.set_index('index') + df_sort = df_sort.sort_index() + + y_true = df_sort['label'].tolist() + y_pred = df_sort['pred_label'].tolist() + + return y_true, y_pred, thred + + +def calculate_accuracy(y_true, y_pred): + accuracy = accuracy_score(y_true, y_pred) + return accuracy + + +def calculate_precision(y_true, y_pred): + precision = precision_score(y_true, y_pred) + return precision + + +def calculate_recall(y_true, y_pred): + recall = recall_score(y_true, y_pred) + return recall + + +def calculate_f1(y_true, y_pred): + f1 = f1_score(y_true, y_pred) + return f1 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/data/LRHR_dataset.py b/subject1-4/dynamicSplit/02DiffAD-main_high/data/LRHR_dataset.py new file mode 100644 index 0000000..b22f921 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/data/LRHR_dataset.py @@ -0,0 +1,43 @@ +from torch.utils.data import Dataset + +from data.prepare_time_data import PrepareTimeData + + +class LRHRDataset(Dataset): + def __init__(self, dataroot, datatype, phase, l_resolution=16, r_resolution=128, + split='train', data_len=-1, need_LR=False): + self.datatype = datatype + self.data_len = data_len + self.need_LR = need_LR + self.split = split + self.phase = phase + self.pre_data = PrepareTimeData(data_path=dataroot, phase=phase, base=l_resolution, size=r_resolution) + self.row_num = self.pre_data.get_row_num() + self.col_num = self.pre_data.get_col_num() + + if datatype == 'time': + self.hr_path, self.sr_path, self.labels, self.pre_labels = self.pre_data.get_sr_data() + self.dataset_len = len(self.sr_path) + if self.data_len <= 0: + self.data_len = self.dataset_len + else: + self.data_len = min(self.data_len, self.dataset_len) + else: + raise NotImplementedError( + 'data_type [{:s}] is not recognized.'.format(datatype)) + + def __len__(self): + return self.data_len + + def __getitem__(self, index): + + data_LR = None + data_ORI = self.hr_path[index] + data_HR = self.hr_path[index] + data_SR = self.sr_path[index] + data_label = self.labels[index] + + if self.phase == 'train': + return {'HR': data_HR, 'SR': data_SR, 'Index': index} + else: + return {'ORI': data_ORI, 'HR': data_HR, 'SR': data_SR, 'label': data_label, 'Index': index} diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/data/__init__.py b/subject1-4/dynamicSplit/02DiffAD-main_high/data/__init__.py new file mode 100644 index 0000000..9c915ff --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/data/__init__.py @@ -0,0 +1,42 @@ +'''create dataset and dataloader''' +import logging + +import torch.utils.data + + +def create_dataloader(dataset, dataset_opt, phase): + '''create dataloader ''' + if phase == 'train': + return torch.utils.data.DataLoader( + dataset, + batch_size=dataset_opt['batch_size'], + shuffle=dataset_opt['use_shuffle'], + num_workers=dataset_opt['num_workers'], + pin_memory=True) + elif phase == 'val': + return torch.utils.data.DataLoader( + dataset, batch_size=1, shuffle=False, num_workers=1, pin_memory=True) + elif phase == 'test': + return torch.utils.data.DataLoader( + dataset, batch_size=1, shuffle=False, num_workers=1, pin_memory=True) + else: + raise NotImplementedError( + 'Dataloader [{:s}] is not found.'.format(phase)) + + +def create_dataset(dataset_opt, phase): + '''create dataset''' + mode = dataset_opt['mode'] + from data.LRHR_dataset import LRHRDataset as D + dataset = D(dataroot=dataset_opt['dataroot'], + datatype=dataset_opt['datatype'], + l_resolution=dataset_opt['l_resolution'], + r_resolution=dataset_opt['r_resolution'], + split=phase, + data_len=dataset_opt['data_len'], + need_LR=(mode == 'LR'), + phase=phase) + logger = logging.getLogger('base') + logger.info('Dataset [{:s} - {:s}] is created.'.format(dataset.__class__.__name__, + dataset_opt['name'])) + return dataset diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/LRHR_dataset.cpython-311.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/LRHR_dataset.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d6f440b01f784415869d311f231f82cc79786cb9 GIT binary patch literal 2619 zcmZ`5OH3O_bjG`D8*Bo_AtoQ1rGXGv6c9}s7163uT_9;nBS@u+wAvW&0w()$XP365 zMnYApa^R2yQgX<_hlr*kha7syv4Nyf{Y_nr6N z%$qm-*3!~UVEmd`*3O3s`5Os;NLA!u1duyKB`Vd4L1!pMJfw#VVMd@NM8=6K+#;%| z(M^GnE%@`sjHpV}Bo*F6GDY1;I^$$)%>lIa3e)l#rd`b$8gjE$6F!Bi#KCDm?huX4 zP?gMtnn)8-o7M0wIwPo&TLhMm0+iGya1wK4m!~GCsvh>*z;bUDfGasHlQZ}Jg)x?G z0**f*U4o$=TmpZ0NFh`piZ3ID2vF1~3sIo_s7N6URFGsr07~>VotTdiQlKCc3(`Zn z3G%H#2lUZ59|f`);Khi~t)Dl6*a{e68}*3>+xpCW1@ek5KWr2iLTcy+&xrlfuufh4 z!7~3_=Nrfb;)wflz+39@Lv?tok2~EyhPI1={wD14R&Ae&@|Ld$S^-}bZg89(0&bl~ z?Sxb^O`Klemiq{->uok6=dIdF)}1k5p|7@rDi#mds2WxXHOAaX{Y+ERWJ+|KR48gC zpK%skDZc}=0O}_Tih`sWyoU>)qa%84ut$7o))qzxp z8$~tL@-Ri$OgCa`nyOr$awR*j=NyKc%CO4ZXr5^bTDY-!%~6>3gJLcjZp248H*4u0 z*GD+lW}abWfqCIafWz|$>zP?ix7}u3yow7LM+`l|wdO$yM$U8-la_PQ$m^P+nU1D@ z#+b$2@SMerjFW0|MO)M7yhNB~ISfyfNAJdUg=w~>FF85ObmOd!Vt5*?9YF$sjRi0J zKPNhL1Q^-0n2X zohCO*9^Y7bnjG3m4s9og%gJGG`#R=sEOGn$omf{X)>Rq*{I8X#8XhY;diBK%BQwY`4%t$s)|&fR;=rQomjK-JJaVVZc2A07&-3it306ek%LY)WuL6H{(z8ZPZc zQ`LS@PZ*1A4&H@Op&OEI}}touRo@wrms0)Fue zyT?yGIRCis$)!?eu9TR^FFwzYd@?0544C1o$G4DSVT`51cy-N;p(%>ntSE-1F6oHJ z73I67jP6NT3a$DPdY zj!6rk_Il`fL?4if+vZp-yD$LlO}7W|Oc)lDdj!z|=&SfIk%Er{?@_#&dx3rgYPH~B xMn}DbKW3kR01Mcj2e2;tg^h$bTIOTlD|{ literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/LRHR_dataset.cpython-37.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/LRHR_dataset.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cbe04557d59ecd665ab5936d0f456f5392e2bbb7 GIT binary patch literal 1611 zcmZuxU29xL7@j#Fdp7%#q)F=+eyobZ0bSDG6pBc#X-%L+-G~>*m0`OxX-<1SwsR(E z;|Yif2!gi-F&E9HUi3~u{U>v)RPzH0-s$tsW@`%0VV-&BozM53=RH@t-4;Xnwf6|Vs4|= zkr`FWfG&KX)nugAM`^CeI;JVJ5`tVttzHKxmT<`uPj+QPMh86cWmC=_Fl^qEZM326 z;E;LSzCKtRoSbmHh?U1*0&HmXC@qfvLAf@bgM|vUaFD%=T0H>NUd;rnBOtGvK(B59 z{n`fxCagJFP=}I#8^D6GTaEkC5d+6;@Hxj@wI{vXo<4N8_7NM>><(%dbslxWEMly? z&%w`tap~XY`WrCx1i$m6St2X-_vuc&m^aHZxPP|xj`%+R3bBB<;YJ)Ja}t3QlablB z;ba?uwZRRCRk{mq5L(UQ+wQAwqPaU!y-&WlRPBA*ORHW{nx0nU@@9eAvLBzbO`1lt zrc7k2uu-9u6xRnftR`7%GzCukfTTImO3;d=eN!2s%g;oylPA%PIP18~rq&s8)=ImD zHrm$H>qoFSKN{KShRUj>MVn8#^>L4+O(#J*?oxi97It}~H0${!Q@JXPl2^4ZwQX#b zIv<&M&IXmrwx*8gvNXC&7pL3XPA0Uf%52A^Wnnw|R8Ny^^gO`=;0LCkNAu`Iz|~8` z6>)s@%b(vrczEyYKYsgpc>co5#lLDJaet8eBI z-;gdpBzZc&;YNRQ*EWSni_{1aVf(5FU|xgIz9rt_9k0osL)+plZ^`rc?%7ik@6VQx z>5ZvSOVx>*)D01lSolWFol|I@f!R4Vg%{AZk)WswL7mD2FuuF|Q zAEP7L9<+Lk)%;nuhm1L4&_0w*wh+v7j55cU9654@@~P(1JM=f%G`o;<$cIDxG@QzV z4NXVIzV+4y*4u;%*9)mWkHf@&f3U857}PHVZ0NM2U!mE7K122;f@K1F^*C~_+c2dK zl89aevQC`l1vWb|tqo4d<{)XgNzLr5L2>!d8 zWAuuee%7>kMf)~6eHN9-|6wy91kABR8ejiS*F5TVQ V|2xVy-qx)fV(f1+ zR*MhgHfr@2KrzKLmh*&j;vy5dmw23g&XlM8Gp2maPrbxf!9I&yml(lfZo}P>)V30Eu;s;^oqJmZO{BGo=)SfHc2_y($nh1P8M z?s#W>y~^bVMqd65ut9AmX>oala%b9xXIY42v+PsU>MuYe8YWp20(lbwMbiR$jR*AW zpy6PC6Da<>4-eWNv>t~S3>>||+m3e{p~ORB&YiD&!M>y3J=8wx8tQtzfwulB2fqQv zmG_XF-@sr={^-wole}b~QcS#9tGAT@_+}$6_$mJd`M{2Yz1UCM3JH|+Nj>Wzy)X%ns|cENsuLScary)(F-Ce=zeRKL5Nonw7a8Ws?H` zQGPTnl^(tG?sj@`@bUKBIV3is@J1v;w=)DfoFCap%CtypDMQRsy#`>S#h1TL-s3$H z@fYyz@Q&CNf=5@!H&>)QTuv~hb6ghURGoN9#SjaLg73xL1&_~jaJ%3a@DfZLO3I#; zWK;sc`0>`$tGV{6Yom4)3jN7V`38n!C(z{s*6`=q32w(VgU+E^@&#bRF}fw5;+9%!1pBHc#ZNrSPg&aKFEZHT~b)TNouhLC(# s4QZ=}&N#V6bcnk~PqL&3!^ziOa5wh<7PQfai(o$@5mvN(PxQQh0WJ-Vh5!Hn literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/__init__.cpython-311.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8eb84ea015c91d03a6b9af293bb90b7ce97b8a33 GIT binary patch literal 2140 zcmcIkO=ufO6rPcG^)E~QiDlQ3y^UMfO0jI*lol&46jV1Qs%f3(;!=iX)!KgQz`1oW_XLmLku^oI~yv?x&txJ-Sw zP)6QN7n!EonnG1uwKQ8%4eHHxQ>7YvA#BbU{Y}$i2*M}i(+60%sro3s>$zq*Tj-m# z3fcy(wgN-7PCG3%s-h}{Ie0E(>c1dK=Mt5l2KHox_Tg*LEfGPm8A0a1MnFR}4By{d zkNkhu?QrWH2+?S*eX8?S1n1j>T<*8?c~QELGqKH{j!SG@oWf~8dP%TkPilV%lo?J1@+N7=; z@J^ODiYC=2r>66zrKOMa6J9AC?Yfhia{ESVai=fq4vf}5cLt{2)KEQ& zlJA}%Ihj5atd8Vxx*kK3#O~XVhIfWvGgZS+-hZb4maqH0eK@&*&ye7Cgu@H?INY^6 z_Gn~hu_5JMrVhEZ9%X3iGq4a8gukgA)YNTRdow z!9@eKp?{o1Z_7u0)UTs5-tuGQLsdWMJD>@YeEv5`feTWwL&Bg9b;v#%Za}PxpGNjV zQ0(wEXiKs?K(X3xAT)Xr23vAfu1T$3og51fY!9-t-_FoQ zj~G=Y=%8JjT^-P-j9D5(URhvpKUjDjJXJglU$k14c}P z$5^N2{ZDkw;J(5_Cd4j-O_mmHSg;XbT(&BD$!3a}2MtZ5q_Ds)2}!yGPB-6dI#)c5 zDicZ@s*SK|mP>|O)-oa9EyBx+fIVbD#B9hjtDDQqC1aU~mo>WpbB%GSWB^WkggQ(} zQCBUC5FR2#*dinoV11zT0%326zi^)QiZLLJLCX=j2mAuDezD%nV%u{T7KL}~7hnL$ zX#eiI6CK{pyVCT*#nUTe&H zbrFYUuMaVC_Mecq&r8m$&~>P(HC_9NO@m5wVe1C4x*ucgqR|61>Y}b~?>R=PgVtLQ TbYsAJn~f)MZymkPJWqcCy7uyu literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/__init__.cpython-37.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd57e7845ba5e7c82b9578c15d89c58752c37872 GIT binary patch literal 1286 zcmZ`&OOIPM6t;bRACqK;nYKK_^Rl9mXf*8xsX~ZHia-jpn6gTPtlQX`xtaTt?SLjE zET9srZYv=+GfOt?Kmz`Wx1hrO03?>2-ON!t|S#%;=2Gf+bl(*e+t=k#`9Od>GzE+Zb$z zPiO!ltymGDknVlR9lP}b$ zJvU02y1U?`U0X7fowjX0{i&cry;y-Uy;@tP7iCn9&bJUxjS`{siF8?eV_2IRE9(?|*#! z=-WSj`+0ox*8W?6{q*4RqwmK1H}8YFXtG9WF{z~*@825a)9HJI8znSojIPH*&YUZnRx=M&M-p%oqIT|6UnrnKkO8m{5%}Jw=xsC&5g8KUJEamDi>0} zfy>D0B*3K^C?_z#hG~8Q*f2pan7(JpoX*)i*pLml?ji;r!!ALmucN1En}F@;+E%3E z0Oqy61^V*;^fnaj%V@){=x_8_DmswD;rixY3cIi~7g?PbwQD`g?PSJHv6kcZ(nxM* z%jvX~u3axH{zB;ssm%|)P-9juX|y`TU29R)ypomDD;GS^%QqChe(ORjja`2>gnBj3 zetP+Z+5VgrCaaarrfOM>{%J3U7?hsOT(q=BXVKJRP z8Q!m;1Oq%g;Jl~{%XxpXa>u)Jaa8Owz;>EP0EDG9rHsb@VgJOj-xIcb-o`uq^*&%U zeXHMxlM^K1y8#3xNLSC15`+!Vu}ij0FcFlbqT7Iy4KPIjHvl7#vBv~C1K(0unK-y$ zz@ygdbQ@ZB8Hn~3-A0?}G87%)K{$`+3D_QX$rW${?hJtuN9&_KMgXZ@SV3Jh_OC}> zdvx~Q*$|RPO^Q{}N;Q&QEu`y|TuY-$=$ootNAK^vJuhWFW}~xSsy~D~br<0ygpUDS zWEN#%^(P>YlUho_M`!vbYQksWbbY6Bo_XSA_p|@_vkP1FU0COp?4{#l46ly?`*uOZ z`UAWuDb@LTQJ=emb7@B)OYOp<2JXCv>I2RvWo``TF6A8W;=C8@W6=3P^lh}FLwy6+ z7%!9BGinF7@N-kdcaAYNlK~(}IzW?#Bs;476{jtFL}Q?c{v2$8{t4$oO*q$h$ldTi pL*M@keP47Wh^LM}u;(3_t$hgTm(aLnDZj$jnG_(TDNBR&*1zPWP@ez* literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/prepare_time_data.cpython-311.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/data/__pycache__/prepare_time_data.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b140cae6c826e507ce230de76177672c9473ca8c GIT binary patch literal 19630 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 Op#%0Lomywjob^95?5*ek literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/data/prepare_time_data.py b/subject1-4/dynamicSplit/02DiffAD-main_high/data/prepare_time_data.py new file mode 100644 index 0000000..646f0c8 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/data/prepare_time_data.py @@ -0,0 +1,355 @@ +import math +import warnings + +import numpy as np +import pandas as pd +import torch + +warnings.filterwarnings("ignore") + + +class PrepareTimeData: + def __init__(self, data_path, phase, base, size): + self.data_path = data_path + self.phase = phase + self.base = base + self.size = size + + self.data_name = self.data_path.split('/')[-1].split('_')[0] + self.read_dataset(self.data_path, self.data_name) + self.df = self.ori_df.copy() + self.row_num = self.ori_df.shape[0] + self.col_num = self.ori_df.shape[1] + self.mean = self.df.mean(axis=1) + + self.df = self.get_mean_df(self.df) + self.df = self.vertical_merge_df(self.df) + self.df = self.join_together_labels(self.df) + self.df = self.fill_data(self.df) + self.df = self.standardize_data(self.df) + + def get_hr_data(self): + df = self.df.copy() + ori_values, values, labels, pre_labels = self.get_data_by_interval(df) + + return ori_values, values, labels, pre_labels + + def get_sr_data(self): + df = self.df.copy() + ori_values, values, labels, pre_labels = self.get_data_by_insert_normal() + + return ori_values, values, labels, pre_labels + + def get_mean_df(self, df): + df = df.copy() + for col in df.columns: + df[col] = self.mean + return df + + def vertical_merge_df(self, df): + df = df.copy() + two_power = 2 + + if self.col_num < 16: + two_power = 16 + df_temp = pd.DataFrame() + col_count = 0 + for i in range(two_power - self.col_num): + if col_count >= self.col_num: + col_count = 0 + df_temp[i] = df.iloc[:, col_count] + col_count = col_count + 1 + else: + while self.col_num > two_power: + two_power = two_power * 2 + df_temp = df.iloc[:, 0:(two_power - self.col_num)] + + col_name = [] + for i in range(self.col_num): + col_name.append('value_' + str(i)) + + df.columns = col_name + col_name = [] + for i in range(self.col_num, two_power): + col_name.append('value_' + str(i)) + + df_temp.columns = col_name + df = pd.concat([df, df_temp], axis=1) + return df + + def join_together_labels(self, df): + df = df.copy() + + if self.phase == 'train': + df['label'] = 0 + else: + df['label'] = self.test_labels + return df + + def fill_data(self, df): + df = df.copy() + data_end = math.ceil(self.row_num / self.size) * self.size + + for i in range(self.row_num, data_end): + df = df._append(pd.Series(), ignore_index=True) + + df.fillna(0, inplace=True) + return df + + def read_dataset(self, data_path, data_name): + if data_name.upper().find('MSL') != -1: + cols = [-1] + self.get_dataset(data_path, cols) + elif data_name.upper().find('PSM') != -1: + if self.phase == 'train': + cols = [-1] + self.get_dataset(data_path, cols) + if self.ori_df.columns.__contains__('timestamp_(min)'): + self.ori_df.drop(columns=['timestamp_(min)'], inplace=True) + else: + cols = [-1] + self.get_dataset(data_path, cols) + if self.ori_df.columns.__contains__('timestamp_(min)'): + self.ori_df.drop(columns=['timestamp_(min)'], inplace=True) + self.test_labels.drop(columns=['timestamp_(min)'], inplace=True) + elif data_name.upper().find('SMAP') != -1: + cols = [0, 1, 2, 3, 4, 7, 8, 9, 10, 12, 13, 15, 16, 19, 20] + self.get_dataset(data_path, cols) + elif data_name.upper().find('SMD') != -1: + cols = [0, 1, 3, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 28, 33, 35, 36, 37] + self.get_dataset(data_path, cols) + + def get_dataset(self, data_path, cols): + if self.phase == 'train': + if -1 in cols: + self.ori_df = pd.read_csv(data_path) + else: + self.ori_df = pd.read_csv(data_path, usecols=cols) + else: + if -1 in cols: + self.ori_df = pd.read_csv(data_path) + else: + self.ori_df = pd.read_csv(data_path, usecols=cols) + + test_label_path = self.data_path.replace('_test.csv', '_test_label.csv') + self.test_labels = pd.read_csv(test_label_path) + + def get_data_by_insert_normal(self): + df = pd.DataFrame(columns=['value', 'label']) + df['value'] = self.df['value_0'] + df['label'] = self.df['label'] + + df_pre_label = self.mutation_point(df) + insert_datas = self.insert_normal(df_pre_label) + + ori_values = [] + values = [] + labels = [] + pre_labels = [] + + start_index = 0 + end_index = self.size + + for col in self.df.columns: + if col == 'label': + continue + self.df[col] = insert_datas['value'] + self.df['pre_label'] = insert_datas['pre_label'] + + ori_df = self.vertical_merge_df(self.ori_df) + ori_df = self.fill_data(ori_df) + + for i in range(0, self.df.shape[0], self.size): + insert_data = pd.DataFrame() + ori_value = pd.DataFrame() + + insert_data = pd.concat([insert_data, self.df[start_index: end_index]]) + ori_value = pd.concat([ori_value, ori_df[start_index: end_index]]) + start_index += self.size + end_index += self.size + + value = insert_data.copy().drop(['label', 'pre_label'], axis=1) + label = insert_data['label'] + pre_label = insert_data['pre_label'] + + value = torch.tensor(np.array(value).astype(np.float32)) + label = torch.tensor(np.array(label).astype(np.int64)) + pre_label = torch.tensor(np.array(pre_label).astype(np.int64)) + ori_value = torch.tensor(np.array(ori_value).astype(np.float32)) + + values.append(value.unsqueeze(0)) + labels.append(label) + pre_labels.append(pre_label) + ori_values.append(ori_value.unsqueeze(0)) + + return ori_values, values, labels, pre_labels + + def standardize_data(self, df): + df = df.copy() + name = self.data_path.split('.csv')[0] + print(name, "Points: {}".format(self.row_num)) + df = self.complete_value(df) + + if self.phase != 'train': + anomaly_len = len(df[df['label'] == 1].index.tolist()) + print("Labeled anomalies: {}".format(anomaly_len)) + + return df + + def complete_value(self, df): + + df.fillna(0, inplace=True) + return df + + def get_mutation_point(self, df_pre_label, start_index, end_index, last_size_var): + size_var = df_pre_label['value'][start_index: end_index].var() + label_count = len(df_pre_label[start_index: end_index][df_pre_label['label'] == 1].index.tolist()) + + if last_size_var == 0: + times = 'Nan' + else: + times = size_var / last_size_var + if times < 1 and times != 0: + times = 1 / times + + if times != "Nan" and times >= 10: + df_pre_label['pre_label'][start_index: end_index] = 1 + else: + df_pre_label['pre_label'][start_index: end_index] = 0 + + return size_var + + def mutation_point(self, df): + df_pre_label = df.copy() + df_pre_label['pre_label'] = 0 + + size = 128 + start_index = 0 + end_index = size + all_var = df_pre_label['value'].var() + + last_size_var = 0 + for i in range(int(self.row_num / size)): + last_size_var = self.get_mutation_point(df_pre_label, start_index, end_index, last_size_var) + + start_index += size + end_index += size + + self.get_mutation_point(df_pre_label, start_index, self.row_num - 1, last_size_var) + return df_pre_label + + def get_index(self, indexes): + count = 0 + start_indexes = [] + end_indexes = [] + + if len(indexes) != 0: + count = count + 1 + start_indexes.append(indexes[0]) + + for i in range(1, len(indexes)): + if indexes[i - 1] + 1 != indexes[i]: + count = count + 1 + end_indexes.append(indexes[i - 1]) + start_indexes.append(indexes[i]) + + end_indexes.append(indexes[len(indexes) - 1]) + + return start_indexes, end_indexes, count + + def insert_normal(self, data): + pre_labels = 'pre_label' + + nor_indexes = data[0:self.row_num][data[pre_labels] == 0].index.tolist() + ano_indexes = data[0:self.row_num][data[pre_labels] == 1].index.tolist() + + nor_start_indexes, nor_end_indexes, nor_count = self.get_index(nor_indexes) + ano_start_indexes, ano_end_indexes, ano_count = self.get_index(ano_indexes) + + interval = int(self.size / self.base) + ano_len = 2 + + df = pd.DataFrame(columns=['ind', 'value', 'label', 'pre_label']) + + for i in range(nor_count): + + if nor_end_indexes[i] - nor_start_indexes[i] + 1 < interval: + temp_df = pd.DataFrame(columns=['ind', 'value', 'label', 'pre_label']) + + x = range(nor_start_indexes[i], nor_end_indexes[i] + 1) + xp = [nor_start_indexes[i], nor_end_indexes[i]] + fp = [data['value'][nor_start_indexes[i]], data['value'][nor_end_indexes[i]]] + z = np.interp(x, xp, fp) + + temp_df['ind'] = x + temp_df['value'] = z + temp_df['pre_label'] = 0 + df = pd.concat([df, temp_df]) + else: + last_start_x = -1 + start_xs = range(nor_start_indexes[i], nor_end_indexes[i] + 1, interval) + xp = [] + fp = [] + for start_x in start_xs: + if start_x + interval > nor_end_indexes[i]: + last_start_x = start_x + break + + xp.append(start_x) + xp.append(start_x + interval - 1) + + fp.append(data['value'][start_x]) + fp.append(data['value'][start_x + interval - 1]) + + x = range(nor_start_indexes[i], last_start_x) + z = np.interp(x, xp, fp) + + temp_df = pd.DataFrame(columns=['ind', 'value', 'label', 'pre_label']) + temp_df['ind'] = x + temp_df['value'] = z + temp_df['pre_label'] = 0 + df = pd.concat([df, temp_df]) + + if last_start_x != -1: + temp_df = pd.DataFrame(columns=['ind', 'value', 'label', 'pre_label']) + + x = range(last_start_x, nor_end_indexes[i] + 1) + xp = [last_start_x, nor_end_indexes[i]] + fp = [data['value'][last_start_x], data['value'][nor_end_indexes[i]]] + z = np.interp(x, xp, fp) + + temp_df['ind'] = x + temp_df['value'] = z + temp_df['pre_label'] = 0 + df = pd.concat([df, temp_df]) + + for i in range(ano_count): + temp_df = pd.DataFrame(columns=['ind', 'value', 'label', 'pre_label']) + + x = range(ano_start_indexes[i] - 1, ano_end_indexes[i] + 2) + xp = [ano_start_indexes[i] - 1, ano_end_indexes[i] + 1] + fp = [data['value'][ano_start_indexes[i] - 1], data['value'][ano_end_indexes[i] + 1]] + z = np.interp(x, xp, fp) + + for j in range(len(x)): + if j == 0 or j == len(x) - 1: + continue + + temp_df.loc[x[j], 'ind'] = x[j] + temp_df.loc[x[j], 'value'] = z[j] + temp_df.loc[x[j], 'pre_label'] = 1 + + df = pd.concat([df, temp_df]) + + df = df.set_index(['ind'], inplace=False).sort_index() + df['label'] = data['label'] + for i in range(self.row_num, data.shape[0]): + df = df._append(pd.Series(), ignore_index=True) + df.fillna(0, inplace=True) + return df + + def get_row_num(self): + return self.row_num + + def get_col_num(self): + return self.col_num diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/model/__init__.py b/subject1-4/dynamicSplit/02DiffAD-main_high/model/__init__.py new file mode 100644 index 0000000..0eb77d1 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/model/__init__.py @@ -0,0 +1,10 @@ +import logging + +logger = logging.getLogger('base') + + +def create_model(opt): + from .model import DDPM as M + m = M(opt) + logger.info('Model [{:s}] is created.'.format(m.__class__.__name__)) + return m diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/__init__.cpython-311.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..082de7cfb60ff5dd414beac17a353dfd923d5957 GIT binary patch literal 696 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 C2;q_d literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/base_model.cpython-38.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/base_model.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3da8f605c28b8459254af43ffe831b1b9783811d GIT binary patch literal 2055 zcmbtV&2Jk;6rYdvdgIt_>V$@(B3vOM`OpLfQE`Z(0+xD#2r1$cftJnAIN4-BoSAVU z*7}r6{2R$Je*pi?Tsd*(#sz+}8^>-Egiyzx_vYh$&wFpb?{r!O*X7fYfA+!V{A4IGG$cmTX49*PyUAy#Eq~*7T zkZJ7H%!XUTE%G&{-U29TNkU@i1uLnbPvFYQlKMcf98O%iJ0?6p7z5}D0^yBa+dLeN z!$fH7#bXg!9*@R~LR!CJc`-7!VG0!=SzpN4Ni1#aKprM}sEr)i<$5hgMSRp}*3&W_ zDj&R8M74qb`h4@K$mC`k<@j%AXEB`E{B&!O42NG1o@Y^lL+97#0Xz(=<;LjD24R@w zi3vj|OFKz~`qZP{zkTM@N%tlm8#BT?fpH#GfpHOXu3pjI%BDV3%Q&*0h)h(S)S%-I zmxfY`(A~JLuA)sRt8;xf_pwtj8*Y6^p?ZkZO7<14RNhv$is&X;GLhjZQc)(2RC)zG zGqoSi)!sw-e+*FFnJEjtt{zGg#$%;qZo=1z9!IHOy=dD`|S>NcObBn;rI|T=Yy~qO>=!nqD!iNUq=WPI|aH-ow-` zBqg~Zm)O=Zq_&ZdGnw|Oa$esKO0byZvR?gmZMIFtn}EwPsj}bvq1C(JAU1^#Ib< zBL`gPP%dTEdk(l#Rv$U=+yU3Z7l3Q7$~}rplB(w+xtamL`E{yWc-{no4XQ8DMxLvW aXN(KND%n-{4z_DEcU&*lu0R9Y=KlcnQP4jC literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/model.cpython-311.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/model.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eaaf2026989c9d60984dd033f4de1f75f61500ac GIT binary patch literal 12814 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 TUS4gQJ@YLt`Ti;8cxL|#C{~-7 literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/model.cpython-37.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/model.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a6d3feb52b05a954211ccca611f7a60e346cf07d GIT binary patch literal 5358 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 literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/networks.cpython-37.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/networks.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f54583dcd8ca45edf1ccee30b849a6bd8b1630a6 GIT binary patch literal 3177 zcmbtW&2J<}74Pb=>7EaNZ#E`Nu$B*Lq>b^KkB}vhP2$KzT1JSEOJme(Pqk;-?&%&? z)nv2I_!3s)WGM#}3Bkd>L;<1Pf&}>wa>yT0Hv~%XjSGSk@O#zmvArZHf*#H5*YCZ0 zRrP-Fy{Z>Fou-B757U3}zt36LpXlTKalqWgU*;g(;w-nK>dhi%zU|01Z)fC2E+d_t zJ0mahn3b{MvR^HkE)WKoLkslqe-VHATac->Z|$=qdupH9oSiam zA2{N!a!y=mynQTa%1#|db`5SFgyL=D_WhIK)M8dKG~?WQ+^e5@+=dzF)#Kj2G|sQ) zgCwkGLP%^16gJuDY4^plc;)P0cm`O#d9;5oE7C;h)(eU14|}B;ZSq?C*XO!T9ma7# zPo#`v9mH{wj8bs!URH2HanX$eLy|n!{{1u?3=uq@s01O*5~;nzRFts}`(+_jQmDA= zXg1Q0R2)KbOAdc+iED86w;sq#cXl@7v(w*y^vicXeDi02e(!fXw>LMQ{>!@$KYa5S zI~%tNn0TCwQxW$|p6+aHZe@FW&u=|7O0r^S1W~?Ir0RYt4&?gyfnKf_C1b)hu9n)y zH1cr}iv?_sEwLu(<+r#F-5CSa1XUWm*X`hl~lM5fa6SR5l?|<^bA>I`fL?G5OneUdKJAJgT9}K!DdgXP zsnKLpcD0Z%qj`+j&9Hmx3U+&D+<8HwkU!KXk_6ZDnDEDR^ z_7ES+I$<23ps(Qv0I0{>Vv|Cwys5*TWBUjtcj8acN6}NaVBx~zhsL5YwNZrjk!LIb z5G-!O!iU9>WGXPSITi9oHOo)g>o{!CFN5CUjhE3ivLw$A6P1<4+9*Z1_}Y(OyCaW& zqW!9!beUMjO2y|vz(0wXZeE1q@D{b6Pja$Wlxi&-jq`Mr7AoavxPD#^2C1NezYRn#$j#xO}MO3w--!nZG*a~MtZkxn~8N;%&L&Uraob+ za09hD#hJfq9ia-jy=rj>Abo+lXl{*g$d2qIbW@H#${VZJK||iHIPSyNItau)9-K>_ zwWiKK4qvk5;VPvKam^WrF}18UGvnrF+`Qoy;AIj2rQ;B3XQR$t_^G8ew+#JC z&0jO49)sjM{*NE~l!|kTGu!Q!(Or~Lf}T^8P8@}>%3 zXR3M9nj($i#Y2id+0&jm^PK^zZ6 zIT=fF8vvZGf#_yd#QkAX6ltzoYi z-p$MY0TPvqatu#mgZzgo!`(q#OiOhE?DnI@8SoVMv^3uSE=(kal8(qWTd;4S9H}s`{uUgU*+xcm z!EVFK9HO?khp`9?^=Z6JW;v$g8NQNtL>Fq^p#FseUu@A=V79$p6yiJhtgZy%AXWEF zlM`PeAzimF8kh-}neftn%tgT50fJ|%$bXv-b4j;^fCV;ft8F*k=6rK8m~Srq8}KFw Az5oCK literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/networks.cpython-38.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/model/__pycache__/networks.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e5b7f298038b9d6c90d587852ba00957106b20b2 GIT binary patch literal 3165 zcmbtW&2Jn<7Vqk>>7EaNhhWGeZANz4XU9%le)grymE68+c_7!Y$5nE2_RMVy10Jw)r|EH*y*E*|{_FB9B=q zJMy`6heZv($UW|V!lHmL@qmZmLf+)9PpqiPmwAWJLDJ&$d;yX+XK!2GmAjbH>UEiR zvm#U4-AZKo!$&J$Z+^G`*-L$!dh3T4>EV49ulx#RYVBA%?7*JdM>c177`JyFaYH#r zE_%EjENaT`IE?ff+}aJrm&EP(N5LJ7S;f$dbL(**{_1g8%{Z?f_vNW^el;H?VKo!n zVw1D5(MC_Zua?CJckki(0joEU_HSiHnh4!`B~krhuN0#VUibdzrEXJ)aoo=nDdSiN zaa<&$6r8)A6D(*U(jkF^b zhmg#Y!GBreJWTy`ZGBjd()Bzk@LwP8^-G?vU){KwZEwGP^QlpiK?qU4UZm=FDR$+R z@t$6;rj;?F7gvjE!J(qVFyPc`(4=q8Cp5Ux5FvoShlK+~wY3 z1+nK^I{@H$%eG>F2KhH)M(DHgd2Cs52x&St}YK-KJ;}Pp%amA_o2W-6R`j#h`Y4Eas_e zfyg3}B_hipT}Q0oqdnPA@>D!Tass^~gq2=7gJf;^QS`_QAQhA=Y@r78gj-c7F%NU|wAo2sXgJcQq7xP5U3w{0`-IOUM4zjE9aGwvAgFHWJ4@F!@C=&YuC}#M))7=l`S@u($*b z-KgQ~69~r-#oVlZ?xUfsBgO#;suq55K2=a#Y><1EH+8skXdfWej{GUABr4`jXt>aL z$7nRBHj>Xi@Qen)fyPB>_|O=VOa(?Zr$XMSX88yE7{>{!VbI&Z@H#3+mgL!fqO!7B z8>Mg=UwiMP7v#bF+OJAUmx*&&srVBJ_%(cV^TZwdm#OSL$jDkzs{qV#)%+D!ho%Ioy>V*RX%-%x&8oUsN9WGKdz{4gXJp$LtX2Plt;@$iEPKI})i$WhY|Fmq z+r+nRn+5m8)6h7Riv&B>4wH*lk)>0d@2l1Ua*^As7Iy&GC90#jHNs&!vJX&CIVve{ ztXjJbd86XE4_#|F5Vv@6EV*t?ogEyqq{+io3LxT|GY(^FS!>3%XIy8-&CR%Z!!5wd zBHpFL5CLc-+g;eHr8T#V{*{_PXGT2)$$7jFANmxOe3jbR-OmVSk3Yg6ttt$^uxfqE z#ARswq2iRk)1XVir%YZ{;m1rhk6Kd%G^}_C*2j9ZiptkKCJ6UWVHsaA?d zlU!xvJVVq5iBd%@QmLCD@m5~;cM-B&lw(*D*T{aTGTaelwx4!G@f;-L&qSUj@;pe? zIc->q7pQ}ROI#=NR}dZ4DpK3|)4GN014ouoHPfA~R3)+O4^uwLQ|&2%%GmYHIPoF| zM`2##x?UBl1y4MV9^~^?QfLgulQ`p2w|FL%$hIbwtL>--?~)KVFGlXWy;Mbuo5@7VEGg)EV%%;b9}6l)f2iI5geSV4$vF8S$?{|iYn^*pVrJTh zNn33fg>K)(ZRxE=cU&%Y-Np$N5RWls_ zVv|~d+4_~D5O1JaT@b=Ss&1K*C!Qc7UA#`pnQ@t!@YJ5nwZPm6g6oy{U!= 0: + v.requires_grad = True + v.data.zero_() + optim_params.append(v) + logger.info( + 'Params [{:s}] initialized to 0 and will optimize.'.format(k)) + else: + optim_params = list(self.netG.parameters()) + + self.optG = torch.optim.Adam( + optim_params, lr=opt['train']["optimizer"]["lr"]) + self.log_dict = OrderedDict() + self.load_network() + self.print_network() + + def feed_data(self, data): + self.data = self.set_device(data) + + def optimize_parameters(self): + self.optG.zero_grad() + l_pix = self.netG(self.data) + # need to average in multi-gpu + b, c, h, w = self.data['HR'].shape + l_pix = l_pix.sum() / int(b * c * h * w) + + l_pix.backward() + self.optG.step() + + # set log + self.log_dict['l_pix'] = l_pix.item() + + def test(self,connection,continous=False): + self.netG.eval() + + with torch.no_grad(): + ori = self.data['ORI'].squeeze() + min_num = ori.min().item() + max_num = ori.max().item() + if isinstance(self.netG, nn.DataParallel): + self.SR = self.netG.module.super_resolution( + self.data['SR'],connection, continous=continous, min_num=min_num, max_num=max_num) + else: + self.SR = self.netG.super_resolution( + self.data['SR'],connection, continous=continous, min_num=min_num, max_num=max_num) + self.netG.train() + + def sample(self, batch_size=1, continous=False): + self.netG.eval() + with torch.no_grad(): + if isinstance(self.netG, nn.DataParallel): + self.SR = self.netG.module.sample(batch_size, continous) + else: + self.SR = self.netG.sample(batch_size, continous) + self.netG.train() + + def set_loss(self): + if isinstance(self.netG, nn.DataParallel): + self.netG.module.set_loss(self.device) + else: + self.netG.set_loss(self.device) + + def set_new_noise_schedule(self, schedule_opt, schedule_phase='train'): + if self.schedule_phase is None or self.schedule_phase != schedule_phase: + self.schedule_phase = schedule_phase + if isinstance(self.netG, nn.DataParallel): + self.netG.module.set_new_noise_schedule( + schedule_opt, self.device) + else: + self.netG.set_new_noise_schedule(schedule_opt, self.device) + + def get_current_log(self): + return self.log_dict + + def get_current_visuals(self, need_LR=True, sample=False): + out_dict = OrderedDict() + if sample: + out_dict['SAM'] = self.SR.detach().float().cpu() + else: + out_dict['SR'] = self.SR.detach().float().cpu() + out_dict['INF'] = self.data['SR'].detach().float().cpu() + out_dict['ORI'] = self.data['ORI'].detach().float().cpu() + out_dict['HR'] = self.data['HR'].detach().float().cpu() + out_dict['label'] = self.data['label'].detach().cpu() + if need_LR and 'LR' in self.data: + out_dict['LR'] = self.data['LR'].detach().float().cpu() + else: + out_dict['LR'] = out_dict['INF'] + return out_dict + + def print_network(self): + s, n = self.get_network_description(self.netG) + if isinstance(self.netG, nn.DataParallel): + net_struc_str = '{} - {}'.format(self.netG.__class__.__name__, + self.netG.module.__class__.__name__) + else: + net_struc_str = '{}'.format(self.netG.__class__.__name__) + + logger.info( + 'Network G structure: {}, with parameters: {:,d}'.format(net_struc_str, n)) + logger.info(s) + + def save_network(self, epoch, iter_step): + gen_path = os.path.join( + self.opt['path']['checkpoint'], 'E{}_gen.pth'.format(epoch)) + opt_path = os.path.join( + self.opt['path']['checkpoint'], 'E{}_opt.pth'.format(epoch)) + # gen + network = self.netG + if isinstance(self.netG, nn.DataParallel): + network = network.module + state_dict = network.state_dict() + for key, param in state_dict.items(): + state_dict[key] = param.cpu() + torch.save(state_dict, gen_path) + # opt + opt_state = {'epoch': epoch, 'iter': iter_step, + 'scheduler': None, 'optimizer': None} + opt_state['optimizer'] = self.optG.state_dict() + torch.save(opt_state, opt_path) + + logger.info( + 'Saved model in [{:s}] ...'.format(gen_path)) + + def load_network(self): + load_path = self.opt['path']['resume_state'] + if load_path is not None: + logger.info( + 'Loading pretrained model for G [{:s}] ...'.format(load_path)) + gen_path = '{}_gen.pth'.format(load_path) + opt_path = '{}_opt.pth'.format(load_path) + # gen + network = self.netG + if isinstance(self.netG, nn.DataParallel): + network = network.module + network.load_state_dict(torch.load( + gen_path), strict=(not self.opt['model']['finetune_norm'])) + + if self.opt['phase'] == 'train': + # optimizer + opt = torch.load(opt_path) + self.optG.load_state_dict(opt['optimizer']) + self.begin_step = opt['iter'] + self.begin_epoch = opt['epoch'] diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/model/networks.py b/subject1-4/dynamicSplit/02DiffAD-main_high/model/networks.py new file mode 100644 index 0000000..d2769b5 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/model/networks.py @@ -0,0 +1,112 @@ +import functools +import logging + +import torch +import torch.nn as nn +from torch.nn import init + +logger = logging.getLogger('base') + + +# initialize +def weights_init_normal(m, std=0.02): + classname = m.__class__.__name__ + if classname.find('Conv') != -1: + init.normal_(m.weight.data, 0.0, std) + if m.bias is not None: + m.bias.data.zero_() + elif classname.find('Linear') != -1: + init.normal_(m.weight.data, 0.0, std) + if m.bias is not None: + m.bias.data.zero_() + elif classname.find('BatchNorm2d') != -1: + init.normal_(m.weight.data, 1.0, std) # BN also uses norm + init.constant_(m.bias.data, 0.0) + + +def weights_init_kaiming(m, scale=1): + classname = m.__class__.__name__ + if classname.find('Conv2d') != -1: + init.kaiming_normal_(m.weight.data, a=0, mode='fan_in') + m.weight.data *= scale + if m.bias is not None: + m.bias.data.zero_() + elif classname.find('Linear') != -1: + init.kaiming_normal_(m.weight.data, a=0, mode='fan_in') + m.weight.data *= scale + if m.bias is not None: + m.bias.data.zero_() + elif classname.find('BatchNorm2d') != -1: + init.constant_(m.weight.data, 1.0) + init.constant_(m.bias.data, 0.0) + + +def weights_init_orthogonal(m): + classname = m.__class__.__name__ + if classname.find('Conv') != -1: + init.orthogonal_(m.weight.data, gain=1) + if m.bias is not None: + m.bias.data.zero_() + elif classname.find('Linear') != -1: + init.orthogonal_(m.weight.data, gain=1) + if m.bias is not None: + m.bias.data.zero_() + elif classname.find('BatchNorm2d') != -1: + init.constant_(m.weight.data, 1.0) + init.constant_(m.bias.data, 0.0) + + +def init_weights(net, init_type='kaiming', scale=1, std=0.02): + # scale for 'kaiming', std for 'normal'. + logger.info('Initialization method [{:s}]'.format(init_type)) + if init_type == 'normal': + weights_init_normal_ = functools.partial(weights_init_normal, std=std) + net.apply(weights_init_normal_) + elif init_type == 'kaiming': + weights_init_kaiming_ = functools.partial( + weights_init_kaiming, scale=scale) + net.apply(weights_init_kaiming_) + elif init_type == 'orthogonal': + net.apply(weights_init_orthogonal) + else: + raise NotImplementedError( + 'initialization method [{:s}] not implemented'.format(init_type)) + + +# define network +def define_G(opt): + model_opt = opt['model'] + if model_opt['which_model_G'] == 'sr3': + from .sr3_modules import diffusion, unet + + if ('norm_groups' not in model_opt['unet']) or model_opt['unet']['norm_groups'] is None: + model_opt['unet']['norm_groups'] = 32 + + model = unet.UNet( + in_channel=model_opt['unet']['in_channel'], + out_channel=model_opt['unet']['out_channel'], + norm_groups=model_opt['unet']['norm_groups'], + inner_channel=model_opt['unet']['inner_channel'], + channel_mults=model_opt['unet']['channel_multiplier'], + attn_res=model_opt['unet']['attn_res'], + res_blocks=model_opt['unet']['res_blocks'], + dropout=model_opt['unet']['dropout'], + time_size=model_opt['diffusion']['time_size'] + ) + + netG = diffusion.GaussianDiffusion( + model, + time_size=model_opt['diffusion']['time_size'], + channels=model_opt['diffusion']['channels'], + loss_type='l1', # L1 or L2 + conditional=model_opt['diffusion']['conditional'], + schedule_opt=model_opt['beta_schedule']['train'] + ) + if opt['phase'] == 'train': + init_weights(netG, init_type='orthogonal') + + if opt['gpu_ids'] and opt['distributed']: + assert torch.cuda.is_available() + netG = nn.DataParallel(netG) + + return netG diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/diffusion.cpython-311.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/diffusion.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..02efccf97b419249399eb1051362db2cdf2e5ab4 GIT binary patch literal 16437 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 literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/diffusion.cpython-37.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/diffusion.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c07ac5f1fb3a4272820d36f3ec06b99f65f03bbf GIT binary patch literal 7556 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 literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/diffusion.cpython-38.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/diffusion.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be4f35138c6051016821f8bea0216749cb0393f2 GIT binary patch literal 7735 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 literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/unet.cpython-311.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/unet.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..238e09c47c02c50a1d25ac838b07d2e8110ed8ae GIT binary patch literal 16113 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 YJje6k&iXLDV-6k$J$tqa2IHgu1Ax<91ONa4 literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/unet.cpython-37.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/unet.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..69c86c07ff82dfdf6974e215ce6058f76e46913d GIT binary patch literal 8276 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 Blr#VU literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/unet.cpython-38.pyc b/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/__pycache__/unet.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..914d38468f8770184e50ff0233c2c5f5851c6297 GIT binary patch literal 8164 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 literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/diffusion.py b/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/diffusion.py new file mode 100644 index 0000000..0e0ec32 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/diffusion.py @@ -0,0 +1,284 @@ +import math +from functools import partial +from inspect import isfunction + +import numpy as np +import torch +from torch import nn +from tqdm import tqdm +import socket +import time +import io + +def _warmup_beta(linear_start, linear_end, n_timestep, warmup_frac): + betas = linear_end * np.ones(n_timestep, dtype=np.float64) + warmup_time = int(n_timestep * warmup_frac) + betas[:warmup_time] = np.linspace( + linear_start, linear_end, warmup_time, dtype=np.float64) + return betas + + +def make_beta_schedule(schedule, n_timestep, linear_start=1e-4, linear_end=2e-2, cosine_s=8e-3): + if schedule == 'quad': + betas = np.linspace(linear_start ** 0.5, linear_end ** 0.5, + n_timestep, dtype=np.float64) ** 2 + elif schedule == 'linear': + betas = np.linspace(linear_start, linear_end, + n_timestep, dtype=np.float64) + elif schedule == 'warmup10': + betas = _warmup_beta(linear_start, linear_end, + n_timestep, 0.1) + elif schedule == 'warmup50': + betas = _warmup_beta(linear_start, linear_end, + n_timestep, 0.5) + elif schedule == 'const': + betas = linear_end * np.ones(n_timestep, dtype=np.float64) + elif schedule == 'jsd': # 1/T, 1/(T-1), 1/(T-2), ..., 1 + betas = 1. / np.linspace(n_timestep, + 1, n_timestep, dtype=np.float64) + elif schedule == "cosine": + timesteps = ( + torch.arange(n_timestep + 1, dtype=torch.float64) / + n_timestep + cosine_s + ) + alphas = timesteps / (1 + cosine_s) * math.pi / 2 + alphas = torch.cos(alphas).pow(2) + alphas = alphas / alphas[0] + betas = 1 - alphas[1:] / alphas[:-1] + betas = betas.clamp(max=0.999) + else: + raise NotImplementedError(schedule) + return betas + + +# gaussian diffusion trainer class +def exists(x): + return x is not None + + +def default(val, d): + if exists(val): + return val + return d() if isfunction(d) else d + + +class GaussianDiffusion(nn.Module): + def __init__(self, denoise_fn, time_size, channels=3, loss_type='l1', + conditional=True, schedule_opt=None): + + super().__init__() + self.channels = channels + self.time_size = time_size + self.denoise_fn = denoise_fn + self.loss_type = loss_type + self.conditional = conditional + if schedule_opt is not None: + pass + + def set_loss(self, device): + if self.loss_type == 'l1': + self.loss_func = nn.L1Loss(reduction='sum').to(device) + elif self.loss_type == 'l2': + self.loss_func = nn.MSELoss(reduction='sum').to(device) + else: + raise NotImplementedError() + + def set_new_noise_schedule(self, schedule_opt, device): + to_torch = partial(torch.tensor, dtype=torch.float32, device=device) + + betas = make_beta_schedule( + schedule=schedule_opt['schedule'], + n_timestep=schedule_opt['n_timestep'], + linear_start=schedule_opt['linear_start'], + linear_end=schedule_opt['linear_end']) + + betas = betas.detach().cpu().numpy() if isinstance( + betas, torch.Tensor) else betas + + alphas = 1. - betas + alphas_cumprod = np.cumprod(alphas, axis=0) + alphas_cumprod_prev = np.append(1., alphas_cumprod[:-1]) + self.sqrt_alphas_cumprod_prev = np.sqrt( + np.append(1., alphas_cumprod)) + + timesteps, = betas.shape + self.num_timesteps = int(timesteps) + + self.register_buffer('betas', to_torch(betas)) + self.register_buffer('alphas_cumprod', to_torch(alphas_cumprod)) + self.register_buffer('alphas_cumprod_prev', + to_torch(alphas_cumprod_prev)) + + # calculations for diffusion q(x_t | x_{t-1}) and others + self.register_buffer('sqrt_alphas_cumprod', + to_torch(np.sqrt(alphas_cumprod))) + self.register_buffer('sqrt_one_minus_alphas_cumprod', + to_torch(np.sqrt(1. - alphas_cumprod))) + self.register_buffer('log_one_minus_alphas_cumprod', + to_torch(np.log(1. - alphas_cumprod))) + self.register_buffer('sqrt_recip_alphas_cumprod', + to_torch(np.sqrt(1. / alphas_cumprod))) + self.register_buffer('sqrt_recipm1_alphas_cumprod', + to_torch(np.sqrt(1. / alphas_cumprod - 1))) + + # calculations for posterior q(x_{t-1} | x_t, x_0) + posterior_variance = betas * \ + (1. - alphas_cumprod_prev) / (1. - alphas_cumprod) + # above: equal to 1. / (1. / (1. - alpha_cumprod_tm1) + alpha_t / beta_t) + self.register_buffer('posterior_variance', + to_torch(posterior_variance)) + # below: log calculation clipped because the posterior variance is 0 at the beginning of the diffusion chain + self.register_buffer('posterior_log_variance_clipped', to_torch( + np.log(np.maximum(posterior_variance, 1e-20)))) + self.register_buffer('posterior_mean_coef1', to_torch( + betas * np.sqrt(alphas_cumprod_prev) / (1. - alphas_cumprod))) + self.register_buffer('posterior_mean_coef2', to_torch( + (1. - alphas_cumprod_prev) * np.sqrt(alphas) / (1. - alphas_cumprod))) + + def predict_start_from_noise(self, x_t, t, noise): + return self.sqrt_recip_alphas_cumprod[t] * x_t - \ + self.sqrt_recipm1_alphas_cumprod[t] * noise + + def q_posterior(self, x_start, x_t, t): + posterior_mean = self.posterior_mean_coef1[t] * \ + x_start + self.posterior_mean_coef2[t] * x_t + posterior_log_variance_clipped = self.posterior_log_variance_clipped[t] + return posterior_mean, posterior_log_variance_clipped + + def p_mean_variance(self, x, t, clip_denoised: bool, condition_x=None): + batch_size = x.shape[0] + noise_level = torch.FloatTensor( + [self.sqrt_alphas_cumprod_prev[t + 1]]).repeat(batch_size, 1).to(x.device) + if condition_x is not None: + x_temp = torch.cat([condition_x, x], dim=1) + noise = self.denoise_fn(x_temp, noise_level) + x_recon = self.predict_start_from_noise(x, t=t, noise=noise) + else: + x_recon = self.predict_start_from_noise( + x, t=t, noise=self.denoise_fn(x, noise_level)) + + if clip_denoised: + x_recon.clamp_(self.min_num, self.max_num) + + model_mean, posterior_log_variance = self.q_posterior( + x_start=x_recon, x_t=x, t=t) + return model_mean, posterior_log_variance + + @torch.no_grad() + def p_sample(self, x, t, clip_denoised=True, condition_x=None): + model_mean, model_log_variance = self.p_mean_variance( + x=x, t=t, clip_denoised=clip_denoised, condition_x=condition_x) + + noise = torch.randn_like(x) if t > 0 else torch.zeros_like(x) + return model_mean + noise * (0.5 * model_log_variance).exp() + + @torch.no_grad() + def p_sample_loop(self, x_in,connection, continous=False): + device = self.betas.device + q = 0 + + sample_inter = (1 | (self.num_timesteps // 10)) + + img = self.receive_tensor(connection) + x = self.receive_tensor(connection) + print("img.shape,x.shape---",img.shape, x.shape) + + if not self.conditional: + # shape = x_in + shape =x + print(shape)#kk + # img = torch.randn(shape, device=device) + ret_img = img + for i in tqdm(reversed(range(0, self.num_timesteps)), desc='sampling loop time step', + total=self.num_timesteps): + img = self.p_sample(img, i, clip_denoised=True) + if i % sample_inter == 0: + ret_img = torch.cat([ret_img, img], dim=0) + else: + # x = x_in + shape = x.shape + print(shape)#kk + # img = torch.randn(shape, device=device) + ret_img = x + + for i in tqdm(reversed(range(0, self.num_timesteps)), desc='sampling loop time step', + total=self.num_timesteps): + img = self.p_sample(img, i, condition_x=x, clip_denoised=True) + if i % sample_inter == 0: + ret_img = torch.cat([ret_img, img], dim=0) + + # print(ret_img.shape)#kk + # print(ret_img[-1].shape)#kk + + if continous: + return ret_img + else: + return ret_img[-1] + + @torch.no_grad() + def receive_tensor(self,socket): + # 首先读取数据长度 + data_length = int.from_bytes(socket.recv(4), byteorder='big') + # 然后根据数据长度读取数据 + data = b'' + while len(data) < data_length: + packet = socket.recv(data_length - len(data)) + if not packet: + return None + data += packet + buffer = io.BytesIO(data) + tensor = torch.load(buffer) + return tensor + + @torch.no_grad() + def sample(self, batch_size=1, continous=False): + time_size = self.time_size + channels = self.channels + return self.p_sample_loop((batch_size, channels, time_size, time_size), continous) + + @torch.no_grad() + def super_resolution(self, x_in,connection, min_num, max_num, continous=False): + self.min_num = min_num + self.max_num = max_num + return self.p_sample_loop(x_in,connection, continous) + + def q_sample(self, x_start, continuous_sqrt_alpha_cumprod, noise=None): + noise = default(noise, lambda: torch.randn_like(x_start)) + + # random gama + return ( + continuous_sqrt_alpha_cumprod * x_start + + (1 - continuous_sqrt_alpha_cumprod ** 2).sqrt() * noise + ) + + def p_losses(self, x_in, noise=None): + x_start = x_in['HR'] + [b, c, h, w] = x_start.shape + t = np.random.randint(1, self.num_timesteps + 1) + + continuous_sqrt_alpha_cumprod = torch.FloatTensor( + np.random.uniform( + self.sqrt_alphas_cumprod_prev[t - 1], + self.sqrt_alphas_cumprod_prev[t], + size=b + ) + ).to(x_start.device) + + continuous_sqrt_alpha_cumprod = continuous_sqrt_alpha_cumprod.view(b, -1) + + noise = default(noise, lambda: torch.randn_like(x_start)) + + x_noisy = self.q_sample( + x_start=x_start, continuous_sqrt_alpha_cumprod=continuous_sqrt_alpha_cumprod.view(-1, 1, 1, 1), noise=noise) + + if not self.conditional: + x_recon = self.denoise_fn(x_noisy, continuous_sqrt_alpha_cumprod) + else: + x_cat = torch.cat([x_in['SR'], x_noisy], dim=1) + x_recon = self.denoise_fn(x_cat, continuous_sqrt_alpha_cumprod) + + loss = self.loss_func(noise, x_recon) + return loss + + def forward(self, x, *args, **kwargs): + return self.p_losses(x, *args, **kwargs) diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/unet.py b/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/unet.py new file mode 100644 index 0000000..77159a7 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/model/sr3_modules/unet.py @@ -0,0 +1,274 @@ +import math +from inspect import isfunction + +import torch +from torch import nn + + +def exists(x): + return x is not None + + +def default(val, d): + if exists(val): + return val + return d() if isfunction(d) else d + + +class PositionalEncoding(nn.Module): + def __init__(self, dim): + super().__init__() + self.dim = dim + + def forward(self, noise_level): + count = self.dim // 2 + step = torch.arange(count, dtype=noise_level.dtype, + device=noise_level.device) / count + encoding = noise_level.unsqueeze( + 1) * torch.exp(-math.log(1e4) * step.unsqueeze(0)) + encoding = torch.cat( + [torch.sin(encoding), torch.cos(encoding)], dim=-1) + return encoding + + +class FeatureWiseAffine(nn.Module): + def __init__(self, in_channels, out_channels, use_affine_level=False): + super(FeatureWiseAffine, self).__init__() + self.use_affine_level = use_affine_level + self.noise_func = nn.Sequential( + nn.Linear(in_channels, out_channels * (1 + self.use_affine_level)) + ) + + def forward(self, x, noise_embed): + batch = x.shape[0] + if self.use_affine_level: + gamma, beta = self.noise_func(noise_embed).view( + batch, -1, 1, 1).chunk(3, dim=1) + x = (1 + gamma) * x + beta + else: + x = x + self.noise_func(noise_embed).view(batch, -1, 1, 1) + return x + + +class Swish(nn.Module): + def forward(self, x): + return x * torch.sigmoid(x) + + +class Upsample(nn.Module): + def __init__(self, dim): + super().__init__() + self.up = nn.Upsample(scale_factor=2, mode="nearest") + self.conv = nn.Conv2d(dim, dim, 3, padding=1) + + def forward(self, x): + return self.conv(self.up(x)) + + +class Downsample(nn.Module): + def __init__(self, dim): + super().__init__() + self.conv = nn.Conv2d(dim, dim, 3, 2, 1) + + def forward(self, x): + return self.conv(x) + + +# building block modules +class Block(nn.Module): + def __init__(self, dim, dim_out, groups=32, dropout=0): + super().__init__() + self.block = nn.Sequential( + nn.GroupNorm(groups, dim), + Swish(), + nn.Dropout(dropout) if dropout != 0 else nn.Identity(), + nn.Conv2d(dim, dim_out, 3, padding=1) + ) + + def forward(self, x): + return self.block(x) + + +class ResnetBlock(nn.Module): + def __init__(self, dim, dim_out, noise_level_emb_dim=None, dropout=0, use_affine_level=False, norm_groups=32): + super().__init__() + self.noise_func = FeatureWiseAffine( + noise_level_emb_dim, dim_out, use_affine_level) + + self.block1 = Block(dim, dim_out, groups=norm_groups) + self.block2 = Block(dim_out, dim_out, groups=norm_groups, dropout=dropout) + self.res_conv = nn.Conv2d( + dim, dim_out, 1) if dim != dim_out else nn.Identity() + + def forward(self, x, time_emb): + b, c, h, w = x.shape + h = self.block1(x) + h = self.noise_func(h, time_emb) + h = self.block2(h) + return h + self.res_conv(x) + + +class SelfAttention(nn.Module): + def __init__(self, in_channel, n_head=1, norm_groups=32): + super().__init__() + + self.n_head = n_head + + self.norm = nn.GroupNorm(norm_groups, in_channel) + self.qkv = nn.Conv2d(in_channel, in_channel * 3, 1, bias=False) + self.out = nn.Conv2d(in_channel, in_channel, 1) + + def forward(self, input): + batch, channel, height, width = input.shape + n_head = self.n_head + head_dim = channel // n_head + + norm = self.norm(input) + qkv = self.qkv(norm).view(batch, n_head, head_dim * 3, height, width) + query, key, value = qkv.chunk(3, dim=2) # bhdyx + + attn = torch.einsum( + "bnchw, bncyx -> bnhwyx", query, key + ).contiguous() / math.sqrt(channel) + attn = attn.view(batch, n_head, height, width, -1) + attn = torch.softmax(attn, -1) + attn = attn.view(batch, n_head, height, width, height, width) + + out = torch.einsum("bnhwyx, bncyx -> bnchw", attn, value).contiguous() + out = self.out(out.view(batch, channel, height, width)) + + return out + input + + +class ResnetBlocWithAttn(nn.Module): + def __init__(self, dim, dim_out, *, noise_level_emb_dim=None, norm_groups=32, dropout=0, with_attn=False): + super().__init__() + self.with_attn = with_attn + self.res_block = ResnetBlock( + dim, dim_out, noise_level_emb_dim, norm_groups=norm_groups, dropout=dropout) + if with_attn: + self.attn = SelfAttention(dim_out, norm_groups=norm_groups) + + def forward(self, x, time_emb): + x = self.res_block(x, time_emb) + if (self.with_attn): + x = self.attn(x) + return x + + +class UNet(nn.Module): + def __init__( + self, + in_channel=6, + out_channel=3, + inner_channel=32, + norm_groups=32, + channel_mults=(1, 2, 4, 8, 8), + attn_res=(8), + res_blocks=3, + dropout=0, + with_noise_level_emb=True, + time_size=128 + ): + super().__init__() + + if with_noise_level_emb: + noise_level_channel = inner_channel + self.noise_level_mlp = nn.Sequential( + PositionalEncoding(inner_channel), + nn.Linear(inner_channel, inner_channel * 4), + Swish(), + nn.Linear(inner_channel * 4, inner_channel) + ) + else: + noise_level_channel = None + self.noise_level_mlp = None + + num_mults = len(channel_mults) + pre_channel = inner_channel + feat_channels = [pre_channel] + now_res = time_size + downs = [nn.Conv2d(in_channel, inner_channel, + kernel_size=3, padding=1)] + + for ind in range(num_mults): + is_last = (ind == num_mults - 1) + use_attn = (now_res in attn_res) + channel_mult = inner_channel * channel_mults[ind] + + for _ in range(0, res_blocks): + downs.append(ResnetBlocWithAttn( + pre_channel, channel_mult, noise_level_emb_dim=noise_level_channel, norm_groups=norm_groups, + dropout=dropout, with_attn=use_attn)) + feat_channels.append(channel_mult) + pre_channel = channel_mult + if not is_last: + downs.append(Downsample(pre_channel)) + feat_channels.append(pre_channel) + now_res = now_res // 2 + self.downs = nn.ModuleList(downs) + + self.mid = nn.ModuleList([ + ResnetBlocWithAttn(pre_channel, pre_channel, noise_level_emb_dim=noise_level_channel, + norm_groups=norm_groups, + dropout=dropout, with_attn=True), + ResnetBlocWithAttn(pre_channel, pre_channel, noise_level_emb_dim=noise_level_channel, + norm_groups=norm_groups, + dropout=dropout, with_attn=False) + ]) + + ups = [] + for ind in reversed(range(num_mults)): + is_last = (ind < 1) + use_attn = (now_res in attn_res) + channel_mult = inner_channel * channel_mults[ind] + + for _ in range(0, res_blocks + 1): + ups.append(ResnetBlocWithAttn( + pre_channel + feat_channels.pop(), channel_mult, noise_level_emb_dim=noise_level_channel, + norm_groups=norm_groups, + dropout=dropout, with_attn=use_attn)) + pre_channel = channel_mult + if not is_last: + ups.append(Upsample(pre_channel)) + now_res = now_res * 2 + + self.ups = nn.ModuleList(ups) + self.final_conv = Block(pre_channel, default(out_channel, in_channel), groups=norm_groups) + + def forward(self, x, time): + t = self.noise_level_mlp(time) if exists( + self.noise_level_mlp) else None + + feats = [] + for layer in self.downs: + if isinstance(layer, ResnetBlocWithAttn): + x = layer(x, t) + else: + x = layer(x) + feats.append(x) + + for layer in self.mid: + if isinstance(layer, ResnetBlocWithAttn): + x = layer(x, t) + else: + x = layer(x) + + for layer in self.ups: + if isinstance(layer, ResnetBlocWithAttn): + pop_temp = feats.pop() + x_temp = torch.cat((x, pop_temp), dim=1) + x = layer(x_temp, t) + else: + x = layer(x) + + return self.final_conv(x) +#模型组件 +#PositionalEncoding: 位置编码器,用于编码噪声级别。 +#FeatureWiseAffine: 用于特征级别的仿射变换。 +#Swish: Swish 激活函数。 +#Upsample: 上采样模块。 +#Downsample: 下采样模块。 +#Block: 基本的卷积块。 +#ResnetBlock: ResNet 风格的残差块。 +#SelfAttention: 自注意力机制模块,用于提取图像特征中的重要信息。 \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/requirements.txt b/subject1-4/dynamicSplit/02DiffAD-main_high/requirements.txt new file mode 100644 index 0000000..918c9c0 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/requirements.txt @@ -0,0 +1,7 @@ +torch>=1.12 +torchvision +numpy~=1.23.2 +pandas~=1.5.1 +scikit-learn~=1.1.2 +tqdm~=4.64.1 +tensorboardx~=2.5.1 \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/server2.py b/subject1-4/dynamicSplit/02DiffAD-main_high/server2.py new file mode 100644 index 0000000..bc031d5 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/server2.py @@ -0,0 +1,44 @@ +import socket +import time +import io +import torch +def receive_tensor(socket): + # 首先读取数据长度 + data_length = int.from_bytes(socket.recv(4), byteorder='big') + # 然后根据数据长度读取数据 + data = b'' + while len(data) < data_length: + packet = socket.recv(data_length - len(data)) + if not packet: + return None + data += packet + buffer = io.BytesIO(data) + tensor = torch.load(buffer) + return tensor + +def main(): + server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server_address = ('', 9999) # 空字符串表示监听所有可用的接口 + server_socket.bind(server_address) + server_socket.listen(1) + + print("等待客户端连接...") + connection, client_address = server_socket.accept() + print(f"客户端 {client_address} 已连接") + + while True: + # data = client_connection.recv(4) + # if len(data) == 4: + # received_int = int.from_bytes(data, byteorder='big') + # print("---------",received_int) + # else: + # print("Received incomplete data.") + img = receive_tensor(connection) + x = receive_tensor(connection) + print("img.shape,x.shape---",img.shape, x.shape) + + connection.close() + server_socket.close() + +if __name__ == "__main__": + main() diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/test_split.py b/subject1-4/dynamicSplit/02DiffAD-main_high/test_split.py new file mode 100644 index 0000000..bf821c3 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/test_split.py @@ -0,0 +1,163 @@ +import argparse +import logging +import os +import time + +import pandas as pd +import torch +from tensorboardX import SummaryWriter + +import core.logger as Logger +import core.metrics as Metrics +import data as Data +import model as Model +from decimal import Decimal +import sys + +import socket +import time +import io + +def time_test(params, strategy_params, temp_list): + torch.backends.cudnn.enabled = True + torch.backends.cudnn.benchmark = True + opt = params['opt'] + logger = params['logger'] + logger_test = params['logger_test'] + model_epoch = params['model_epoch'] + + diffusion = Model.create_model(opt) + logger.info('Initial Model Finished') + + current_step = diffusion.begin_step + current_epoch = diffusion.begin_epoch + + if opt['path']['resume_state']: + logger.info('Resuming training from epoch: {}, iter: {}.'.format( + current_epoch, current_step)) + + diffusion.set_new_noise_schedule( + opt['model']['beta_schedule'][opt['phase']], schedule_phase=opt['phase']) + + logger.info('Begin Model Evaluation.') + idx = 0 + + all_datas = pd.DataFrame() + sr_datas = pd.DataFrame() + differ_datas = pd.DataFrame() + + result_path = '{}'.format(opt['path']['results']) + os.makedirs(result_path, exist_ok=True) + + print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))#news + + server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server_address = ('', 9999) # 空字符串表示监听所有可用的接口 + server_socket.bind(server_address) + server_socket.listen(1) + + print("等待客户端连接...") + connection, client_address = server_socket.accept() + print(f"客户端 {client_address} 已连接") + + for _, test_data in enumerate(test_loader): + # print(test_data['ORI'].shape) + # print(test_data['HR'].shape) + # print(test_data['SR'].shape) + # print(test_data['label'].shape) + # sys.exit (0) + idx += 1 + diffusion.feed_data(test_data) + diffusion.test(connection,continous=False) + visuals = diffusion.get_current_visuals() + + all_data, sr_df, differ_df = Metrics.tensor2allcsv(visuals, params['col_num']) + all_datas = Metrics.merge_all_csv(all_datas, all_data) + sr_datas = Metrics.merge_all_csv(sr_datas, sr_df) + differ_datas = Metrics.merge_all_csv(differ_datas, differ_df) + + # print(idx) + # sys.exit (0) + connection.close() + server_socket.close() + + print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))#new + all_datas = all_datas.reset_index(drop=True) + sr_datas = sr_datas.reset_index(drop=True) + differ_datas = differ_datas.reset_index(drop=True) + + for i in range(params['row_num'], all_datas.shape[0]): + all_datas.drop(index=[i], inplace=True) + sr_datas.drop(index=[i], inplace=True) + differ_datas.drop(index=[i], inplace=True) + + f1,accuracy,precision,recall = Metrics.relabeling_strategy(all_datas, strategy_params) + + temp_f1 = Decimal(f1).quantize(Decimal("0.0000")) + temp_acc = Decimal(accuracy).quantize(Decimal("0.0000")) + temp_prec = Decimal(precision).quantize(Decimal("0.0000")) + temp_rec = Decimal(recall).quantize(Decimal("0.0000")) + print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))#new + print('F1-score: ', float(temp_f1)) + print('precision: ', float(temp_prec)) + print('accuracy: ', float(temp_acc)) + print('recall: ', float(temp_rec)) + + +# evaluate model performance +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('-c', '--config', type=str, default='//02DiffAD-main/config/smd_time_test.json', + help='JSON file for configuration') + parser.add_argument('-p', '--phase', type=str, choices=['train ', 'val', 'test'], + help='Run either train(training) or val(generation)', default='test') + parser.add_argument('-gpu', '--gpu_ids', type=str, default=None) + parser.add_argument('-debug', '-d', action='store_true') + parser.add_argument('-enable_wandb', action='store_true') + parser.add_argument('-log_wandb_ckpt', action='store_true') + parser.add_argument('-log_eval', action='store_true') + + temp_list = [] + model_epoch = 100 + + # parse configs + args = parser.parse_args() + opt = Logger.parse(args, model_epoch) + # Convert to NoneDict, which return None for missing key. + opt = Logger.dict_to_nonedict(opt) + logger_name = 'test' + str(model_epoch) + # logging + Logger.setup_logger(logger_name, opt['path']['log'], 'test', level=logging.INFO) + logger = logging.getLogger('base') + logger.info(Logger.dict2str(opt)) + tb_logger = SummaryWriter(log_dir=opt['path']['tb_logger']) + + #开始测试 + test_set = Data.create_dataset(opt['datasets']['test'], 'test') + + test_loader = Data.create_dataloader(test_set, opt['datasets']['test'], 'test') + logger.info('Initial Dataset Finished') + logger_test = logging.getLogger(logger_name) # test logger + + start_label = opt['model']['beta_schedule']['test']['start_label'] + end_label = opt['model']['beta_schedule']['test']['end_label'] + step_label = opt['model']['beta_schedule']['test']['step_label'] + step_t = opt['model']['beta_schedule']['test']['step_t'] + strategy_params = { + 'start_label': start_label, + 'end_label': end_label, + 'step_label': step_label, + 'step_t': step_t + } + + params = { + 'opt': opt, + 'logger': logger, + 'logger_test': logger_test, + 'model_epoch': model_epoch, + 'row_num': test_set.row_num, + 'col_num': test_set.col_num + } + + time_test(params, strategy_params, temp_list) + logging.shutdown() diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/time_test.py b/subject1-4/dynamicSplit/02DiffAD-main_high/time_test.py new file mode 100644 index 0000000..c4f9053 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/time_test.py @@ -0,0 +1,133 @@ +import argparse +import logging +import os +import time + +import pandas as pd +import torch +from tensorboardX import SummaryWriter + +import core.logger as Logger +import core.metrics as Metrics +import data as Data +import model as Model +from decimal import Decimal + + +def time_test(params, strategy_params, temp_list): + torch.backends.cudnn.enabled = True + torch.backends.cudnn.benchmark = True + opt = params['opt'] + logger = params['logger'] + logger_test = params['logger_test'] + model_epoch = params['model_epoch'] + + diffusion = Model.create_model(opt) + logger.info('Initial Model Finished') + + current_step = diffusion.begin_step + current_epoch = diffusion.begin_epoch + + if opt['path']['resume_state']: + logger.info('Resuming training from epoch: {}, iter: {}.'.format( + current_epoch, current_step)) + + diffusion.set_new_noise_schedule( + opt['model']['beta_schedule'][opt['phase']], schedule_phase=opt['phase']) + + logger.info('Begin Model Evaluation.') + idx = 0 + + all_datas = pd.DataFrame() + sr_datas = pd.DataFrame() + differ_datas = pd.DataFrame() + + result_path = '{}'.format(opt['path']['results']) + os.makedirs(result_path, exist_ok=True) + + print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))#news + for _, test_data in enumerate(test_loader): + idx += 1 + diffusion.feed_data(test_data) + diffusion.test(continous=False) + visuals = diffusion.get_current_visuals() + + all_data, sr_df, differ_df = Metrics.tensor2allcsv(visuals, params['col_num']) + all_datas = Metrics.merge_all_csv(all_datas, all_data) + sr_datas = Metrics.merge_all_csv(sr_datas, sr_df) + differ_datas = Metrics.merge_all_csv(differ_datas, differ_df) + + print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))#news + all_datas = all_datas.reset_index(drop=True) + sr_datas = sr_datas.reset_index(drop=True) + differ_datas = differ_datas.reset_index(drop=True) + + for i in range(params['row_num'], all_datas.shape[0]): + all_datas.drop(index=[i], inplace=True) + sr_datas.drop(index=[i], inplace=True) + differ_datas.drop(index=[i], inplace=True) + + f1 = Metrics.relabeling_strategy(all_datas, strategy_params) + temp_f1 = Decimal(f1) + # temp_f1 = Decimal(f1).quantize(Decimal("0.0000")) + print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))#new + print('F1-score: ', float(temp_f1)) + + +# evaluate model performance +if __name__ == '__main__': + print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))#news + parser = argparse.ArgumentParser() + parser.add_argument('-c', '--config', type=str, default='//02DiffAD-main/config/msl_time_test.json', + help='JSON file for configuration') + parser.add_argument('-p', '--phase', type=str, choices=['train ', 'val', 'test'], + help='Run either train(training) or val(generation)', default='test') + parser.add_argument('-gpu', '--gpu_ids', type=str, default=None) + parser.add_argument('-debug', '-d', action='store_true') + parser.add_argument('-enable_wandb', action='store_true') + parser.add_argument('-log_wandb_ckpt', action='store_true') + parser.add_argument('-log_eval', action='store_true') + + temp_list = [] + model_epoch = 100 + + # parse configs + args = parser.parse_args() + opt = Logger.parse(args, model_epoch) + # Convert to NoneDict, which return None for missing key. + opt = Logger.dict_to_nonedict(opt) + logger_name = 'test' + str(model_epoch) + # logging + Logger.setup_logger(logger_name, opt['path']['log'], 'test', level=logging.INFO) + logger = logging.getLogger('base') + logger.info(Logger.dict2str(opt)) + tb_logger = SummaryWriter(log_dir=opt['path']['tb_logger']) + + test_set = Data.create_dataset(opt['datasets']['test'], 'test') + + test_loader = Data.create_dataloader(test_set, opt['datasets']['test'], 'test') + logger.info('Initial Dataset Finished') + logger_test = logging.getLogger(logger_name) # test logger + + start_label = opt['model']['beta_schedule']['test']['start_label'] + end_label = opt['model']['beta_schedule']['test']['end_label'] + step_label = opt['model']['beta_schedule']['test']['step_label'] + step_t = opt['model']['beta_schedule']['test']['step_t'] + strategy_params = { + 'start_label': start_label, + 'end_label': end_label, + 'step_label': step_label, + 'step_t': step_t + } + + params = { + 'opt': opt, + 'logger': logger, + 'logger_test': logger_test, + 'model_epoch': model_epoch, + 'row_num': test_set.row_num, + 'col_num': test_set.col_num + } + + time_test(params, strategy_params, temp_list) + logging.shutdown() diff --git a/subject1-4/dynamicSplit/02DiffAD-main_high/time_train.py b/subject1-4/dynamicSplit/02DiffAD-main_high/time_train.py new file mode 100644 index 0000000..a1f87e3 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_high/time_train.py @@ -0,0 +1,87 @@ +import argparse +import logging +import math + +import torch +from tensorboardX import SummaryWriter + +import core.logger as Logger +import data as Data +import model as Model + +# train model +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('-c', '--config', type=str, default='//02DiffAD-main/config/smd_time_train.json', + help='JSON file for configuration') + parser.add_argument('-p', '--phase', type=str, choices=['train', 'val'], + help='Run either train(training) or val(generation)', default='train') + parser.add_argument('-gpu', '--gpu_ids', type=str, default=None) + parser.add_argument('-debug', '-d', action='store_true') + parser.add_argument('-enable_wandb', action='store_true') + parser.add_argument('-log_wandb_ckpt', action='store_true') + parser.add_argument('-log_eval', action='store_true') + + # parse configs + args = parser.parse_args() + opt = Logger.parse(args) + # Convert to NoneDict, which return None for missing key. + opt = Logger.dict_to_nonedict(opt) + + # logging + torch.backends.cudnn.enabled = True + torch.backends.cudnn.benchmark = True + + Logger.setup_logger(None, opt['path']['log'], + 'train', level=logging.INFO, screen=True) + Logger.setup_logger('val', opt['path']['log'], 'val', level=logging.INFO) + logger = logging.getLogger('base') + logger.info(Logger.dict2str(opt)) + tb_logger = SummaryWriter(log_dir=opt['path']['tb_logger']) + + for phase, dataset_opt in opt['datasets'].items(): + if phase == 'train' and args.phase != 'val': + train_set = Data.create_dataset(dataset_opt, phase) + train_loader = Data.create_dataloader(train_set, dataset_opt, phase) + + logger.info('Initial Dataset Finished') + + diffusion = Model.create_model(opt) + logger.info('Initial Model Finished') + + current_step = diffusion.begin_step + current_epoch = diffusion.begin_epoch + n_epoch = opt['train']['n_epoch'] + + if opt['path']['resume_state']: + logger.info('Resuming training from epoch: {}, iter: {}.'.format( + current_epoch, current_step)) + + diffusion.set_new_noise_schedule( + opt['model']['beta_schedule'][opt['phase']], schedule_phase=opt['phase']) + + save_model_iter = math.ceil(train_set.__len__() / opt['datasets']['train']['batch_size']) + while current_epoch < n_epoch: + current_epoch += 1 + for _, train_data in enumerate(train_loader): + current_step += 1 + if current_epoch > n_epoch: + break + diffusion.feed_data(train_data) + diffusion.optimize_parameters() + # log + if current_epoch % opt['train']['print_freq'] == 0 and current_step % save_model_iter == 0: + logs = diffusion.get_current_log() + message = ' '.format( + current_epoch, current_step) + for k, v in logs.items(): + message += '{:s}: {:.4e} '.format(k, v) + tb_logger.add_scalar(k, v, current_step) + logger.info(message) + + # save model + if current_epoch % opt['train']['save_checkpoint_freq'] == 0 and current_step % save_model_iter == 0: + logger.info('Saving models and training states.') + diffusion.save_network(current_epoch, current_step) + + logger.info('End of training.') diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/client2.py b/subject1-4/dynamicSplit/02DiffAD-main_low/client2.py new file mode 100644 index 0000000..10704c0 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/client2.py @@ -0,0 +1,29 @@ + +import socket +import random +import string +import time +import schedule + + +def establish_connection(ip='100.64.0.28',port=9999): + + + +def sent_data(): + data_size_bytes = 1 * 1024 * 1024 # 发送 1-10MB 的数据 + data = #generate_random_data(data_size_bytes) + print("开始发送数据...") + start_time = time.time() + + client_socket.sendall(data) + end_time = time.time() + elapsed_time = end_time - start_time + + print("数据发送完成") + + client_socket.close() + +if __name__ == "__main__": + + diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/config/msl_time_test.json b/subject1-4/dynamicSplit/02DiffAD-main_low/config/msl_time_test.json new file mode 100644 index 0000000..bb9a3a7 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/config/msl_time_test.json @@ -0,0 +1,71 @@ +{ + "name": "MSL_TEST", + "phase": "test", + "gpu_ids": [ + 0 + ], + "path": { + "log": "logs", + "tb_logger": "tb_logger", + "results": "results", + "checkpoint": "checkpoint", + "resume_state": "//experiments/MSL_TRAIN_16_128_20/checkpoint/E100" + }, + "datasets": { + "test": { + "name": "msl_test", + "mode": "HR", + "dataroot": "//02DiffAD-main/tf_dataset/msl/msl_test.csv", + "datatype": "time", + "l_resolution": 16, + "r_resolution": 128, + "data_len": -1 + } + }, + "model": { + "which_model_G": "sr3", + "finetune_norm": false, + "unet": { + "in_channel": 2, + "out_channel": 1, + "inner_channel": 32, + "norm_groups": 16, + "channel_multiplier": [ + 1, + 2, + 4, + 8, + 16 + ], + "attn_res": [], + "res_blocks": 1, + "dropout": 0 + }, + "beta_schedule": { + "train": { + "schedule": "linear", + "n_timestep": 20, + "linear_start": 1e-6, + "linear_end": 1e-2 + }, + "test": { + "schedule": "linear", + "start_label": 1, + "end_label": 2001, + "step_label": 1, + "step_t": 1000, + "n_timestep": 100, + "linear_start": 1e-6, + "linear_end": 1e-2 + } + }, + "diffusion": { + "time_size": 128, + "channels": 1, + "conditional": true + } + }, + "wandb": { + "project": "distributed_time" + } +} \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/config/msl_time_train.json b/subject1-4/dynamicSplit/02DiffAD-main_low/config/msl_time_train.json new file mode 100644 index 0000000..8440faa --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/config/msl_time_train.json @@ -0,0 +1,80 @@ +{ + "name": "MSL_TRAIN", + "phase": "train", + "gpu_ids": [ + 1, + 3 + ], + "path": { + "log": "logs", + "tb_logger": "tb_logger", + "results": "results", + "checkpoint": "checkpoint", + "resume_state": null + }, + "datasets": { + "train": { + "name": "msl_train", + "mode": "HR", + "dataroot": "//02DiffAD-main/tf_dataset/msl/msl_train.csv", + "datatype": "time", + "l_resolution": 16, + "r_resolution": 128, + "batch_size": 32, + "num_workers": 4, + "use_shuffle": false, + "data_len": -1 + } + }, + "model": { + "which_model_G": "sr3", + "finetune_norm": false, + "unet": { + "in_channel": 2, + "out_channel": 1, + "inner_channel": 32, + "norm_groups": 16, + "channel_multiplier": [ + 1, + 2, + 4, + 8, + 16 + ], + "attn_res": [], + "res_blocks": 1, + "dropout": 0 + }, + "beta_schedule": { + "train": { + "schedule": "linear", + "n_timestep": 20, + "linear_start": 1e-6, + "linear_end": 1e-2 + } + }, + "diffusion": { + "time_size": 128, + "channels": 1, + "conditional": true + } + }, + "train": { + "n_epoch": 100, + "val_freq": 100, + "save_checkpoint_freq": 100, + "print_freq": 10, + "optimizer": { + "type": "adam", + "lr": 3e-6 + }, + "ema_scheduler": { + "step_start_ema": 5000, + "update_ema_every": 1, + "ema_decay": 0.9999 + } + }, + "wandb": { + "project": "distributed_time" + } +} \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/config/psm_time_test.json b/subject1-4/dynamicSplit/02DiffAD-main_low/config/psm_time_test.json new file mode 100644 index 0000000..a78f9da --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/config/psm_time_test.json @@ -0,0 +1,71 @@ +{ + "name": "PSM_TEST", + "phase": "test", + "gpu_ids": [ + 0 + ], + "path": { + "log": "logs", + "tb_logger": "tb_logger", + "results": "results", + "checkpoint": "checkpoint", + "resume_state": "experiments/PSM_TRAIN_16_128_100/checkpoint/E20" + }, + "datasets": { + "test": { + "name": "psm_test", + "mode": "HR", + "dataroot": "tf_dataset/psm/psm_test.csv", + "datatype": "time", + "l_resolution": 16, + "r_resolution": 128, + "data_len": -1 + } + }, + "model": { + "which_model_G": "sr3", + "finetune_norm": false, + "unet": { + "in_channel": 2, + "out_channel": 1, + "inner_channel": 32, + "norm_groups": 16, + "channel_multiplier": [ + 1, + 2, + 4, + 8, + 16 + ], + "attn_res": [], + "res_blocks": 1, + "dropout": 0 + }, + "beta_schedule": { + "train": { + "schedule": "linear", + "n_timestep": 100, + "linear_start": 1e-6, + "linear_end": 1e-2 + }, + "test": { + "schedule": "linear", + "start_label": 1, + "end_label": 2001, + "step_label": 1, + "step_t": 1000, + "n_timestep": 100, + "linear_start": 1e-6, + "linear_end": 1e-2 + } + }, + "diffusion": { + "time_size": 128, + "channels": 1, + "conditional": true + } + }, + "wandb": { + "project": "distributed_time" + } +} \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/config/psm_time_train.json b/subject1-4/dynamicSplit/02DiffAD-main_low/config/psm_time_train.json new file mode 100644 index 0000000..c9cd489 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/config/psm_time_train.json @@ -0,0 +1,80 @@ +{ + "name": "PSM_TRAIN", + "phase": "train", + "gpu_ids": [ + 0, + 1 + ], + "path": { + "log": "logs", + "tb_logger": "tb_logger", + "results": "results", + "checkpoint": "checkpoint", + "resume_state": null + }, + "datasets": { + "train": { + "name": "psm_train", + "mode": "HR", + "dataroot": "tf_dataset/psm/psm_train.csv", + "datatype": "time", + "l_resolution": 16, + "r_resolution": 128, + "batch_size": 32, + "num_workers": 4, + "use_shuffle": false, + "data_len": -1 + } + }, + "model": { + "which_model_G": "sr3", + "finetune_norm": false, + "unet": { + "in_channel": 2, + "out_channel": 1, + "inner_channel": 32, + "norm_groups": 16, + "channel_multiplier": [ + 1, + 2, + 4, + 8, + 16 + ], + "attn_res": [], + "res_blocks": 1, + "dropout": 0 + }, + "beta_schedule": { + "train": { + "schedule": "linear", + "n_timestep": 100, + "linear_start": 1e-6, + "linear_end": 1e-2 + } + }, + "diffusion": { + "time_size": 128, + "channels": 1, + "conditional": true + } + }, + "train": { + "n_epoch": 100, + "val_freq": 100, + "save_checkpoint_freq": 10, + "print_freq": 10, + "optimizer": { + "type": "adam", + "lr": 3e-6 + }, + "ema_scheduler": { + "step_start_ema": 5000, + "update_ema_every": 1, + "ema_decay": 0.9999 + } + }, + "wandb": { + "project": "distributed_time" + } +} \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/config/smap_time_test.json b/subject1-4/dynamicSplit/02DiffAD-main_low/config/smap_time_test.json new file mode 100644 index 0000000..c73f713 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/config/smap_time_test.json @@ -0,0 +1,71 @@ +{ + "name": "SMAP_TEST", + "phase": "test", + "gpu_ids": [ + 0 + ], + "path": { + "log": "logs", + "tb_logger": "tb_logger", + "results": "results", + "checkpoint": "checkpoint", + "resume_state": "//experiments/SMAP_TRAIN_128_2048_20/checkpoint/E100" + }, + "datasets": { + "test": { + "name": "smap_test", + "mode": "HR", + "dataroot": "//02DiffAD-main/tf_dataset/smap/smap_test.csv", + "datatype": "time", + "l_resolution": 128, + "r_resolution": 2048, + "data_len": -1 + } + }, + "model": { + "which_model_G": "sr3", + "finetune_norm": false, + "unet": { + "in_channel": 2, + "out_channel": 1, + "inner_channel": 32, + "norm_groups": 16, + "channel_multiplier": [ + 1, + 2, + 4, + 8, + 16 + ], + "attn_res": [], + "res_blocks": 1, + "dropout": 0 + }, + "beta_schedule": { + "train": { + "schedule": "linear", + "n_timestep": 20, + "linear_start": 1e-6, + "linear_end": 1e-2 + }, + "test": { + "schedule": "linear", + "start_label": 1, + "end_label": 3001, + "step_label": 1, + "step_t": 1000, + "n_timestep": 20, + "linear_start": 1e-6, + "linear_end": 1e-2 + } + }, + "diffusion": { + "time_size": 2048, + "channels": 1, + "conditional": true + } + }, + "wandb": { + "project": "distributed_time" + } +} \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/config/smap_time_train.json b/subject1-4/dynamicSplit/02DiffAD-main_low/config/smap_time_train.json new file mode 100644 index 0000000..d5d1909 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/config/smap_time_train.json @@ -0,0 +1,80 @@ +{ + "name": "SMAP_TRAIN", + "phase": "train", + "gpu_ids": [ + 1, + 3 + ], + "path": { + "log": "logs", + "tb_logger": "tb_logger", + "results": "results", + "checkpoint": "checkpoint", + "resume_state": null + }, + "datasets": { + "train": { + "name": "smap_train", + "mode": "HR", + "dataroot": "//02DiffAD-main/tf_dataset/smap/smap_train.csv", + "datatype": "time", + "l_resolution": 128, + "r_resolution": 2048, + "batch_size": 32, + "num_workers": 4, + "use_shuffle": false, + "data_len": -1 + } + }, + "model": { + "which_model_G": "sr3", + "finetune_norm": false, + "unet": { + "in_channel": 2, + "out_channel": 1, + "inner_channel": 32, + "norm_groups": 16, + "channel_multiplier": [ + 1, + 2, + 4, + 8, + 16 + ], + "attn_res": [], + "res_blocks": 1, + "dropout": 0 + }, + "beta_schedule": { + "train": { + "schedule": "linear", + "n_timestep": 20, + "linear_start": 1e-6, + "linear_end": 1e-2 + } + }, + "diffusion": { + "time_size": 2048, + "channels": 1, + "conditional": true + } + }, + "train": { + "n_epoch": 100, + "val_freq": 100, + "save_checkpoint_freq": 10, + "print_freq": 10, + "optimizer": { + "type": "adam", + "lr": 3e-6 + }, + "ema_scheduler": { + "step_start_ema": 5000, + "update_ema_every": 1, + "ema_decay": 0.9999 + } + }, + "wandb": { + "project": "distributed_time" + } +} \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/config/smd_time_test.json b/subject1-4/dynamicSplit/02DiffAD-main_low/config/smd_time_test.json new file mode 100644 index 0000000..ed8fc90 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/config/smd_time_test.json @@ -0,0 +1,71 @@ +{ + "name": "SMD_TEST", + "phase": "test", + "gpu_ids": [ + 0 + ], + "path": { + "log": "logs", + "tb_logger": "tb_logger", + "results": "results", + "checkpoint": "checkpoint", + "resume_state": "./experiments/SMD_TRAIN_128_2048_20/checkpoint/E100" + }, + "datasets": { + "test": { + "name": "smd_test", + "mode": "HR", + "dataroot": "./tf_dataset/smd/smd_test.csv", + "datatype": "time", + "l_resolution": 128, + "r_resolution": 2048, + "data_len": -1 + } + }, + "model": { + "which_model_G": "sr3", + "finetune_norm": false, + "unet": { + "in_channel": 2, + "out_channel": 1, + "inner_channel": 32, + "norm_groups": 16, + "channel_multiplier": [ + 1, + 2, + 4, + 8, + 16 + ], + "attn_res": [], + "res_blocks": 1, + "dropout": 0 + }, + "beta_schedule": { + "train": { + "schedule": "linear", + "n_timestep": 20, + "linear_start": 1e-6, + "linear_end": 1e-2 + }, + "test": { + "schedule": "linear", + "start_label": 1, + "end_label": 1001, + "step_label": 1, + "step_t": 1000, + "n_timestep": 20, + "linear_start": 1e-6, + "linear_end": 1e-2 + } + }, + "diffusion": { + "time_size": 2048, + "channels": 1, + "conditional": true + } + }, + "wandb": { + "project": "distributed_time" + } +} \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/config/smd_time_train.json b/subject1-4/dynamicSplit/02DiffAD-main_low/config/smd_time_train.json new file mode 100644 index 0000000..12e176f --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/config/smd_time_train.json @@ -0,0 +1,80 @@ +{ + "name": "SMD_TRAIN", + "phase": "train", + "gpu_ids": [ + 0, + 1 + ], + "path": { + "log": "logs", + "tb_logger": "tb_logger", + "results": "results", + "checkpoint": "checkpoint", + "resume_state": null + }, + "datasets": { + "train": { + "name": "smd_train", + "mode": "HR", + "dataroot": "//02DiffAD-main/tf_dataset/smd/smd_train.csv", + "datatype": "time", + "l_resolution": 128, + "r_resolution": 2048, + "batch_size": 8, + "num_workers": 4, + "use_shuffle": false, + "data_len": -1 + } + }, + "model": { + "which_model_G": "sr3", + "finetune_norm": false, + "unet": { + "in_channel": 2, + "out_channel": 1, + "inner_channel": 32, + "norm_groups": 16, + "channel_multiplier": [ + 1, + 2, + 4, + 8, + 16 + ], + "attn_res": [], + "res_blocks": 1, + "dropout": 0 + }, + "beta_schedule": { + "train": { + "schedule": "linear", + "n_timestep": 20, + "linear_start": 1e-6, + "linear_end": 1e-2 + } + }, + "diffusion": { + "time_size": 2048, + "channels": 1, + "conditional": true + } + }, + "train": { + "n_epoch": 100, + "val_freq": 100, + "save_checkpoint_freq": 100, + "print_freq": 10, + "optimizer": { + "type": "adam", + "lr": 3e-6 + }, + "ema_scheduler": { + "step_start_ema": 5000, + "update_ema_every": 1, + "ema_decay": 0.9999 + } + }, + "wandb": { + "project": "distributed_time" + } +} \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/core/__pycache__/logger.cpython-37.pyc b/subject1-4/dynamicSplit/02DiffAD-main_low/core/__pycache__/logger.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cfefb82c3279ac7f0d56de3e6d90c0fdf2c56f14 GIT binary patch literal 4123 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 literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/core/logger.py b/subject1-4/dynamicSplit/02DiffAD-main_low/core/logger.py new file mode 100644 index 0000000..672af18 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/core/logger.py @@ -0,0 +1,143 @@ +import json +import logging +import os +from collections import OrderedDict +from datetime import datetime + + +def mkdirs(paths): + if isinstance(paths, str): + os.makedirs(paths, exist_ok=True) + else: + for path in paths: + os.makedirs(path, exist_ok=True) + + +def get_timestamp(): + return datetime.now().strftime('%y%m%d_%H%M%S') + + +def parse(args, model_epoch=None): + phase = args.phase + opt_path = args.config + gpu_ids = args.gpu_ids + enable_wandb = args.enable_wandb + # remove comments starting with '//' + json_str = '' + with open(opt_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.split('//')[0] + '\n' + json_str += line + + opt = json.loads(json_str, object_pairs_hook=OrderedDict) + + # set log directory + if args.debug: + opt['name'] = 'debug_{}'.format(opt['name']) + if opt['phase'] == 'train': + experiments_root = os.path.join( + 'experiments', '{}_{}_{}_{}'.format(opt['name'], opt['datasets']['train']['l_resolution'], + opt['datasets']['train']['r_resolution'], + opt['model']['beta_schedule']['train']['n_timestep'])) + elif opt['phase'] == 'test': + experiments_root = os.path.join( + 'experiments', '{}_{}_{}_{}_{}'.format(opt['name'], opt['datasets']['test']['l_resolution'], + opt['datasets']['test']['r_resolution'], + opt['model']['beta_schedule']['test']['n_timestep'], model_epoch)) + + opt['path']['experiments_root'] = experiments_root + for key, path in opt['path'].items(): + if 'resume' not in key and 'experiments' not in key: + opt['path'][key] = os.path.join(experiments_root, path) + mkdirs(opt['path'][key]) + + opt['phase'] = phase + + # export CUDA_VISIBLE_DEVICES + if gpu_ids is not None: + opt['gpu_ids'] = [int(id) for id in gpu_ids.split(',')] + gpu_list = gpu_ids + else: + gpu_list = ','.join(str(x) for x in opt['gpu_ids']) + os.environ['CUDA_VISIBLE_DEVICES'] = gpu_list + print('export CUDA_VISIBLE_DEVICES=' + gpu_list) + + if len(gpu_list) > 1: + opt['distributed'] = True + else: + opt['distributed'] = False + + # debug + if 'debug' in opt['name']: + opt['train']['print_freq'] = 2 + opt['train']['save_checkpoint_freq'] = 3 + opt['datasets']['train']['batch_size'] = 2 + opt['model']['beta_schedule']['train']['n_timestep'] = 10 + opt['datasets']['train']['data_len'] = 6 + + # W&B Logging + try: + log_wandb_ckpt = args.log_wandb_ckpt + opt['log_wandb_ckpt'] = log_wandb_ckpt + except: + pass + try: + log_eval = args.log_eval + opt['log_eval'] = log_eval + except: + pass + try: + log_infer = args.log_infer + opt['log_infer'] = log_infer + except: + pass + opt['enable_wandb'] = enable_wandb + + return opt + + +class NoneDict(dict): + def __missing__(self, key): + return None + + +# convert to NoneDict, which return None for missing key. +def dict_to_nonedict(opt): + if isinstance(opt, dict): + new_opt = dict() + for key, sub_opt in opt.items(): + new_opt[key] = dict_to_nonedict(sub_opt) + return NoneDict(**new_opt) + elif isinstance(opt, list): + return [dict_to_nonedict(sub_opt) for sub_opt in opt] + else: + return opt + + +def dict2str(opt, indent_l=1): + '''dict to string for logger''' + msg = '' + for k, v in opt.items(): + if isinstance(v, dict): + msg += ' ' * (indent_l * 2) + k + ':[\n' + msg += dict2str(v, indent_l + 1) + msg += ' ' * (indent_l * 2) + ']\n' + else: + msg += ' ' * (indent_l * 2) + k + ': ' + str(v) + '\n' + return msg + + +def setup_logger(logger_name, root, phase, level=logging.INFO, screen=False): + '''set up logger''' + l = logging.getLogger(logger_name) + formatter = logging.Formatter( + '%(asctime)s.%(msecs)03d - %(levelname)s: %(message)s', datefmt='%y-%m-%d %H:%M:%S') + log_file = os.path.join(root, '{}.log'.format(phase)) + fh = logging.FileHandler(log_file, mode='w') + fh.setFormatter(formatter) + l.setLevel(level) + l.addHandler(fh) + if screen: + sh = logging.StreamHandler() + sh.setFormatter(formatter) + l.addHandler(sh) diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/core/metrics.py b/subject1-4/dynamicSplit/02DiffAD-main_low/core/metrics.py new file mode 100644 index 0000000..2691ae9 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/core/metrics.py @@ -0,0 +1,169 @@ +import numpy as np +import pandas as pd +from sklearn.metrics import f1_score, accuracy_score, recall_score, precision_score, mean_squared_error + + +def squeeze_tensor(tensor): + return tensor.squeeze().cpu() + + +def update_csv_col_name(all_datas): + df = all_datas.copy() + df.columns = [0, 1, 2, 3] + + return df + + +def tensor2allcsv(visuals, col_num): + df = pd.DataFrame() + sr_df = pd.DataFrame(squeeze_tensor(visuals['SR'])) + ori_df = pd.DataFrame(squeeze_tensor(visuals['ORI'])) + lr_df = pd.DataFrame(squeeze_tensor(visuals['LR'])) + inf_df = pd.DataFrame(squeeze_tensor(visuals['INF'])) + + if col_num != 1: + for i in range(col_num, sr_df.shape[1]): + sr_df.drop(labels=i, axis=1, inplace=True) + ori_df.drop(labels=i, axis=1, inplace=True) + lr_df.drop(labels=i, axis=1, inplace=True) + inf_df.drop(labels=i, axis=1, inplace=True) + + df['SR'] = sr_df.mean(axis=1) + df['ORI'] = ori_df.mean(axis=1) + df['LR'] = lr_df.mean(axis=1) + df['INF'] = inf_df.mean(axis=1) + + df['differ'] = (ori_df - sr_df).abs().mean(axis=1) + df['label'] = squeeze_tensor(visuals['label']) + + differ_df = (sr_df - ori_df) + + return df, sr_df, differ_df + + +def merge_all_csv(all_datas, all_data): + all_datas = pd.concat([all_datas, all_data]) + return all_datas + + +def save_csv(data, data_path): + data.to_csv(data_path, index=False) + + +def get_mean(df): + mean = df['value'].astype('float32').mean() + normal_mean = df['value'][df['label'] == 0].astype('float32').mean() + anomaly_mean = df['value'][df['label'] == 1].astype('float32').mean() + + return mean, normal_mean, anomaly_mean + + +def get_val_mean(df): + mean_dict = {} + + ori = 'ORI' + ori_mean = df[ori].astype('float32').mean() + ori_normal_mean = df[ori][df['label'] == 0].astype('float32').mean() + ori_anomaly_mean = df[ori][df['label'] == 1].astype('float32').mean() + + gen_mean = df['SR'].astype('float32').mean() + gen_normal_mean = df['SR'][df['label'] == 0].astype('float32').mean() + gen_anomaly_mean = df['SR'][df['label'] == 1].astype('float32').mean() + + mean_dict['MSE'] = mean_squared_error(df[ori], df['SR']) + + mean_dict['ori_mean'] = ori_mean + mean_dict['ori_normal_mean'] = ori_normal_mean + mean_dict['ori_anomaly_mean'] = ori_anomaly_mean + + mean_dict['gen_mean'] = gen_mean + mean_dict['gen_normal_mean'] = gen_normal_mean + mean_dict['gen_anomaly_mean'] = gen_anomaly_mean + + mean_dict['mean_differ'] = ori_mean - gen_mean + mean_dict['normal_mean_differ'] = ori_normal_mean - gen_normal_mean + mean_dict['anomaly_mean_differ'] = ori_anomaly_mean - gen_anomaly_mean + + mean_dict['ori_no-ano_differ'] = ori_normal_mean - ori_anomaly_mean + mean_dict['ori_mean-no_differ'] = ori_mean - ori_normal_mean + mean_dict['ori_mean-ano_differ'] = ori_mean - ori_anomaly_mean + + mean_dict['gen_no-ano_differ'] = gen_normal_mean - gen_anomaly_mean + mean_dict['gen_mean-no_differ'] = gen_mean - gen_normal_mean + mean_dict['gen_mean-ano_differ'] = gen_mean - gen_anomaly_mean + + return mean_dict + + +def relabeling_strategy(df, params): + y_true = [] + best_N = 0 + best_f1 = -1 + best_thred = 0 + best_predictions = [] + thresholds = np.arange(params['start_label'], params['end_label'], params['step_label']) + + df_sort = df.sort_values(by="differ", ascending=False) + df_sort = df_sort.reset_index(drop=False) + + for t in thresholds: + # if (t - 1) % params['step_t'] == 0: + # print("t: ", t) + y_true, y_pred, thred = predict_labels(df_sort, t) + for i in range(len(y_true)): + if y_pred[i] == 1 and y_true[i] == 1: + j = i - 1 + while j >= 0 and y_true[j] == 1 and y_pred[j] == 0: + y_pred[j] = 1 + j -= 1 + j = i + 1 + while j < len(y_pred) and y_true[j] == 1 and y_pred[j] == 0: + y_pred[j] = 1 + j += 1 + + f1 = calculate_f1(y_true, y_pred) + if f1 > best_f1: + best_f1 = f1 + best_N = t + best_thred = thred + best_predictions = y_pred + + accuracy = calculate_accuracy(y_true, best_predictions) + precision = calculate_precision(y_true, best_predictions) + recall = calculate_recall(y_true, best_predictions) + + return best_f1,accuracy,precision,recall + + +def predict_labels(df_sort, num): + df_sort['pred_label'] = 0 + df_sort.loc[0:num - 1, 'pred_label'] = 1 + thred = df_sort.loc[num - 1, 'differ'] + + df_sort = df_sort.set_index('index') + df_sort = df_sort.sort_index() + + y_true = df_sort['label'].tolist() + y_pred = df_sort['pred_label'].tolist() + + return y_true, y_pred, thred + + +def calculate_accuracy(y_true, y_pred): + accuracy = accuracy_score(y_true, y_pred) + return accuracy + + +def calculate_precision(y_true, y_pred): + precision = precision_score(y_true, y_pred) + return precision + + +def calculate_recall(y_true, y_pred): + recall = recall_score(y_true, y_pred) + return recall + + +def calculate_f1(y_true, y_pred): + f1 = f1_score(y_true, y_pred) + return f1 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/data/LRHR_dataset.py b/subject1-4/dynamicSplit/02DiffAD-main_low/data/LRHR_dataset.py new file mode 100644 index 0000000..b22f921 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/data/LRHR_dataset.py @@ -0,0 +1,43 @@ +from torch.utils.data import Dataset + +from data.prepare_time_data import PrepareTimeData + + +class LRHRDataset(Dataset): + def __init__(self, dataroot, datatype, phase, l_resolution=16, r_resolution=128, + split='train', data_len=-1, need_LR=False): + self.datatype = datatype + self.data_len = data_len + self.need_LR = need_LR + self.split = split + self.phase = phase + self.pre_data = PrepareTimeData(data_path=dataroot, phase=phase, base=l_resolution, size=r_resolution) + self.row_num = self.pre_data.get_row_num() + self.col_num = self.pre_data.get_col_num() + + if datatype == 'time': + self.hr_path, self.sr_path, self.labels, self.pre_labels = self.pre_data.get_sr_data() + self.dataset_len = len(self.sr_path) + if self.data_len <= 0: + self.data_len = self.dataset_len + else: + self.data_len = min(self.data_len, self.dataset_len) + else: + raise NotImplementedError( + 'data_type [{:s}] is not recognized.'.format(datatype)) + + def __len__(self): + return self.data_len + + def __getitem__(self, index): + + data_LR = None + data_ORI = self.hr_path[index] + data_HR = self.hr_path[index] + data_SR = self.sr_path[index] + data_label = self.labels[index] + + if self.phase == 'train': + return {'HR': data_HR, 'SR': data_SR, 'Index': index} + else: + return {'ORI': data_ORI, 'HR': data_HR, 'SR': data_SR, 'label': data_label, 'Index': index} diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/data/__init__.py b/subject1-4/dynamicSplit/02DiffAD-main_low/data/__init__.py new file mode 100644 index 0000000..9c915ff --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/data/__init__.py @@ -0,0 +1,42 @@ +'''create dataset and dataloader''' +import logging + +import torch.utils.data + + +def create_dataloader(dataset, dataset_opt, phase): + '''create dataloader ''' + if phase == 'train': + return torch.utils.data.DataLoader( + dataset, + batch_size=dataset_opt['batch_size'], + shuffle=dataset_opt['use_shuffle'], + num_workers=dataset_opt['num_workers'], + pin_memory=True) + elif phase == 'val': + return torch.utils.data.DataLoader( + dataset, batch_size=1, shuffle=False, num_workers=1, pin_memory=True) + elif phase == 'test': + return torch.utils.data.DataLoader( + dataset, batch_size=1, shuffle=False, num_workers=1, pin_memory=True) + else: + raise NotImplementedError( + 'Dataloader [{:s}] is not found.'.format(phase)) + + +def create_dataset(dataset_opt, phase): + '''create dataset''' + mode = dataset_opt['mode'] + from data.LRHR_dataset import LRHRDataset as D + dataset = D(dataroot=dataset_opt['dataroot'], + datatype=dataset_opt['datatype'], + l_resolution=dataset_opt['l_resolution'], + r_resolution=dataset_opt['r_resolution'], + split=phase, + data_len=dataset_opt['data_len'], + need_LR=(mode == 'LR'), + phase=phase) + logger = logging.getLogger('base') + logger.info('Dataset [{:s} - {:s}] is created.'.format(dataset.__class__.__name__, + dataset_opt['name'])) + return dataset diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/data/__pycache__/LRHR_dataset.cpython-37.pyc b/subject1-4/dynamicSplit/02DiffAD-main_low/data/__pycache__/LRHR_dataset.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fba63b4d4fed74b4bb401570224523be5d07696d GIT binary patch literal 1587 zcmZuxTZeH zV=suiAP7DQzPJzBM}5enApVnjRh0b!KAZ1U&&CZ{O?~y%sZ&*_s=m|LyWJK;`Sgd; z?v(~(e^BSFcp%qMi#Gt0NuIEjN1PLP5+`*dm$MI;bftI1q^J0y8+p>-VPWGGGg!z? zusJTrg(^XpKGJGB*6QOpRb-uz%USV3uAvsM0The4WRWAgvLS;b9=Wn97mgSfZ^<@V zUv{v`qG{h6ZVl%DK_`mwFs$r~jhdoGidXg<2ety^mTv0#r`L1giodubM!o zY5?8J1$w1laWJp)CI8-o1!H#`4}%j14sY-U%UhKroqLWxwzl>O8PP> ztb548FMx6B-sAc^F!Th!|4X?-R_Y&8OgvjGSEcuGt#VHIA^!$C{X*J33Wbl^#aNRV? zjl60m5|x=CQ%Z_kL*p0IBrY}SL%V>eIn_$gjHrD_l|tuVh-^PK!JO3ANuJc!IjOCM zwi8XTr|a+oSnN3($@sQPil{}4*W9>>BWlx5kd6(?P2CxLM6NPL3Ey%dXWOB=uIaPS`~S+U&eW6I{I8sUm&j~0us>AOuvZcpSJ-w zu8uau>B(<@|McjuAHV(c_g_aFZ(Y7J+PJ(K@9w_0`DO}{jVQm~HSi^w2edpxYDT1#}7r!1!$S>7DHO#ExN@0)CPupP(bz0W^7+Rs30YfXtXP zXdH?qn-At#Mj7Htj$F7-c~f!e9J@QL&LZR%bbpMWgH^LP(6m+P8fR;0oE@lbJCo|m z&^PXf!)<*DgZdSK@vSEGtK{wJHL|Z0TqK~^4Fh|06wr%6zLC|oz+!XL)^JX+ zS<5=rE7NtzeKZMCU~9TztAk}k&S-Jw0J@5HaX+1^`>jB z*xM|Zxt{FxA@ro^(;+pzY;=)m9~nkJU_rkLD_5J=cJBXeWt#8QVZKY!D`?}6({UdI DO$U=G literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/data/__pycache__/LRHR_dataset.cpython-38.pyc b/subject1-4/dynamicSplit/02DiffAD-main_low/data/__pycache__/LRHR_dataset.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1e39c78c33598a1ab6c337e134f89dfec4d299be GIT binary patch literal 1609 zcmZux%Wfn!6t!JdUDdB7lMKT{JQ@&4B|$f00TM!JfG{M|D4-6oC_q+E+nKJJdi1y| zf`p2MNF*dA{veCV5*B=rx2*CDY{I$j^w1;WZl5~$`gMJM?63R%4nz5M>qx)fV(f1+ zR*MhgHfr@2KrzKLmh*&j;vy5dmw23g&XlM8Gp2maPrbxf!9I&yml(lfZo}P>)V30Eu;s;^oqJmZO{BGo=)SfHc2_y($nh1P8M z?s#W>y~^bVMqd65ut9AmX>oala%b9xXIY42v+PsU>MuYe8YWp20(lbwMbiR$jR*AW zpy6PC6Da<>4-eWNv>t~S3>>||+m3e{p~ORB&YiD&!M>y3J=8wx8tQtzfwulB2fqQv zmG_XF-@sr={^-wole}b~QcS#9tGAT@_+}$6_$mJd`M{2Yz1UCM3JH|+Nj>Wzy)X%ns|cENsuLScary)(F-Ce=zeRKL5Nonw7a8Ws?H` zQGPTnl^(tG?sj@`@bUKBIV3is@J1v;w=)DfoFCap%CtypDMQRsy#`>S#h1TL-s3$H z@fYyz@Q&CNf=5@!H&>)QTuv~hb6ghURGoN9#SjaLg73xL1&_~jaJ%3a@DfZLO3I#; zWK;sc`0>`$tGV{6Yom4)3jN7V`38n!C(z{s*6`=q32w(VgU+E^@&#bRF}fw5;+9%!1pBHc#ZNrSPg&aKFEZHT~b)TNouhLC(# s4QZ=}&N#V6bcnk~PqL&3!^ziOa5wh<7PQfai(o$@5mvN(PxQQh0WJ-Vh5!Hn literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/data/__pycache__/__init__.cpython-37.pyc b/subject1-4/dynamicSplit/02DiffAD-main_low/data/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..583fdb411b8bb294ea66cad9f625dff815b054ca GIT binary patch literal 1262 zcmZ`(OOGQp5Vqa!$0V6yW_NjnXYXwzvC(Ly719bJ9$5rZG>2IZCHhb}l&bS7ldqRk`X@-rwDA5m=x8FrMB? z2>AmKPZtB_UD);xfFvU#sbm!$(ID9{-)&I$IcXG<6DmlH#rry zT&hufVU@6_i|MpdzTGTp@ufCr%GghO+~BKxy0sdPr`Eh|M6GIV&VBSnQC(5E{m^r# ztXsY@fL?8refHG@yZ$^cZQf{?PxYda{i9w2HE1(A_3^@$mGvCE>s$EUF!a^mJksvt zdS0noHBQNg#%SY{sWx@tdXZ1J=lnDk?CU9p1xA1z~#HWezX%^pvMCicaH$>PFBBL$32e$_QV}RtT5K>Qs vFt_3C_XFkof${y&a3n{dO!(khX5_C4>9e%}Jw=xsC&5g8KUJEamDi>0} zfy>D0B*3K^C?_z#hG~8Q*f2pan7(JpoX*)i*pLml?ji;r!!ALmucN1En}F@;+E%3E z0Oqy61^V*;^fnaj%V@){=x_8_DmswD;rixY3cIi~7g?PbwQD`g?PSJHv6kcZ(nxM* z%jvX~u3axH{zB;ssm%|)P-9juX|y`TU29R)ypomDD;GS^%QqChe(ORjja`2>gnBj3 zetP+Z+5VgrCaaarrfOM>{%J3U7?hsOT(q=BXVKJRP z8Q!m;1Oq%g;Jl~{%XxpXa>u)Jaa8Owz;>EP0EDG9rHsb@VgJOj-xIcb-o`uq^*&%U zeXHMxlM^K1y8#3xNLSC15`+!Vu}ij0FcFlbqT7Iy4KPIjHvl7#vBv~C1K(0unK-y$ zz@ygdbQ@ZB8Hn~3-A0?}G87%)K{$`+3D_QX$rW${?hJtuN9&_KMgXZ@SV3Jh_OC}> zdvx~Q*$|RPO^Q{}N;Q&QEu`y|TuY-$=$ootNAK^vJuhWFW}~xSsy~D~br<0ygpUDS zWEN#%^(P>YlUho_M`!vbYQksWbbY6Bo_XSA_p|@_vkP1FU0COp?4{#l46ly?`*uOZ z`UAWuDb@LTQJ=emb7@B)OYOp<2JXCv>I2RvWo``TF6A8W;=C8@W6=3P^lh}FLwy6+ z7%!9BGinF7@N-kdcaAYNlK~(}IzW?#Bs;476{jtFL}Q?c{v2$8{t4$oO*q$h$ldTi pL*M@keP47Wh^LM}u;(3_t$hgTm(aLnDZj$jnG_(TDNBR&*1zPWP@ez* literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/data/__pycache__/prepare_time_data.cpython-37.pyc b/subject1-4/dynamicSplit/02DiffAD-main_low/data/__pycache__/prepare_time_data.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d96b52ba38087ebbdf94a7d3f4e1cc3c8c0f7bd4 GIT binary patch literal 8695 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 a>f@s6#P0n>Dj#rH)TKSSr_xj-XZ{b0LcfLp literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/data/__pycache__/prepare_time_data.cpython-38.pyc b/subject1-4/dynamicSplit/02DiffAD-main_low/data/__pycache__/prepare_time_data.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..512dafab3324b460ed69a511d6cb0b5e2e15e974 GIT binary patch literal 8676 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 Op#%0Lomywjob^95?5*ek literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/data/prepare_time_data.py b/subject1-4/dynamicSplit/02DiffAD-main_low/data/prepare_time_data.py new file mode 100644 index 0000000..8252bb2 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/data/prepare_time_data.py @@ -0,0 +1,359 @@ +import math +import warnings + +import numpy as np +import pandas as pd +import torch + +warnings.filterwarnings("ignore") + + +class PrepareTimeData: + def __init__(self, data_path, phase, base, size): + self.data_path = data_path + self.phase = phase + self.base = base + self.size = size + + self.data_name = self.data_path.split('/')[-1].split('_')[0] + self.read_dataset(self.data_path, self.data_name) + self.df = self.ori_df.copy() + self.row_num = self.ori_df.shape[0] + self.col_num = self.ori_df.shape[1] + self.mean = self.df.mean(axis=1) + + self.df = self.get_mean_df(self.df) + self.df = self.vertical_merge_df(self.df) + self.df = self.join_together_labels(self.df) + self.df = self.fill_data(self.df) + self.df = self.standardize_data(self.df) + + def get_hr_data(self): + df = self.df.copy() + ori_values, values, labels, pre_labels = self.get_data_by_interval(df) + + return ori_values, values, labels, pre_labels + + def get_sr_data(self): + df = self.df.copy() + ori_values, values, labels, pre_labels = self.get_data_by_insert_normal() + + return ori_values, values, labels, pre_labels + + def get_mean_df(self, df): + df = df.copy() + for col in df.columns: + df[col] = self.mean + return df + + def vertical_merge_df(self, df): + df = df.copy() + two_power = 2 + + if self.col_num < 16: + two_power = 16 + df_temp = pd.DataFrame() + col_count = 0 + for i in range(two_power - self.col_num): + if col_count >= self.col_num: + col_count = 0 + df_temp[i] = df.iloc[:, col_count] + col_count = col_count + 1 + else: + while self.col_num > two_power: + two_power = two_power * 2 + df_temp = df.iloc[:, 0:(two_power - self.col_num)] + + col_name = [] + for i in range(self.col_num): + col_name.append('value_' + str(i)) + + df.columns = col_name + col_name = [] + for i in range(self.col_num, two_power): + col_name.append('value_' + str(i)) + + df_temp.columns = col_name + df = pd.concat([df, df_temp], axis=1) + return df + + def join_together_labels(self, df): + df = df.copy() + + if self.phase == 'train': + df['label'] = 0 + else: + df['label'] = self.test_labels + return df + + def fill_data(self, df): + df = df.copy() + data_end = math.ceil(self.row_num / self.size) * self.size + + for i in range(self.row_num, data_end): + # df = df._append(pd.Series(), ignore_index=True) + df = df.append(pd.Series(), ignore_index=True) + # df = pd.concat([df, pd.Series()], ignore_index=True) + # df = pd.DataFrame(df).append(new_row, ignore_index=True) + # df = pd.concat([df, pd.DataFrame([new_row])], ignore_index=True) + + df.fillna(0, inplace=True) + return df + + def read_dataset(self, data_path, data_name): + if data_name.upper().find('MSL') != -1: + cols = [-1] + self.get_dataset(data_path, cols) + elif data_name.upper().find('PSM') != -1: + if self.phase == 'train': + cols = [-1] + self.get_dataset(data_path, cols) + if self.ori_df.columns.__contains__('timestamp_(min)'): + self.ori_df.drop(columns=['timestamp_(min)'], inplace=True) + else: + cols = [-1] + self.get_dataset(data_path, cols) + if self.ori_df.columns.__contains__('timestamp_(min)'): + self.ori_df.drop(columns=['timestamp_(min)'], inplace=True) + self.test_labels.drop(columns=['timestamp_(min)'], inplace=True) + elif data_name.upper().find('SMAP') != -1: + cols = [0, 1, 2, 3, 4, 7, 8, 9, 10, 12, 13, 15, 16, 19, 20] + self.get_dataset(data_path, cols) + elif data_name.upper().find('SMD') != -1: + cols = [0, 1, 3, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 28, 33, 35, 36, 37] + self.get_dataset(data_path, cols) + + def get_dataset(self, data_path, cols): + if self.phase == 'train': + if -1 in cols: + self.ori_df = pd.read_csv(data_path) + else: + self.ori_df = pd.read_csv(data_path, usecols=cols) + else: + if -1 in cols: + self.ori_df = pd.read_csv(data_path) + else: + self.ori_df = pd.read_csv(data_path, usecols=cols) + + test_label_path = self.data_path.replace('_test.csv', '_test_label.csv') + self.test_labels = pd.read_csv(test_label_path) + + def get_data_by_insert_normal(self): + df = pd.DataFrame(columns=['value', 'label']) + df['value'] = self.df['value_0'] + df['label'] = self.df['label'] + + df_pre_label = self.mutation_point(df) + insert_datas = self.insert_normal(df_pre_label) + + ori_values = [] + values = [] + labels = [] + pre_labels = [] + + start_index = 0 + end_index = self.size + + for col in self.df.columns: + if col == 'label': + continue + self.df[col] = insert_datas['value'] + self.df['pre_label'] = insert_datas['pre_label'] + + ori_df = self.vertical_merge_df(self.ori_df) + ori_df = self.fill_data(ori_df) + + for i in range(0, self.df.shape[0], self.size): + insert_data = pd.DataFrame() + ori_value = pd.DataFrame() + + insert_data = pd.concat([insert_data, self.df[start_index: end_index]]) + ori_value = pd.concat([ori_value, ori_df[start_index: end_index]]) + start_index += self.size + end_index += self.size + + value = insert_data.copy().drop(['label', 'pre_label'], axis=1) + label = insert_data['label'] + pre_label = insert_data['pre_label'] + + value = torch.tensor(np.array(value).astype(np.float32)) + label = torch.tensor(np.array(label).astype(np.int64)) + pre_label = torch.tensor(np.array(pre_label).astype(np.int64)) + ori_value = torch.tensor(np.array(ori_value).astype(np.float32)) + + values.append(value.unsqueeze(0)) + labels.append(label) + pre_labels.append(pre_label) + ori_values.append(ori_value.unsqueeze(0)) + + return ori_values, values, labels, pre_labels + + def standardize_data(self, df): + df = df.copy() + name = self.data_path.split('.csv')[0] + print(name, "Points: {}".format(self.row_num)) + df = self.complete_value(df) + + if self.phase != 'train': + anomaly_len = len(df[df['label'] == 1].index.tolist()) + print("Labeled anomalies: {}".format(anomaly_len)) + + return df + + def complete_value(self, df): + + df.fillna(0, inplace=True) + return df + + def get_mutation_point(self, df_pre_label, start_index, end_index, last_size_var): + size_var = df_pre_label['value'][start_index: end_index].var() + label_count = len(df_pre_label[start_index: end_index][df_pre_label['label'] == 1].index.tolist()) + + if last_size_var == 0: + times = 'Nan' + else: + times = size_var / last_size_var + if times < 1 and times != 0: + times = 1 / times + + if times != "Nan" and times >= 10: + df_pre_label['pre_label'][start_index: end_index] = 1 + else: + df_pre_label['pre_label'][start_index: end_index] = 0 + + return size_var + + def mutation_point(self, df): + df_pre_label = df.copy() + df_pre_label['pre_label'] = 0 + + size = 128 + start_index = 0 + end_index = size + all_var = df_pre_label['value'].var() + + last_size_var = 0 + for i in range(int(self.row_num / size)): + last_size_var = self.get_mutation_point(df_pre_label, start_index, end_index, last_size_var) + + start_index += size + end_index += size + + self.get_mutation_point(df_pre_label, start_index, self.row_num - 1, last_size_var) + return df_pre_label + + def get_index(self, indexes): + count = 0 + start_indexes = [] + end_indexes = [] + + if len(indexes) != 0: + count = count + 1 + start_indexes.append(indexes[0]) + + for i in range(1, len(indexes)): + if indexes[i - 1] + 1 != indexes[i]: + count = count + 1 + end_indexes.append(indexes[i - 1]) + start_indexes.append(indexes[i]) + + end_indexes.append(indexes[len(indexes) - 1]) + + return start_indexes, end_indexes, count + + def insert_normal(self, data): + pre_labels = 'pre_label' + + nor_indexes = data[0:self.row_num][data[pre_labels] == 0].index.tolist() + ano_indexes = data[0:self.row_num][data[pre_labels] == 1].index.tolist() + + nor_start_indexes, nor_end_indexes, nor_count = self.get_index(nor_indexes) + ano_start_indexes, ano_end_indexes, ano_count = self.get_index(ano_indexes) + + interval = int(self.size / self.base) + ano_len = 2 + + df = pd.DataFrame(columns=['ind', 'value', 'label', 'pre_label']) + + for i in range(nor_count): + + if nor_end_indexes[i] - nor_start_indexes[i] + 1 < interval: + temp_df = pd.DataFrame(columns=['ind', 'value', 'label', 'pre_label']) + + x = range(nor_start_indexes[i], nor_end_indexes[i] + 1) + xp = [nor_start_indexes[i], nor_end_indexes[i]] + fp = [data['value'][nor_start_indexes[i]], data['value'][nor_end_indexes[i]]] + z = np.interp(x, xp, fp) + + temp_df['ind'] = x + temp_df['value'] = z + temp_df['pre_label'] = 0 + df = pd.concat([df, temp_df]) + else: + last_start_x = -1 + start_xs = range(nor_start_indexes[i], nor_end_indexes[i] + 1, interval) + xp = [] + fp = [] + for start_x in start_xs: + if start_x + interval > nor_end_indexes[i]: + last_start_x = start_x + break + + xp.append(start_x) + xp.append(start_x + interval - 1) + + fp.append(data['value'][start_x]) + fp.append(data['value'][start_x + interval - 1]) + + x = range(nor_start_indexes[i], last_start_x) + z = np.interp(x, xp, fp) + + temp_df = pd.DataFrame(columns=['ind', 'value', 'label', 'pre_label']) + temp_df['ind'] = x + temp_df['value'] = z + temp_df['pre_label'] = 0 + df = pd.concat([df, temp_df]) + + if last_start_x != -1: + temp_df = pd.DataFrame(columns=['ind', 'value', 'label', 'pre_label']) + + x = range(last_start_x, nor_end_indexes[i] + 1) + xp = [last_start_x, nor_end_indexes[i]] + fp = [data['value'][last_start_x], data['value'][nor_end_indexes[i]]] + z = np.interp(x, xp, fp) + + temp_df['ind'] = x + temp_df['value'] = z + temp_df['pre_label'] = 0 + df = pd.concat([df, temp_df]) + + for i in range(ano_count): + temp_df = pd.DataFrame(columns=['ind', 'value', 'label', 'pre_label']) + + x = range(ano_start_indexes[i] - 1, ano_end_indexes[i] + 2) + xp = [ano_start_indexes[i] - 1, ano_end_indexes[i] + 1] + fp = [data['value'][ano_start_indexes[i] - 1], data['value'][ano_end_indexes[i] + 1]] + z = np.interp(x, xp, fp) + + for j in range(len(x)): + if j == 0 or j == len(x) - 1: + continue + + temp_df.loc[x[j], 'ind'] = x[j] + temp_df.loc[x[j], 'value'] = z[j] + temp_df.loc[x[j], 'pre_label'] = 1 + + df = pd.concat([df, temp_df]) + + df = df.set_index(['ind'], inplace=False).sort_index() + df['label'] = data['label'] + for i in range(self.row_num, data.shape[0]): + df = df.append(pd.Series(), ignore_index=True) + df.fillna(0, inplace=True) + return df + + def get_row_num(self): + return self.row_num + + def get_col_num(self): + return self.col_num diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/model/__init__.py b/subject1-4/dynamicSplit/02DiffAD-main_low/model/__init__.py new file mode 100644 index 0000000..0eb77d1 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/model/__init__.py @@ -0,0 +1,10 @@ +import logging + +logger = logging.getLogger('base') + + +def create_model(opt): + from .model import DDPM as M + m = M(opt) + logger.info('Model [{:s}] is created.'.format(m.__class__.__name__)) + return m diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/__init__.cpython-37.pyc b/subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..54bd8d91fd9f3fafe38dfc71311f3954ade614ba GIT binary patch literal 445 zcmYjNJxc>Y5Z$?t`V}BB%Um1b}wAGk8pbyYEmiq0|XnJ zTxnw|i2uTJTSdtauy^)EaA4lf@Mhk=-Q8-nOfZh`9PbU!ch&rbj>R^nSVmxkK|p$h zlPNGQgPz88X55gT&ftjH<_u>@R~l!o;C)aHhEgyw_b|l@0>j;agfIahV;GZbm}sds z)tNpu#@f&v7Ba{br=h0Nohcz3q|t64b}pAXG2=n)j?WT zr$J}g%h$ux=l$)+>$B5XYi>A=X506?o%U+z`jL}g=}_uNeoAS5bRjFhj%dylP)Aq@ z1S(*`A|wk~+lDMEe||KOr2$V5a<7RR&iUNKKbS{CTAQeN9`G&oA3{CS(#rY|GyQPv literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/__init__.cpython-38.pyc b/subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab45257dcdcb10a5de99202a7f9699e0e3952e25 GIT binary patch literal 447 zcmYjNu};G<5cMTanpQ0!!N7#NMuG;xh7bagkyc2Er3hIec0#H+L2(!g?F16P(T@BM zqgST>0u$%J(39`k=Xdw+?Au&Ebal&I)tLNYjT%i5N`qZ$`yIzeHF22psEkB4G|dW-udfFt=)JVRL&yXV%1- zxJy_X&O%)}S{X4PG!4V+;mhu@claULnfnD!VeA}JX2ZEcrNwT7Vv`AMn`EdMzU9!n{LJSuPnavGy@ zaCj7ENpcY$$SA{0(=1>tE3%rg!P8WC|7Kwg_yMg&bOp%Cg=W*=w&>^2{i8 z#OmZg|A0a-z1YWIdTXKdKbdPwOU|YD{$|&bY}cU&kC^vnXWo0id2il(deUgr2*y|6 z_4+@1g#7M4W`kq#7*oFkB8Z>~*)BL8ux&=kQzDq)uZZBsY?}-EoV2~ykR{#7(b-^F zJjT?Yfk?7V1=(hT3igUXiwh6j6D3gwFNuoq!ONm5YTy;IBX%30@Po zfY!9tC!v;~4~0x32jhn0aD{w=snaS#h_y=W{#%cId)QCMr2EFX@HEt#Q;_H0?m7jYzQZAb3LX`qc9*`;DF zN5g2Z&8(+o(pP2Z{zz0E?4OT7K3(sv2Cq+l{p*LH{`~&iKYshAxB9`_hrQLct+?O+ zcV^cQe8P6+jCF3VNBl{j|j%I9w9Ikvx()C=k1kJspPDY`1cdqelp)uu$&mdig z?K2xwSV5)IZo6!2v5r%1!W4z*i8w-a#zqdbWhhb~*Rx&{Yt#0M9H&Q?AIO*1b3&Js zu%?j-MNvO+Az1+-v__lMr? zXo#1NRE+8!rk#ys7@>MLu_(0LzIq$FmZhn!Z=s2Nf$B~Ynbc&KvI125iwG@nGfr0Vj|C*Mn|*$u-#&9ViHFEpV+Dx5T<0 z1c&Gh#fiEB>&o>fb<2^aBd%vCmon<1BkwxmTK+lWTBveQ;?g7UZ$9-aKA-;@`6)cF kK*0L>|4b)M)uWl>Ib*r)yhr;R#Wgow*VV2#eOl-L0w@&Kng9R* literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/base_model.cpython-38.pyc b/subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/base_model.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3da8f605c28b8459254af43ffe831b1b9783811d GIT binary patch literal 2055 zcmbtV&2Jk;6rYdvdgIt_>V$@(B3vOM`OpLfQE`Z(0+xD#2r1$cftJnAIN4-BoSAVU z*7}r6{2R$Je*pi?Tsd*(#sz+}8^>-Egiyzx_vYh$&wFpb?{r!O*X7fYfA+!V{A4IGG$cmTX49*PyUAy#Eq~*7T zkZJ7H%!XUTE%G&{-U29TNkU@i1uLnbPvFYQlKMcf98O%iJ0?6p7z5}D0^yBa+dLeN z!$fH7#bXg!9*@R~LR!CJc`-7!VG0!=SzpN4Ni1#aKprM}sEr)i<$5hgMSRp}*3&W_ zDj&R8M74qb`h4@K$mC`k<@j%AXEB`E{B&!O42NG1o@Y^lL+97#0Xz(=<;LjD24R@w zi3vj|OFKz~`qZP{zkTM@N%tlm8#BT?fpH#GfpHOXu3pjI%BDV3%Q&*0h)h(S)S%-I zmxfY`(A~JLuA)sRt8;xf_pwtj8*Y6^p?ZkZO7<14RNhv$is&X;GLhjZQc)(2RC)zG zGqoSi)!sw-e+*FFnJEjtt{zGg#$%;qZo=1z9!IHOy=dD`|S>NcObBn;rI|T=Yy~qO>=!nqD!iNUq=WPI|aH-ow-` zBqg~Zm)O=Zq_&ZdGnw|Oa$esKO0byZvR?gmZMIFtn}EwPsj}bvq1C(JAU1^#Ib< zBL`gPP%dTEdk(l#Rv$U=+yU3Z7l3Q7$~}rplB(w+xtamL`E{yWc-{no4XQ8DMxLvW aXN(KND%n-{4z_DEcU&*lu0R9Y=KlcnQP4jC literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/model.cpython-37.pyc b/subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/model.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..60f0c607a64793439df223f4e821eedd86c34e14 GIT binary patch literal 5353 zcmZ`-%WvGq8Rzh|B=;d%R%FR`oJ|6>-6Bz(6n(%j+Bj9@CbgBsHkx2-m!NhiiPSE4 zJ)E_jHTPtr0SW}|sfRWP?lG4lhoV5yd(dM~JO> zcivVTcwG;)#qGX72)Y3?Vxz2cXU4jXs|I&@?XkgYaq!6MHaWX#biA*ym$B1fs{Wqf zv55Ir(vx2?G@{LaE6U^RLmu~)y$iBOgO7gJoX86hu|Y@dnx7bZj5BUN_PQ1woA`;S@Ibukh1o33!`7$JfwO=V$mjS{i(V zpT)b$&++qkw>~j!qq~Glyr}H0t@p3@%=w92yy>A6=IgkNG$bpGM`mdjY{r-&trU<=fniWfbPUgP4!|v2vt{k_;-)I%*0>2hafJRIlb4=1=k6o)y~C#Lg+S5=V5 zGUV~Sq!%k2{Z|FqoARi+Kg@HrMpPEx$GMX{esW<8TMM7YE@#mo=HZA=AIn(eswv{T z<3z-HxGy5EZ0v=SM>0~*Bo@O^xzT78qtWdT_xEF=>?GS8Dwp^XNoDtwT&m#MijEwL z-hp!TeU*KMM+0S}a#fHHD-X+r9EPYG{b9s$UVTy39El{O`(pUj?63d*CfTTgl$um919?ko|3~7gf1A`dFO8JQ7F#1`2~Mv%qXH*YcRn)=bn`1Jo*WSqo2q zzs*+6mg%x}=HWkSl8J5}32$MmbYHU5pW?}vQ9w@(vQ6kLJPLG_?Q~3W8a?713eev@ zqQz@O>Ea?NqYf2@LL-j?9N3?tZU{yW5RZi zq((pDBN>k7V+rC3AEjAZGvl`t?K5rSBJpi%6;|oa4C2$&1`RH0+L1oZl|fp6WQvsN zw2?OPw#f$<4E(kWhg+XI(2iDiL67*x{tvH9O-yO&C1OmcTaft?4 zn5%*$PqJJ_8T^o$Wva0Stt5xo?<1JHuq}Am?y~l4Aw0{lKbFZb6IZZ;c0+Svs%EdB z#IX5%*gK4+cuVgv6p0{qi!CZnSb;6$T)v5pd<_NUX$G*#2L3JB;aOPZOKjq6xzb2M za$E?LDhpx$3Ke2;WfXH^{s=*dLY^U=)PsiNIPKY8{hyuo4 zueAMbY^FIZwuyR|il0+)jf(3il$%F`Q9nM$Bui_&3U(veI|y^=wC2zWmWU59`#n5) z0|jX~ab(pz%O-Wrhicu0XCMzjj35?kcPEJrOq!{M3%7|*ZQusPeTvapi&~!4kGxi` zx&%4q6E_jhp-s6}oI;q>9_?u{>LDM|0m!}#oOi{X`_Q9UruF10$t~R3`vtrNmEGC=CY|GhzB1uIakT%neqB5S&_W7tcX=~*(z$V$}2vTy=rM6 z>-NS%ka1DerX$QF#;V@<#DH51P7{|G>hVuhr16NHnkinw=BzZ~&fxY+8%`ggZFUW3 zY~ZYbk0?2nb&T>Q4!m!QBY|a5wO_< zZjs9BjmA~fwkt!eWfY;W-Ov`Pyx|yN4KU|~y{gm4d4Dg-$5B702%WE^Fn}*?wr;Mm zv--aV+c*y_GLKcyn7U9Fk{s!XRu)=NgAK@R#sJQd4oC|7Y;GBscxBWqbyMOXOFg1y z00G%DH?_g*KEMP^`enc^v_TJMNGRYX(Nd)w+IsArN$ugZ{c8K+bYkLpZKpzU?W=7# z;c-unMSKaJuK*OwgZ2}!h{j8=@M)*sJwtb!gFk@WyeASsXG9I{V&27lj`^83RX0%( zVkSr%hT4mY3)Jxfiq2dp3`jBSHnDK1PeSDhiHHuyPw;4nM(B?s%Cfm^+Mp&Y+F+gn zrweNdFl)i{zoR0xjewsTR#nMWm5vc-pV4bCdMWNWQwP8cZ&^z{_^)3SPU-`aIVGaX z)P2w{bTWp7YZWrBO})Y^k$@F$0lmI^@S!1_WeYWnJRQX>WYGq9KC`C;K9*>e!soCY zJiDZJjH7`2OuHIR!h{|QT8a32i*W!Q}1vz1U#G6-+nj^_v37HBoC?z93NFW zwsPXp5XM1>O(_4!GYUbtOBa)ko6$YwM;dw~V>-&6Ha9mrE6N<^BEnE*r`W1O{cW21 zEb;4r832LExXL6P!il-)(u9}wDmnJj$n%&=1XV2B#el9)=Y%ooEQp$sr|8I*r3TY<)tFRDX2Z^8y%O-bQr#6ClmFo3~B9V8NDy>?$2+^jlZ`7|P zot-{WvbkbWYn9RjyYW6Cwbr3}MQadZ6kfOFn1fEi|*esZ*2qP6aG*^7*?VoNn$Vc%7PZ}>f;^=dQ9;L5&3W$Ki~D_e;Khw_0CLXa zA{C^<&b~Liq5ON%N3`7 VOvp=z1WNH6NEsUl#0@jB{tqUB0~`PV literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/model.cpython-38.pyc b/subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/model.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5b417c9cb376fba19d0425af84e967504b2847c GIT binary patch literal 5434 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 literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/networks.cpython-38.pyc b/subject1-4/dynamicSplit/02DiffAD-main_low/model/__pycache__/networks.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e5b7f298038b9d6c90d587852ba00957106b20b2 GIT binary patch literal 3165 zcmbtW&2Jn<7Vqk>>7EaNhhWGeZANz4XU9%le)grymE68+c_7!Y$5nE2_RMVy10Jw)r|EH*y*E*|{_FB9B=q zJMy`6heZv($UW|V!lHmL@qmZmLf+)9PpqiPmwAWJLDJ&$d;yX+XK!2GmAjbH>UEiR zvm#U4-AZKo!$&J$Z+^G`*-L$!dh3T4>EV49ulx#RYVBA%?7*JdM>c177`JyFaYH#r zE_%EjENaT`IE?ff+}aJrm&EP(N5LJ7S;f$dbL(**{_1g8%{Z?f_vNW^el;H?VKo!n zVw1D5(MC_Zua?CJckki(0joEU_HSiHnh4!`B~krhuN0#VUibdzrEXJ)aoo=nDdSiN zaa<&$6r8)A6D(*U(jkF^b zhmg#Y!GBreJWTy`ZGBjd()Bzk@LwP8^-G?vU){KwZEwGP^QlpiK?qU4UZm=FDR$+R z@t$6;rj;?F7gvjE!J(qVFyPc`(4=q8Cp5Ux5FvoShlK+~wY3 z1+nK^I{@H$%eG>F2KhH)M(DHgd2Cs52x&St}YK-KJ;}Pp%amA_o2W-6R`j#h`Y4Eas_e zfyg3}B_hipT}Q0oqdnPA@>D!Tass^~gq2=7gJf;^QS`_QAQhA=Y@r78gj-c7F%NU|wAo2sXgJcQq7xP5U3w{0`-IOUM4zjE9aGwvAgFHWJ4@F!@C=&YuC}#M))7=l`S@u($*b z-KgQ~69~r-#oVlZ?xUfsBgO#;suq55K2=a#Y><1EH+8skXdfWej{GUABr4`jXt>aL z$7nRBHj>Xi@Qen)fyPB>_|O=VOa(?Zr$XMSX88yE7{>{!VbI&Z@H#3+mgL!fqO!7B z8>Mg=UwiMP7v#bF+OJAUmx*&&srVBJ_%(cV^TZwdm#OSL$jDkzs{qV#)%+D!ho%Ioy>V*RX%-%x&8oUsN9WGKdz{4gXJp$LtX2Plt;@$iEPKI})i$WhY|Fmq z+r+nRn+5m8)6h7Riv&B>4wH*lk)>0d@2l1Ua*^As7Iy&GC90#jHNs&!vJX&CIVve{ ztXjJbd86XE4_#|F5Vv@6EV*t?ogEyqq{+io3LxT|GY(^FS!>3%XIy8-&CR%Z!!5wd zBHpFL5CLc-+g;eHr8T#V{*{_PXGT2)$$7jFANmxOe3jbR-OmVSk3Yg6ttt$^uxfqE z#ARswq2iRk)1XVir%YZ{;m1rhk6Kd%G^}_C*2j9ZiptkKCJ6UWVHsaA?d zlU!xvJVVq5iBd%@QmLCD@m5~;cM-B&lw(*D*T{aTGTaelwx4!G@f;-L&qSUj@;pe? zIc->q7pQ}ROI#=NR}dZ4DpK3|)4GN014ouoHPfA~R3)+O4^uwLQ|&2%%GmYHIPoF| zM`2##x?UBl1y4MV9^~^?QfLgulQ`p2w|FL%$hIbwtL>--?~)KVFGlXWy;Mbuo5@7VEGg)EV%%;b9}6l)f2iI5geSV4$vF8S$?{|iYn^*pVrJTh zNn33fg>K)(ZRxE=cU&%Y-Np$N5RWls_ zVv|~d+4_~D5O1JaT@b=Ss&1K*C!Qc7UA#`pnQ@t!@YJ5nwZPm6g6oy{U!= 0: + v.requires_grad = True + v.data.zero_() + optim_params.append(v) + logger.info( + 'Params [{:s}] initialized to 0 and will optimize.'.format(k)) + else: + optim_params = list(self.netG.parameters()) + + self.optG = torch.optim.Adam( + optim_params, lr=opt['train']["optimizer"]["lr"]) + self.log_dict = OrderedDict() + self.load_network() + self.print_network() + + def feed_data(self, data): + self.data = self.set_device(data) + + def optimize_parameters(self): + self.optG.zero_grad() + l_pix = self.netG(self.data) + # need to average in multi-gpu + b, c, h, w = self.data['HR'].shape + l_pix = l_pix.sum() / int(b * c * h * w) + + l_pix.backward() + self.optG.step() + + # set log + self.log_dict['l_pix'] = l_pix.item() + + def test(self,client_socket, continous=False): + self.netG.eval() + + with torch.no_grad(): + ori = self.data['ORI'].squeeze() + min_num = ori.min().item() + max_num = ori.max().item() + if isinstance(self.netG, nn.DataParallel): + self.SR = self.netG.module.super_resolution( + self.data['SR'],client_socket, continous=continous, min_num=min_num, max_num=max_num) + else: + self.SR = self.netG.super_resolution( + self.data['SR'],client_socket, continous=continous, min_num=min_num, max_num=max_num) + self.netG.train() + + def sample(self, batch_size=1, continous=False): + self.netG.eval() + with torch.no_grad(): + if isinstance(self.netG, nn.DataParallel): + self.SR = self.netG.module.sample(batch_size, continous) + else: + self.SR = self.netG.sample(batch_size, continous) + self.netG.train() + + def set_loss(self): + if isinstance(self.netG, nn.DataParallel): + self.netG.module.set_loss(self.device) + else: + self.netG.set_loss(self.device) + + def set_new_noise_schedule(self, schedule_opt, schedule_phase='train'): + if self.schedule_phase is None or self.schedule_phase != schedule_phase: + self.schedule_phase = schedule_phase + if isinstance(self.netG, nn.DataParallel): + self.netG.module.set_new_noise_schedule( + schedule_opt, self.device) + else: + self.netG.set_new_noise_schedule(schedule_opt, self.device) + + def get_current_log(self): + return self.log_dict + + def get_current_visuals(self, need_LR=True, sample=False): + out_dict = OrderedDict() + if sample: + out_dict['SAM'] = self.SR.detach().float().cpu() + else: + out_dict['SR'] = self.SR.detach().float().cpu() + out_dict['INF'] = self.data['SR'].detach().float().cpu() + out_dict['ORI'] = self.data['ORI'].detach().float().cpu() + out_dict['HR'] = self.data['HR'].detach().float().cpu() + out_dict['label'] = self.data['label'].detach().cpu() + if need_LR and 'LR' in self.data: + out_dict['LR'] = self.data['LR'].detach().float().cpu() + else: + out_dict['LR'] = out_dict['INF'] + return out_dict + + def print_network(self): + s, n = self.get_network_description(self.netG) + if isinstance(self.netG, nn.DataParallel): + net_struc_str = '{} - {}'.format(self.netG.__class__.__name__, + self.netG.module.__class__.__name__) + else: + net_struc_str = '{}'.format(self.netG.__class__.__name__) + + logger.info( + 'Network G structure: {}, with parameters: {:,d}'.format(net_struc_str, n)) + logger.info(s) + + def save_network(self, epoch, iter_step): + gen_path = os.path.join( + self.opt['path']['checkpoint'], 'E{}_gen.pth'.format(epoch)) + opt_path = os.path.join( + self.opt['path']['checkpoint'], 'E{}_opt.pth'.format(epoch)) + # gen + network = self.netG + if isinstance(self.netG, nn.DataParallel): + network = network.module + state_dict = network.state_dict() + for key, param in state_dict.items(): + state_dict[key] = param.cpu() + torch.save(state_dict, gen_path) + # opt + opt_state = {'epoch': epoch, 'iter': iter_step, + 'scheduler': None, 'optimizer': None} + opt_state['optimizer'] = self.optG.state_dict() + torch.save(opt_state, opt_path) + + logger.info( + 'Saved model in [{:s}] ...'.format(gen_path)) + + def load_network(self): + load_path = self.opt['path']['resume_state'] + if load_path is not None: + logger.info( + 'Loading pretrained model for G [{:s}] ...'.format(load_path)) + gen_path = '{}_gen.pth'.format(load_path) + opt_path = '{}_opt.pth'.format(load_path) + # gen + network = self.netG + if isinstance(self.netG, nn.DataParallel): + network = network.module + network.load_state_dict(torch.load( + gen_path), strict=(not self.opt['model']['finetune_norm'])) + + if self.opt['phase'] == 'train': + # optimizer + opt = torch.load(opt_path) + self.optG.load_state_dict(opt['optimizer']) + self.begin_step = opt['iter'] + self.begin_epoch = opt['epoch'] diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/model/networks.py b/subject1-4/dynamicSplit/02DiffAD-main_low/model/networks.py new file mode 100644 index 0000000..d2769b5 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/model/networks.py @@ -0,0 +1,112 @@ +import functools +import logging + +import torch +import torch.nn as nn +from torch.nn import init + +logger = logging.getLogger('base') + + +# initialize +def weights_init_normal(m, std=0.02): + classname = m.__class__.__name__ + if classname.find('Conv') != -1: + init.normal_(m.weight.data, 0.0, std) + if m.bias is not None: + m.bias.data.zero_() + elif classname.find('Linear') != -1: + init.normal_(m.weight.data, 0.0, std) + if m.bias is not None: + m.bias.data.zero_() + elif classname.find('BatchNorm2d') != -1: + init.normal_(m.weight.data, 1.0, std) # BN also uses norm + init.constant_(m.bias.data, 0.0) + + +def weights_init_kaiming(m, scale=1): + classname = m.__class__.__name__ + if classname.find('Conv2d') != -1: + init.kaiming_normal_(m.weight.data, a=0, mode='fan_in') + m.weight.data *= scale + if m.bias is not None: + m.bias.data.zero_() + elif classname.find('Linear') != -1: + init.kaiming_normal_(m.weight.data, a=0, mode='fan_in') + m.weight.data *= scale + if m.bias is not None: + m.bias.data.zero_() + elif classname.find('BatchNorm2d') != -1: + init.constant_(m.weight.data, 1.0) + init.constant_(m.bias.data, 0.0) + + +def weights_init_orthogonal(m): + classname = m.__class__.__name__ + if classname.find('Conv') != -1: + init.orthogonal_(m.weight.data, gain=1) + if m.bias is not None: + m.bias.data.zero_() + elif classname.find('Linear') != -1: + init.orthogonal_(m.weight.data, gain=1) + if m.bias is not None: + m.bias.data.zero_() + elif classname.find('BatchNorm2d') != -1: + init.constant_(m.weight.data, 1.0) + init.constant_(m.bias.data, 0.0) + + +def init_weights(net, init_type='kaiming', scale=1, std=0.02): + # scale for 'kaiming', std for 'normal'. + logger.info('Initialization method [{:s}]'.format(init_type)) + if init_type == 'normal': + weights_init_normal_ = functools.partial(weights_init_normal, std=std) + net.apply(weights_init_normal_) + elif init_type == 'kaiming': + weights_init_kaiming_ = functools.partial( + weights_init_kaiming, scale=scale) + net.apply(weights_init_kaiming_) + elif init_type == 'orthogonal': + net.apply(weights_init_orthogonal) + else: + raise NotImplementedError( + 'initialization method [{:s}] not implemented'.format(init_type)) + + +# define network +def define_G(opt): + model_opt = opt['model'] + if model_opt['which_model_G'] == 'sr3': + from .sr3_modules import diffusion, unet + + if ('norm_groups' not in model_opt['unet']) or model_opt['unet']['norm_groups'] is None: + model_opt['unet']['norm_groups'] = 32 + + model = unet.UNet( + in_channel=model_opt['unet']['in_channel'], + out_channel=model_opt['unet']['out_channel'], + norm_groups=model_opt['unet']['norm_groups'], + inner_channel=model_opt['unet']['inner_channel'], + channel_mults=model_opt['unet']['channel_multiplier'], + attn_res=model_opt['unet']['attn_res'], + res_blocks=model_opt['unet']['res_blocks'], + dropout=model_opt['unet']['dropout'], + time_size=model_opt['diffusion']['time_size'] + ) + + netG = diffusion.GaussianDiffusion( + model, + time_size=model_opt['diffusion']['time_size'], + channels=model_opt['diffusion']['channels'], + loss_type='l1', # L1 or L2 + conditional=model_opt['diffusion']['conditional'], + schedule_opt=model_opt['beta_schedule']['train'] + ) + if opt['phase'] == 'train': + init_weights(netG, init_type='orthogonal') + + if opt['gpu_ids'] and opt['distributed']: + assert torch.cuda.is_available() + netG = nn.DataParallel(netG) + + return netG diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/__pycache__/diffusion.cpython-37.pyc b/subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/__pycache__/diffusion.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4424c1bb5fcb44b0485367b87b7362c398559b36 GIT binary patch literal 7979 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 IcY!wazmFY?a*v zGrW$H8lUBJ_?>yv;3s(FzQG%@zgge4TC<$pFq#XGF$-g*$)wkdMA3;7B!f=A)=%3- zCrgntQ=)cpn|IqZ`O)JdLGNpL^Q#~wD~wH6nxH0U56uN*$1beWEUg7&m+d$xw@Yx9 zlp+qhw7F3_Uo|fqrH#p$E036TcyX^6Hyw=IlXjNIx%AeOEGjdJ?IxbRnR{@eDquYCCP zNB{NXcUHfArR`9&;p5}i!>cy>EryMT)Z8+~^Lo3vId7DfqI3Wzw;tNuo;P-!_gT6G zUI)CN*Sw{r4oUIsIO#{Iby2&jkEvwb+qF^t0m^-pZ;#7ORsQ!Vub})-N(=qjS_xtN3WN{>*I1GE?S8~R)I0sJR|E<4V-rNWT9{hCKGBOWt$+7B^!(t; zsOVEKNvEBqdC{^q^HCrFdF3%q2+iAB4%rlxdAyHj{gdx4{?kAF?59_tOjbAAYR(8c zSWzQFCPT@Ds30YsA`|Tm=|&<-*JEjSqhdpvy^gfdtF(IAU5uPW-JYCZ$%@Z)dr91l z(<0_?2$6}VFa5l|5tDq1S?YO)NFAi*>uH6#n4^IzBOS>xSkl{wa-|8Hkm$-rH@X#v zB+lWePmS2ur1eO__MLkXTQft*6%y5N*oNTdj|g{-r)21v5Z!2Sn|vK3BIUGW`-r7;7fd2 zmDGnNzrs)P)2d{apXX=zS@@JW-sDg6r;s|q&+(@*hsJw`ZM5d0Nzcg>Z$|w*??fq? zOJxur)BZ>^xp;G>P4;W_P@1-!s`FPs3S-w8uswspj+I7e!etmCEEOnR1SoVElE!)hETkWXowQSgq4e7uQJTg{u7x|yJKM1gc${XPJPy}VSxK@y56Q{M zD%6*E$j`y=dD70~WKH}AW+dp)#IF(g43WzqvNlqHFzXfYRFyD<5~8p0KwreKg7Yfg zob=1E0w}`h&u81Gj%?D4qlq7pO4^>+sHe|^l*Xnu`sWG;b4do14X{OfYLn7WsCpa5 z_bTe0BlT|K?iyc#P~oVY6+s#yt-Rlb+EfG#h4S?{s!L5zFPP*}x^G{68+#?qA{*`+ z!2;>MbK?yv7l1dU3%{v&d3>kSjt?t=pT|W=8~!$!a)pdoz!vE>kK2tAdz)52dZ-z_ zYBxTBEhwOwnOT82ETA zdq!%OsOMg3ld~v-&1&gzpI085J8lsSYN#Rj6_7*OGvS7U!OW<9&s6(gFYV3QciE0# z%$5EwoydvO7&Lel;%x7-J%BouuOaVFwY~5C z-Dl*&0b@6g(y*PyYZs3#z0`a{kWm&-)1Yn$|F-;0O(z)DY!Q^hsyyC zfK{w^uP>bx8+%XT8tIKT*^MwKAaa|QDwouPr*~KFJ1qG|1XE6^S6?ky}^dO%T~E{s^9Opth$rcct+@{24~5K0}p_#{>QHW9Ky;yEI}LxfQO zf$f%yWPQ^3Zm505$lTuqS6+Y^tYMlXbN+MJ1$F_FSs(;s`K%6M)rH`Ku9IXL6pis zE>Id_8Vn=?v!$^wHN`vN6DuH4EoIcLt+0@+z`2t1JiJ{?P#4~57drYvbd`1W&OJaE zL&Q_V;Tiz!x? za05DQM&pc@?8|(1?1FV&sd*;9aAN&S_ zC&bhMNgMEX@M$Gm*JuHr3)b96(B#64`RJztfMu3Gx8Xl46etc$h>H=It|=|??Xofm zP+!Gc(|&1lrc~{@^U!+N+zEE7Wl&aW*PHH&GQY}tVXYSLbYaSAgT)$1(-Iq$9&dZI zF8+WDl;NpfqflSl7V#w%OIO6bI4Z;#K*Q-iERY3qtXMM5FWK_?AiHZ5p^##$s&zk!@5D*Vh5W~G6*O-Nfq@CnQW>aAfRGGo zYjG?LKsg7N_^{N>_7wZrQhy5_D(Gtf3E8Yp0TjX|n<11!0MtMz)G$?M~!8HsH(1GAUP;S}cyb?2r7GmWg#DwTL zh^hfz7L0+t2Z(TzfTX%Ia z*YuA&CEeRy^w4VPJ)hcRI+ep4?f1eQad8s=87egfAMG6WH?Ynei@`^Yu1&#C@b#pcLXes3KCOvj~+3n7@wRf)Yv#C1whe`nRvADaHv(0M#R- z1^>rruN;h41{f~@G@cyqhsTWf!;*taz>z$(;hI4cc*EFTg;~Y0|MOH+~O|ePmmrzSnpEPNvLTgZ3!fP7(g_NQIOpB4D z#7H+KH3CTKIzz+e1nUTOi>9gKnVkoW5P+i-s!|xNdp~iI2LH8Pq5JH#AaOXi~ zq~Hrc2DZ8V)N#r@oEP=3?C6wS($dHJd=42%kgH1)z$rJ#gY18yA z>W3^HE{802Cxc+~zQ1c?*UbkMGEpFkJJ%(3k3qOfSx9H4jYd-sb)_!QNM#DJKR|po zJfcUY5^-@4Rm!kEV%k@#bv95c{mZ!aTjkNK|AO3q<2AOQKf0*fLnHX&#F{QC$yKS%mPjC$2k!Zr@c`oeuDxUJ;A$Es50U=>*WD0z7~zvTCU*v^ z9Eiu*gt_GA67Z2u6U@bJi3O}wK~DiNl3)4*#OAn01`@)BusObFqa&rBXCA=V4XPX? z(BB>uiF<^TP*>0Y98x^aQU$4C{0w&?BvSP48;&4cs_NPPhQT3LhZ z3|6H1)^&9l6sFQ0l`?$)FL4pyz$Q%`#aK$jLsa|^RelrXI05OYJDE5?Dj*|x_Q%wm zJghWtT-R2*p>Z0W5l|VNc?PUSzc8OdS!wd~BBgq-pLW(V(N!330=wCFI`LgCc<&Rl zvg-=VDXUHB1Q+AVF6~mingLsttS#AwWOp@$qsg^^#|W$46L%=*Y=wY@(x$tni9ONc zIa=;dz?qZO6JSTYMphY?7~uUE0A8;Bk?q$^4ZP}fdySZ^ZZ5K#S^F5+K%>E>QQ$m! z$YziTQ-G#uKI4``yQ@S=;s>L{w&I`Q4)ptU!cp=H0s8BmA6Nk+G*N{X)#3!R;K8H95Ac@TW{#Nv(pdd>I!SA5%d=jL&M9^Pm1I`jsW;H+u| zNnQZ6c!J0xNOMj+iyv80A2%`UT-|s`kG?0y?Lyt>i!Ty8$+)(~besxo=+86HQ}zN8 r5+mupqrL*F@wC((a!LMW{hjbtns-jK@F8$D00s4H`F`*Wt>b?ILXba* literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/__pycache__/unet.cpython-37.pyc b/subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/__pycache__/unet.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2ec7a53f62dbe159a3ed1c9d5ed50230e31343e5 GIT binary patch literal 8252 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 literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/__pycache__/unet.cpython-38.pyc b/subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/__pycache__/unet.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..914d38468f8770184e50ff0233c2c5f5851c6297 GIT binary patch literal 8164 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 literal 0 HcmV?d00001 diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/diffusion.py b/subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/diffusion.py new file mode 100644 index 0000000..f10c109 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/diffusion.py @@ -0,0 +1,273 @@ +import math +from functools import partial +from inspect import isfunction + +import numpy as np +import torch +from torch import nn +from tqdm import tqdm + +import io +def _warmup_beta(linear_start, linear_end, n_timestep, warmup_frac): + betas = linear_end * np.ones(n_timestep, dtype=np.float64) + warmup_time = int(n_timestep * warmup_frac) + betas[:warmup_time] = np.linspace( + linear_start, linear_end, warmup_time, dtype=np.float64) + return betas + + +def make_beta_schedule(schedule, n_timestep, linear_start=1e-4, linear_end=2e-2, cosine_s=8e-3): + if schedule == 'quad': + betas = np.linspace(linear_start ** 0.5, linear_end ** 0.5, + n_timestep, dtype=np.float64) ** 2 + elif schedule == 'linear': + betas = np.linspace(linear_start, linear_end, + n_timestep, dtype=np.float64) + elif schedule == 'warmup10': + betas = _warmup_beta(linear_start, linear_end, + n_timestep, 0.1) + elif schedule == 'warmup50': + betas = _warmup_beta(linear_start, linear_end, + n_timestep, 0.5) + elif schedule == 'const': + betas = linear_end * np.ones(n_timestep, dtype=np.float64) + elif schedule == 'jsd': # 1/T, 1/(T-1), 1/(T-2), ..., 1 + betas = 1. / np.linspace(n_timestep, + 1, n_timestep, dtype=np.float64) + elif schedule == "cosine": + timesteps = ( + torch.arange(n_timestep + 1, dtype=torch.float64) / + n_timestep + cosine_s + ) + alphas = timesteps / (1 + cosine_s) * math.pi / 2 + alphas = torch.cos(alphas).pow(2) + alphas = alphas / alphas[0] + betas = 1 - alphas[1:] / alphas[:-1] + betas = betas.clamp(max=0.999) + else: + raise NotImplementedError(schedule) + return betas + + +# gaussian diffusion trainer class +def exists(x): + return x is not None + + +def default(val, d): + if exists(val): + return val + return d() if isfunction(d) else d + + +class GaussianDiffusion(nn.Module): + def __init__(self, denoise_fn, time_size, channels=3, loss_type='l1', + conditional=True, schedule_opt=None): + + super().__init__() + self.channels = channels + self.time_size = time_size + self.denoise_fn = denoise_fn + self.loss_type = loss_type + self.conditional = conditional + if schedule_opt is not None: + pass + + def set_loss(self, device): + if self.loss_type == 'l1': + self.loss_func = nn.L1Loss(reduction='sum').to(device) + elif self.loss_type == 'l2': + self.loss_func = nn.MSELoss(reduction='sum').to(device) + else: + raise NotImplementedError() + + def set_new_noise_schedule(self, schedule_opt, device): + to_torch = partial(torch.tensor, dtype=torch.float32, device=device) + + betas = make_beta_schedule( + schedule=schedule_opt['schedule'], + n_timestep=schedule_opt['n_timestep'], + linear_start=schedule_opt['linear_start'], + linear_end=schedule_opt['linear_end']) + + betas = betas.detach().cpu().numpy() if isinstance( + betas, torch.Tensor) else betas + + alphas = 1. - betas + alphas_cumprod = np.cumprod(alphas, axis=0) + alphas_cumprod_prev = np.append(1., alphas_cumprod[:-1]) + self.sqrt_alphas_cumprod_prev = np.sqrt( + np.append(1., alphas_cumprod)) + + timesteps, = betas.shape + self.num_timesteps = int(timesteps) + + self.register_buffer('betas', to_torch(betas)) + self.register_buffer('alphas_cumprod', to_torch(alphas_cumprod)) + self.register_buffer('alphas_cumprod_prev', + to_torch(alphas_cumprod_prev)) + + # calculations for diffusion q(x_t | x_{t-1}) and others + self.register_buffer('sqrt_alphas_cumprod', + to_torch(np.sqrt(alphas_cumprod))) + self.register_buffer('sqrt_one_minus_alphas_cumprod', + to_torch(np.sqrt(1. - alphas_cumprod))) + self.register_buffer('log_one_minus_alphas_cumprod', + to_torch(np.log(1. - alphas_cumprod))) + self.register_buffer('sqrt_recip_alphas_cumprod', + to_torch(np.sqrt(1. / alphas_cumprod))) + self.register_buffer('sqrt_recipm1_alphas_cumprod', + to_torch(np.sqrt(1. / alphas_cumprod - 1))) + + # calculations for posterior q(x_{t-1} | x_t, x_0) + posterior_variance = betas * \ + (1. - alphas_cumprod_prev) / (1. - alphas_cumprod) + # above: equal to 1. / (1. / (1. - alpha_cumprod_tm1) + alpha_t / beta_t) + self.register_buffer('posterior_variance', + to_torch(posterior_variance)) + # below: log calculation clipped because the posterior variance is 0 at the beginning of the diffusion chain + self.register_buffer('posterior_log_variance_clipped', to_torch( + np.log(np.maximum(posterior_variance, 1e-20)))) + self.register_buffer('posterior_mean_coef1', to_torch( + betas * np.sqrt(alphas_cumprod_prev) / (1. - alphas_cumprod))) + self.register_buffer('posterior_mean_coef2', to_torch( + (1. - alphas_cumprod_prev) * np.sqrt(alphas) / (1. - alphas_cumprod))) + + def predict_start_from_noise(self, x_t, t, noise): + return self.sqrt_recip_alphas_cumprod[t] * x_t - \ + self.sqrt_recipm1_alphas_cumprod[t] * noise + + def q_posterior(self, x_start, x_t, t): + posterior_mean = self.posterior_mean_coef1[t] * \ + x_start + self.posterior_mean_coef2[t] * x_t + posterior_log_variance_clipped = self.posterior_log_variance_clipped[t] + return posterior_mean, posterior_log_variance_clipped + + def p_mean_variance(self, x, t, clip_denoised: bool, condition_x=None): + batch_size = x.shape[0] + noise_level = torch.FloatTensor( + [self.sqrt_alphas_cumprod_prev[t + 1]]).repeat(batch_size, 1).to(x.device) + if condition_x is not None: + x_temp = torch.cat([condition_x, x], dim=1) + noise = self.denoise_fn(x_temp, noise_level) + x_recon = self.predict_start_from_noise(x, t=t, noise=noise) + else: + x_recon = self.predict_start_from_noise( + x, t=t, noise=self.denoise_fn(x, noise_level)) + + if clip_denoised: + x_recon.clamp_(self.min_num, self.max_num) + + model_mean, posterior_log_variance = self.q_posterior( + x_start=x_recon, x_t=x, t=t) + return model_mean, posterior_log_variance + + @torch.no_grad() + def p_sample(self, x, t, clip_denoised=True, condition_x=None): + model_mean, model_log_variance = self.p_mean_variance( + x=x, t=t, clip_denoised=clip_denoised, condition_x=condition_x) + + noise = torch.randn_like(x) if t > 0 else torch.zeros_like(x) + return model_mean + noise * (0.5 * model_log_variance).exp() + + @torch.no_grad() + def p_sample_loop(self, x_in,client_socket, continous=False): + device = self.betas.device + q = 0 + + sample_inter = (1 | (self.num_timesteps // 10)) + if not self.conditional: + shape = x_in + # print(shape)#kk + img = torch.randn(shape, device=device) + ret_img = img + for i in tqdm(reversed(range(0, self.num_timesteps)), desc='sampling loop time step', + total=self.num_timesteps): + img = self.p_sample(img, i, clip_denoised=True) + if i % sample_inter == 0: + ret_img = torch.cat([ret_img, img], dim=0) + else: + x = x_in + shape = x.shape + # print(shape)#kk [1,1,2048,32] + img = torch.randn(shape, device=device) + ret_img = x + + for i in tqdm(reversed(range(0, self.num_timesteps)), desc='sampling loop time step', + total=self.num_timesteps): + img = self.p_sample(img, i, condition_x=x, clip_denoised=True) + if i % sample_inter == 0: + ret_img = torch.cat([ret_img, img], dim=0) + bytes_to_send = i.to_bytes(4, byteorder='big') + self.send_tensor(img, client_socket) + self.send_tensor(x, client_socket) + # print(ret_img.shape)#kk [11,1,2048,32] + # print(ret_img[-1].shape)#kk [1,2048,32] + if continous: + return ret_img + else: + return ret_img[-1] + + def send_tensor(self,tensor, socket): + buffer = io.BytesIO() + torch.save(tensor, buffer) + buffer.seek(0) + data = buffer.read() + # 首先发送数据长度 + socket.sendall(len(data).to_bytes(4, byteorder='big')) + # 然后发送数据 + socket.sendall(data) + + + @torch.no_grad() + def sample(self, batch_size=1, continous=False): + time_size = self.time_size + channels = self.channels + return self.p_sample_loop((batch_size, channels, time_size, time_size), continous) + + @torch.no_grad() + def super_resolution(self, x_in,client_socket, min_num, max_num, continous=False): + self.min_num = min_num + self.max_num = max_num + return self.p_sample_loop(x_in,client_socket, continous) + + def q_sample(self, x_start, continuous_sqrt_alpha_cumprod, noise=None): + noise = default(noise, lambda: torch.randn_like(x_start)) + + # random gama + return ( + continuous_sqrt_alpha_cumprod * x_start + + (1 - continuous_sqrt_alpha_cumprod ** 2).sqrt() * noise + ) + + def p_losses(self, x_in, noise=None): + x_start = x_in['HR'] + [b, c, h, w] = x_start.shape + t = np.random.randint(1, self.num_timesteps + 1) + + continuous_sqrt_alpha_cumprod = torch.FloatTensor( + np.random.uniform( + self.sqrt_alphas_cumprod_prev[t - 1], + self.sqrt_alphas_cumprod_prev[t], + size=b + ) + ).to(x_start.device) + + continuous_sqrt_alpha_cumprod = continuous_sqrt_alpha_cumprod.view(b, -1) + + noise = default(noise, lambda: torch.randn_like(x_start)) + + x_noisy = self.q_sample( + x_start=x_start, continuous_sqrt_alpha_cumprod=continuous_sqrt_alpha_cumprod.view(-1, 1, 1, 1), noise=noise) + + if not self.conditional: + x_recon = self.denoise_fn(x_noisy, continuous_sqrt_alpha_cumprod) + else: + x_cat = torch.cat([x_in['SR'], x_noisy], dim=1) + x_recon = self.denoise_fn(x_cat, continuous_sqrt_alpha_cumprod) + + loss = self.loss_func(noise, x_recon) + return loss + + def forward(self, x, *args, **kwargs): + return self.p_losses(x, *args, **kwargs) diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/unet.py b/subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/unet.py new file mode 100644 index 0000000..77159a7 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/model/sr3_modules/unet.py @@ -0,0 +1,274 @@ +import math +from inspect import isfunction + +import torch +from torch import nn + + +def exists(x): + return x is not None + + +def default(val, d): + if exists(val): + return val + return d() if isfunction(d) else d + + +class PositionalEncoding(nn.Module): + def __init__(self, dim): + super().__init__() + self.dim = dim + + def forward(self, noise_level): + count = self.dim // 2 + step = torch.arange(count, dtype=noise_level.dtype, + device=noise_level.device) / count + encoding = noise_level.unsqueeze( + 1) * torch.exp(-math.log(1e4) * step.unsqueeze(0)) + encoding = torch.cat( + [torch.sin(encoding), torch.cos(encoding)], dim=-1) + return encoding + + +class FeatureWiseAffine(nn.Module): + def __init__(self, in_channels, out_channels, use_affine_level=False): + super(FeatureWiseAffine, self).__init__() + self.use_affine_level = use_affine_level + self.noise_func = nn.Sequential( + nn.Linear(in_channels, out_channels * (1 + self.use_affine_level)) + ) + + def forward(self, x, noise_embed): + batch = x.shape[0] + if self.use_affine_level: + gamma, beta = self.noise_func(noise_embed).view( + batch, -1, 1, 1).chunk(3, dim=1) + x = (1 + gamma) * x + beta + else: + x = x + self.noise_func(noise_embed).view(batch, -1, 1, 1) + return x + + +class Swish(nn.Module): + def forward(self, x): + return x * torch.sigmoid(x) + + +class Upsample(nn.Module): + def __init__(self, dim): + super().__init__() + self.up = nn.Upsample(scale_factor=2, mode="nearest") + self.conv = nn.Conv2d(dim, dim, 3, padding=1) + + def forward(self, x): + return self.conv(self.up(x)) + + +class Downsample(nn.Module): + def __init__(self, dim): + super().__init__() + self.conv = nn.Conv2d(dim, dim, 3, 2, 1) + + def forward(self, x): + return self.conv(x) + + +# building block modules +class Block(nn.Module): + def __init__(self, dim, dim_out, groups=32, dropout=0): + super().__init__() + self.block = nn.Sequential( + nn.GroupNorm(groups, dim), + Swish(), + nn.Dropout(dropout) if dropout != 0 else nn.Identity(), + nn.Conv2d(dim, dim_out, 3, padding=1) + ) + + def forward(self, x): + return self.block(x) + + +class ResnetBlock(nn.Module): + def __init__(self, dim, dim_out, noise_level_emb_dim=None, dropout=0, use_affine_level=False, norm_groups=32): + super().__init__() + self.noise_func = FeatureWiseAffine( + noise_level_emb_dim, dim_out, use_affine_level) + + self.block1 = Block(dim, dim_out, groups=norm_groups) + self.block2 = Block(dim_out, dim_out, groups=norm_groups, dropout=dropout) + self.res_conv = nn.Conv2d( + dim, dim_out, 1) if dim != dim_out else nn.Identity() + + def forward(self, x, time_emb): + b, c, h, w = x.shape + h = self.block1(x) + h = self.noise_func(h, time_emb) + h = self.block2(h) + return h + self.res_conv(x) + + +class SelfAttention(nn.Module): + def __init__(self, in_channel, n_head=1, norm_groups=32): + super().__init__() + + self.n_head = n_head + + self.norm = nn.GroupNorm(norm_groups, in_channel) + self.qkv = nn.Conv2d(in_channel, in_channel * 3, 1, bias=False) + self.out = nn.Conv2d(in_channel, in_channel, 1) + + def forward(self, input): + batch, channel, height, width = input.shape + n_head = self.n_head + head_dim = channel // n_head + + norm = self.norm(input) + qkv = self.qkv(norm).view(batch, n_head, head_dim * 3, height, width) + query, key, value = qkv.chunk(3, dim=2) # bhdyx + + attn = torch.einsum( + "bnchw, bncyx -> bnhwyx", query, key + ).contiguous() / math.sqrt(channel) + attn = attn.view(batch, n_head, height, width, -1) + attn = torch.softmax(attn, -1) + attn = attn.view(batch, n_head, height, width, height, width) + + out = torch.einsum("bnhwyx, bncyx -> bnchw", attn, value).contiguous() + out = self.out(out.view(batch, channel, height, width)) + + return out + input + + +class ResnetBlocWithAttn(nn.Module): + def __init__(self, dim, dim_out, *, noise_level_emb_dim=None, norm_groups=32, dropout=0, with_attn=False): + super().__init__() + self.with_attn = with_attn + self.res_block = ResnetBlock( + dim, dim_out, noise_level_emb_dim, norm_groups=norm_groups, dropout=dropout) + if with_attn: + self.attn = SelfAttention(dim_out, norm_groups=norm_groups) + + def forward(self, x, time_emb): + x = self.res_block(x, time_emb) + if (self.with_attn): + x = self.attn(x) + return x + + +class UNet(nn.Module): + def __init__( + self, + in_channel=6, + out_channel=3, + inner_channel=32, + norm_groups=32, + channel_mults=(1, 2, 4, 8, 8), + attn_res=(8), + res_blocks=3, + dropout=0, + with_noise_level_emb=True, + time_size=128 + ): + super().__init__() + + if with_noise_level_emb: + noise_level_channel = inner_channel + self.noise_level_mlp = nn.Sequential( + PositionalEncoding(inner_channel), + nn.Linear(inner_channel, inner_channel * 4), + Swish(), + nn.Linear(inner_channel * 4, inner_channel) + ) + else: + noise_level_channel = None + self.noise_level_mlp = None + + num_mults = len(channel_mults) + pre_channel = inner_channel + feat_channels = [pre_channel] + now_res = time_size + downs = [nn.Conv2d(in_channel, inner_channel, + kernel_size=3, padding=1)] + + for ind in range(num_mults): + is_last = (ind == num_mults - 1) + use_attn = (now_res in attn_res) + channel_mult = inner_channel * channel_mults[ind] + + for _ in range(0, res_blocks): + downs.append(ResnetBlocWithAttn( + pre_channel, channel_mult, noise_level_emb_dim=noise_level_channel, norm_groups=norm_groups, + dropout=dropout, with_attn=use_attn)) + feat_channels.append(channel_mult) + pre_channel = channel_mult + if not is_last: + downs.append(Downsample(pre_channel)) + feat_channels.append(pre_channel) + now_res = now_res // 2 + self.downs = nn.ModuleList(downs) + + self.mid = nn.ModuleList([ + ResnetBlocWithAttn(pre_channel, pre_channel, noise_level_emb_dim=noise_level_channel, + norm_groups=norm_groups, + dropout=dropout, with_attn=True), + ResnetBlocWithAttn(pre_channel, pre_channel, noise_level_emb_dim=noise_level_channel, + norm_groups=norm_groups, + dropout=dropout, with_attn=False) + ]) + + ups = [] + for ind in reversed(range(num_mults)): + is_last = (ind < 1) + use_attn = (now_res in attn_res) + channel_mult = inner_channel * channel_mults[ind] + + for _ in range(0, res_blocks + 1): + ups.append(ResnetBlocWithAttn( + pre_channel + feat_channels.pop(), channel_mult, noise_level_emb_dim=noise_level_channel, + norm_groups=norm_groups, + dropout=dropout, with_attn=use_attn)) + pre_channel = channel_mult + if not is_last: + ups.append(Upsample(pre_channel)) + now_res = now_res * 2 + + self.ups = nn.ModuleList(ups) + self.final_conv = Block(pre_channel, default(out_channel, in_channel), groups=norm_groups) + + def forward(self, x, time): + t = self.noise_level_mlp(time) if exists( + self.noise_level_mlp) else None + + feats = [] + for layer in self.downs: + if isinstance(layer, ResnetBlocWithAttn): + x = layer(x, t) + else: + x = layer(x) + feats.append(x) + + for layer in self.mid: + if isinstance(layer, ResnetBlocWithAttn): + x = layer(x, t) + else: + x = layer(x) + + for layer in self.ups: + if isinstance(layer, ResnetBlocWithAttn): + pop_temp = feats.pop() + x_temp = torch.cat((x, pop_temp), dim=1) + x = layer(x_temp, t) + else: + x = layer(x) + + return self.final_conv(x) +#模型组件 +#PositionalEncoding: 位置编码器,用于编码噪声级别。 +#FeatureWiseAffine: 用于特征级别的仿射变换。 +#Swish: Swish 激活函数。 +#Upsample: 上采样模块。 +#Downsample: 下采样模块。 +#Block: 基本的卷积块。 +#ResnetBlock: ResNet 风格的残差块。 +#SelfAttention: 自注意力机制模块,用于提取图像特征中的重要信息。 \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/requirements.txt b/subject1-4/dynamicSplit/02DiffAD-main_low/requirements.txt new file mode 100644 index 0000000..918c9c0 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/requirements.txt @@ -0,0 +1,7 @@ +torch>=1.12 +torchvision +numpy~=1.23.2 +pandas~=1.5.1 +scikit-learn~=1.1.2 +tqdm~=4.64.1 +tensorboardx~=2.5.1 \ No newline at end of file diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/server2.py b/subject1-4/dynamicSplit/02DiffAD-main_low/server2.py new file mode 100644 index 0000000..cf89ab2 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/server2.py @@ -0,0 +1,38 @@ + + +import socket +import time + +def measure_bandwidth(connection): + start_time = time.time() + total_bytes = 0 + + while True: + data = connection.recv(1024) # 接收数据 + if not data: + break + total_bytes += len(data) + + end_time = time.time() + elapsed_time = end_time - start_time + bandwidth_mbps = (total_bytes * 8) / (elapsed_time * 1e6) # 计算带宽,单位为 Mbps + return bandwidth_mbps, elapsed_time + +def task(): + server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server_address = ('', 9999) # 空字符串表示监听所有可用的接口 + server_socket.bind(server_address) + server_socket.listen(1) + while True: + print("等待客户端连接...") + client_connection, client_address = server_socket.accept() + print(f"客户端 {client_address} 已连接") + + bandwidth_mbps, elapsed_time = measure_bandwidth(client_connection) + print(f"测量完成:实际可用带宽为 {bandwidth_mbps:.2f} Mbps,传输时间为 {elapsed_time:.2f} 秒") + + client_connection.close() + server_socket.close() + +if __name__ == "__main__": + task() diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/test_split.py b/subject1-4/dynamicSplit/02DiffAD-main_low/test_split.py new file mode 100644 index 0000000..ac406b3 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/test_split.py @@ -0,0 +1,164 @@ +import argparse +import logging +import os +import time + +import pandas as pd +import torch +from tensorboardX import SummaryWriter + +import core.logger as Logger +import core.metrics as Metrics +import data as Data +import model as Model +from decimal import Decimal +import sys + +import socket +import random +import string +import time + +def time_test(params, strategy_params, temp_list): + torch.backends.cudnn.enabled = True + torch.backends.cudnn.benchmark = True + opt = params['opt'] + logger = params['logger'] + logger_test = params['logger_test'] + model_epoch = params['model_epoch'] + + diffusion = Model.create_model(opt) + logger.info('Initial Model Finished') + + current_step = diffusion.begin_step + current_epoch = diffusion.begin_epoch + + if opt['path']['resume_state']: + logger.info('Resuming training from epoch: {}, iter: {}.'.format( + current_epoch, current_step)) + + diffusion.set_new_noise_schedule( + opt['model']['beta_schedule'][opt['phase']], schedule_phase=opt['phase']) + + logger.info('Begin Model Evaluation.') + idx = 0 + + all_datas = pd.DataFrame() + sr_datas = pd.DataFrame() + differ_datas = pd.DataFrame() + + result_path = '{}'.format(opt['path']['results']) + os.makedirs(result_path, exist_ok=True) + + print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))#news + + #todo 设置高性能云的 IP 地址和端口号 x.x.x.x 9999 + server_address = ('x.x.x.x', 9999) + client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #kk + client_socket.connect(server_address) #kk + + for _, test_data in enumerate(test_loader): + # print(test_data['ORI'].shape) + # print(test_data['HR'].shape) + # print(test_data['SR'].shape) + # print(test_data['label'].shape) + # sys.exit (0) + idx += 1 + diffusion.feed_data(test_data) + diffusion.test(client_socket,continous=False) + + + + visuals = diffusion.get_current_visuals() + + all_data, sr_df, differ_df = Metrics.tensor2allcsv(visuals, params['col_num']) + all_datas = Metrics.merge_all_csv(all_datas, all_data) + sr_datas = Metrics.merge_all_csv(sr_datas, sr_df) + differ_datas = Metrics.merge_all_csv(differ_datas, differ_df) + + client_socket.close() # kk + os.system("pause") # kk + + # print(idx) + # sys.exit (0) + print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))#new + all_datas = all_datas.reset_index(drop=True) + sr_datas = sr_datas.reset_index(drop=True) + differ_datas = differ_datas.reset_index(drop=True) + + for i in range(params['row_num'], all_datas.shape[0]): + all_datas.drop(index=[i], inplace=True) + sr_datas.drop(index=[i], inplace=True) + differ_datas.drop(index=[i], inplace=True) + + f1,accuracy,precision,recall = Metrics.relabeling_strategy(all_datas, strategy_params) + + temp_f1 = Decimal(f1).quantize(Decimal("0.0000")) + temp_acc = Decimal(accuracy).quantize(Decimal("0.0000")) + temp_prec = Decimal(precision).quantize(Decimal("0.0000")) + temp_rec = Decimal(recall).quantize(Decimal("0.0000")) + print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))#new + print('F1-score: ', float(temp_f1)) + print('precision: ', float(temp_prec)) + print('accuracy: ', float(temp_acc)) + print('recall: ', float(temp_rec)) + + +# evaluate model performance +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('-c', '--config', type=str, default='./config/smd_time_test.json', + help='JSON file for configuration') + #//02DiffAD-main/config/smd_time_test.json + parser.add_argument('-p', '--phase', type=str, choices=['train ', 'val', 'test'], + help='Run either train(training) or val(generation)', default='test') + parser.add_argument('-gpu', '--gpu_ids', type=str, default=None) + parser.add_argument('-debug', '-d', action='store_true') + parser.add_argument('-enable_wandb', action='store_true') + parser.add_argument('-log_wandb_ckpt', action='store_true') + parser.add_argument('-log_eval', action='store_true') + + temp_list = [] + model_epoch = 100 + + # parse configs + args = parser.parse_args() + opt = Logger.parse(args, model_epoch) + # Convert to NoneDict, which return None for missing key. + opt = Logger.dict_to_nonedict(opt) + logger_name = 'test' + str(model_epoch) + # logging + Logger.setup_logger(logger_name, opt['path']['log'], 'test', level=logging.INFO) + logger = logging.getLogger('base') + logger.info(Logger.dict2str(opt)) + tb_logger = SummaryWriter(log_dir=opt['path']['tb_logger']) + + #开始测试 + test_set = Data.create_dataset(opt['datasets']['test'], 'test') + + test_loader = Data.create_dataloader(test_set, opt['datasets']['test'], 'test') + logger.info('Initial Dataset Finished') + logger_test = logging.getLogger(logger_name) # test logger + + start_label = opt['model']['beta_schedule']['test']['start_label'] + end_label = opt['model']['beta_schedule']['test']['end_label'] + step_label = opt['model']['beta_schedule']['test']['step_label'] + step_t = opt['model']['beta_schedule']['test']['step_t'] + strategy_params = { + 'start_label': start_label, + 'end_label': end_label, + 'step_label': step_label, + 'step_t': step_t + } + + params = { + 'opt': opt, + 'logger': logger, + 'logger_test': logger_test, + 'model_epoch': model_epoch, + 'row_num': test_set.row_num, + 'col_num': test_set.col_num + } + + time_test(params, strategy_params, temp_list) + logging.shutdown() diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/time_test.py b/subject1-4/dynamicSplit/02DiffAD-main_low/time_test.py new file mode 100644 index 0000000..c4f9053 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/time_test.py @@ -0,0 +1,133 @@ +import argparse +import logging +import os +import time + +import pandas as pd +import torch +from tensorboardX import SummaryWriter + +import core.logger as Logger +import core.metrics as Metrics +import data as Data +import model as Model +from decimal import Decimal + + +def time_test(params, strategy_params, temp_list): + torch.backends.cudnn.enabled = True + torch.backends.cudnn.benchmark = True + opt = params['opt'] + logger = params['logger'] + logger_test = params['logger_test'] + model_epoch = params['model_epoch'] + + diffusion = Model.create_model(opt) + logger.info('Initial Model Finished') + + current_step = diffusion.begin_step + current_epoch = diffusion.begin_epoch + + if opt['path']['resume_state']: + logger.info('Resuming training from epoch: {}, iter: {}.'.format( + current_epoch, current_step)) + + diffusion.set_new_noise_schedule( + opt['model']['beta_schedule'][opt['phase']], schedule_phase=opt['phase']) + + logger.info('Begin Model Evaluation.') + idx = 0 + + all_datas = pd.DataFrame() + sr_datas = pd.DataFrame() + differ_datas = pd.DataFrame() + + result_path = '{}'.format(opt['path']['results']) + os.makedirs(result_path, exist_ok=True) + + print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))#news + for _, test_data in enumerate(test_loader): + idx += 1 + diffusion.feed_data(test_data) + diffusion.test(continous=False) + visuals = diffusion.get_current_visuals() + + all_data, sr_df, differ_df = Metrics.tensor2allcsv(visuals, params['col_num']) + all_datas = Metrics.merge_all_csv(all_datas, all_data) + sr_datas = Metrics.merge_all_csv(sr_datas, sr_df) + differ_datas = Metrics.merge_all_csv(differ_datas, differ_df) + + print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))#news + all_datas = all_datas.reset_index(drop=True) + sr_datas = sr_datas.reset_index(drop=True) + differ_datas = differ_datas.reset_index(drop=True) + + for i in range(params['row_num'], all_datas.shape[0]): + all_datas.drop(index=[i], inplace=True) + sr_datas.drop(index=[i], inplace=True) + differ_datas.drop(index=[i], inplace=True) + + f1 = Metrics.relabeling_strategy(all_datas, strategy_params) + temp_f1 = Decimal(f1) + # temp_f1 = Decimal(f1).quantize(Decimal("0.0000")) + print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))#new + print('F1-score: ', float(temp_f1)) + + +# evaluate model performance +if __name__ == '__main__': + print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))#news + parser = argparse.ArgumentParser() + parser.add_argument('-c', '--config', type=str, default='//02DiffAD-main/config/msl_time_test.json', + help='JSON file for configuration') + parser.add_argument('-p', '--phase', type=str, choices=['train ', 'val', 'test'], + help='Run either train(training) or val(generation)', default='test') + parser.add_argument('-gpu', '--gpu_ids', type=str, default=None) + parser.add_argument('-debug', '-d', action='store_true') + parser.add_argument('-enable_wandb', action='store_true') + parser.add_argument('-log_wandb_ckpt', action='store_true') + parser.add_argument('-log_eval', action='store_true') + + temp_list = [] + model_epoch = 100 + + # parse configs + args = parser.parse_args() + opt = Logger.parse(args, model_epoch) + # Convert to NoneDict, which return None for missing key. + opt = Logger.dict_to_nonedict(opt) + logger_name = 'test' + str(model_epoch) + # logging + Logger.setup_logger(logger_name, opt['path']['log'], 'test', level=logging.INFO) + logger = logging.getLogger('base') + logger.info(Logger.dict2str(opt)) + tb_logger = SummaryWriter(log_dir=opt['path']['tb_logger']) + + test_set = Data.create_dataset(opt['datasets']['test'], 'test') + + test_loader = Data.create_dataloader(test_set, opt['datasets']['test'], 'test') + logger.info('Initial Dataset Finished') + logger_test = logging.getLogger(logger_name) # test logger + + start_label = opt['model']['beta_schedule']['test']['start_label'] + end_label = opt['model']['beta_schedule']['test']['end_label'] + step_label = opt['model']['beta_schedule']['test']['step_label'] + step_t = opt['model']['beta_schedule']['test']['step_t'] + strategy_params = { + 'start_label': start_label, + 'end_label': end_label, + 'step_label': step_label, + 'step_t': step_t + } + + params = { + 'opt': opt, + 'logger': logger, + 'logger_test': logger_test, + 'model_epoch': model_epoch, + 'row_num': test_set.row_num, + 'col_num': test_set.col_num + } + + time_test(params, strategy_params, temp_list) + logging.shutdown() diff --git a/subject1-4/dynamicSplit/02DiffAD-main_low/time_train.py b/subject1-4/dynamicSplit/02DiffAD-main_low/time_train.py new file mode 100644 index 0000000..a1f87e3 --- /dev/null +++ b/subject1-4/dynamicSplit/02DiffAD-main_low/time_train.py @@ -0,0 +1,87 @@ +import argparse +import logging +import math + +import torch +from tensorboardX import SummaryWriter + +import core.logger as Logger +import data as Data +import model as Model + +# train model +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('-c', '--config', type=str, default='//02DiffAD-main/config/smd_time_train.json', + help='JSON file for configuration') + parser.add_argument('-p', '--phase', type=str, choices=['train', 'val'], + help='Run either train(training) or val(generation)', default='train') + parser.add_argument('-gpu', '--gpu_ids', type=str, default=None) + parser.add_argument('-debug', '-d', action='store_true') + parser.add_argument('-enable_wandb', action='store_true') + parser.add_argument('-log_wandb_ckpt', action='store_true') + parser.add_argument('-log_eval', action='store_true') + + # parse configs + args = parser.parse_args() + opt = Logger.parse(args) + # Convert to NoneDict, which return None for missing key. + opt = Logger.dict_to_nonedict(opt) + + # logging + torch.backends.cudnn.enabled = True + torch.backends.cudnn.benchmark = True + + Logger.setup_logger(None, opt['path']['log'], + 'train', level=logging.INFO, screen=True) + Logger.setup_logger('val', opt['path']['log'], 'val', level=logging.INFO) + logger = logging.getLogger('base') + logger.info(Logger.dict2str(opt)) + tb_logger = SummaryWriter(log_dir=opt['path']['tb_logger']) + + for phase, dataset_opt in opt['datasets'].items(): + if phase == 'train' and args.phase != 'val': + train_set = Data.create_dataset(dataset_opt, phase) + train_loader = Data.create_dataloader(train_set, dataset_opt, phase) + + logger.info('Initial Dataset Finished') + + diffusion = Model.create_model(opt) + logger.info('Initial Model Finished') + + current_step = diffusion.begin_step + current_epoch = diffusion.begin_epoch + n_epoch = opt['train']['n_epoch'] + + if opt['path']['resume_state']: + logger.info('Resuming training from epoch: {}, iter: {}.'.format( + current_epoch, current_step)) + + diffusion.set_new_noise_schedule( + opt['model']['beta_schedule'][opt['phase']], schedule_phase=opt['phase']) + + save_model_iter = math.ceil(train_set.__len__() / opt['datasets']['train']['batch_size']) + while current_epoch < n_epoch: + current_epoch += 1 + for _, train_data in enumerate(train_loader): + current_step += 1 + if current_epoch > n_epoch: + break + diffusion.feed_data(train_data) + diffusion.optimize_parameters() + # log + if current_epoch % opt['train']['print_freq'] == 0 and current_step % save_model_iter == 0: + logs = diffusion.get_current_log() + message = ' '.format( + current_epoch, current_step) + for k, v in logs.items(): + message += '{:s}: {:.4e} '.format(k, v) + tb_logger.add_scalar(k, v, current_step) + logger.info(message) + + # save model + if current_epoch % opt['train']['save_checkpoint_freq'] == 0 and current_step % save_model_iter == 0: + logger.info('Saving models and training states.') + diffusion.save_network(current_epoch, current_step) + + logger.info('End of training.') diff --git a/subject1-4/dynamicSplit/README.md b/subject1-4/dynamicSplit/README.md new file mode 100644 index 0000000..28b2fe5 --- /dev/null +++ b/subject1-4/dynamicSplit/README.md @@ -0,0 +1,69 @@ +# DynamicSplit + + +## Datasets + +1. MSL (Mars Science Laboratory rover) is a public dataset from NASA. You can learn about it + from [Detecting Spacecraft Anomalies Using LSTMs and Nonparametric Dynamic Thresholding](https://arxiv.org/pdf/1802.04431.pdf). +2. SMAP (Soil Moisture Active Passive satellite) also is a public dataset from NASA. You can learn about it + from [Detecting Spacecraft Anomalies Using LSTMs and Nonparametric Dynamic Thresholding](https://arxiv.org/pdf/1802.04431.pdf). +3. SMD (Server Machine Dataset) is a 5-week-long dataset collected from a large Internet company. You can learn about it + from [Robust Anomaly Detection for Multivariate Time Series through Stochastic Recurrent Neural Network ](https://netman.aiops.org/wp-content/uploads/2019/08/OmniAnomaly_camera-ready.pdf). +Please download the dataset mentioned above and place it in the` tf_dataset` folder, e.g., `tf_dataset/msl/msl_test.csv`. + +## DiffAD-Usage + +This DiffAD model was proposed in this original paper, *Imputation-based Time-Series Anomaly Detection with Conditional Weight-Incremental Diffusion Models*. +### Environment + +Install Python 3.8. + +```python +pip install -r requirements.txt +``` + +By default, datasets are placed under the "tf_dataset" folder. If you need to change +the dataset, you can modify the dataset path in the json file in the "config" folder. +Here is an example of modifying the training dataset path: + +```json +"datasets": { + "train|test": { + "dataroot": "tf_dataset/smap/smap_train.csv", + //"dataroot": "tf_dataset/swat/swat_train.csv" + } +}, +``` +In addition, we provide json configuration files for SMAP datasets for reference. + +### Training +Next, we demonstrate using the SMAP dataset. + +#### We use dataset SMAP for training demonstration. + +```python +# Use time_train.py to train the task. +# Edit json files to adjust dataset path, network structure and hyperparameters. +python time_train.py -c config/smap_time_train.json +``` + +### Test +The trained model is placed in "experiments/*/checkpoint/" by default. +If you need to modify this path, you can refer to "config/smap_time_test.json": + +```json +"path": { + "resume_state": "experiments/SMAP_TRAIN_128_2048_100/checkpoint/E100" +}, +``` + +#### We also use dataset SMAP for testing demonstration. + +```python +# Edit json to adjust pretrain model path and dataset_path. +python time_test.py -c config/smap_time_test.json +``` + + +## DynamicSplit-Usage +The `DiffAD-main_low`and `DiffAD-main_high` files should be placed on the low-performing cloud and high-performing cloud, respectively. `test_split.py` shows an example of computational splitting. \ No newline at end of file -- Gitee