commit 884db9b9265fac690cbedc95b8a3c67d068b1d42 Author: newbie Date: Mon Oct 7 09:54:32 2024 +0800 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2bb627b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +Static +Result \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..14b7790 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python Debugger: Current File", + "type": "debugpy", + "request": "launch", + "program": "main.py", + "console": "integratedTerminal" + } + ] +} \ No newline at end of file diff --git a/Qfunctions/__init__.py b/Qfunctions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Qfunctions/__pycache__/Qtorch.cpython-312.pyc b/Qfunctions/__pycache__/Qtorch.cpython-312.pyc new file mode 100644 index 0000000..38e4bbb Binary files /dev/null and b/Qfunctions/__pycache__/Qtorch.cpython-312.pyc differ diff --git a/Qfunctions/__pycache__/__init__.cpython-312.pyc b/Qfunctions/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..a0cc2b2 Binary files /dev/null and b/Qfunctions/__pycache__/__init__.cpython-312.pyc differ diff --git a/Qfunctions/__pycache__/divSet.cpython-312.pyc b/Qfunctions/__pycache__/divSet.cpython-312.pyc new file mode 100644 index 0000000..17896c9 Binary files /dev/null and b/Qfunctions/__pycache__/divSet.cpython-312.pyc differ diff --git a/Qfunctions/__pycache__/loaData.cpython-312.pyc b/Qfunctions/__pycache__/loaData.cpython-312.pyc new file mode 100644 index 0000000..7439bfb Binary files /dev/null and b/Qfunctions/__pycache__/loaData.cpython-312.pyc differ diff --git a/Qfunctions/__pycache__/saveToxlsx.cpython-312.pyc b/Qfunctions/__pycache__/saveToxlsx.cpython-312.pyc new file mode 100644 index 0000000..56d5d26 Binary files /dev/null and b/Qfunctions/__pycache__/saveToxlsx.cpython-312.pyc differ diff --git a/Qfunctions/__pycache__/test.cpython-312.pyc b/Qfunctions/__pycache__/test.cpython-312.pyc new file mode 100644 index 0000000..8eab54c Binary files /dev/null and b/Qfunctions/__pycache__/test.cpython-312.pyc differ diff --git a/Qfunctions/divSet.py b/Qfunctions/divSet.py new file mode 100644 index 0000000..8e09c2e --- /dev/null +++ b/Qfunctions/divSet.py @@ -0,0 +1,28 @@ +from sklearn.model_selection import train_test_split +from sklearn.preprocessing import StandardScaler, LabelEncoder + +def divSet(data, labels = None, test_size=0.2, random_state=None): + + encoder = LabelEncoder() + + # 最后一列是标签 + X = data.iloc[:, :-1] + y = data.iloc[:, -1] + + if labels: + labels = encoder.fit_transform(labels) + else: + encoder.fit(y) + + # 分割数据集为训练集和测试集 + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=random_state) + # 标准化特征 + scaler = StandardScaler() + X_train = scaler.fit_transform(X_train) + X_test = scaler.transform(X_test) + + # 编码标签 + y_train = encoder.transform(y_train.values.reshape(-1, 1)) + y_test = encoder.transform(y_test.values.reshape(-1, 1)) + + return X_train, X_test, y_train, y_test, encoder diff --git a/Qfunctions/loaData.py b/Qfunctions/loaData.py new file mode 100644 index 0000000..5d7272e --- /dev/null +++ b/Qfunctions/loaData.py @@ -0,0 +1,97 @@ +import os +import pandas as pd + +STATIC_PATH = './Static' + +# 从文件夹中读取所有xlsx文件,每个文件对应一个label +# labelNames为label的名字,如果不提供则默认为文件名 +def load_data(folder, labelNames, isDir): + # 检查folder参数 + if folder is None: + raise ValueError("The 'folder' parameter is required.") + + # 检查labelNames参数 + if labelNames is None: + raise ValueError("The 'labelNames' parameter is required if 'folder' does not contain labels.") + + folder = os.path.join(STATIC_PATH, folder) + + # 看看有没有元数据文件夹 + if not os.path.isdir(folder): + raise ValueError(f"The folder '{folder}' does not exist.") + +# fileNames = [f for f in os.listdir(folder) if f.endswith('.xlsx')] + +# # 获取数据的最大行数 +# max_row_length = get_max_row_len(folder, fileNames) + +# all_features = [] + +# for i, fileName in enumerate(fileNames): + +# features = load_xlsx(folder + '/' + fileName, labelNames[i], max_row_length, 'zero') +# all_features.append(features) + +# data = pd.concat(all_features, ignore_index = True) + + data = None + if not isDir: + data = load_from_file(folder=folder, labelNames=labelNames) + else: + data = load_from_folder(folder=folder, labelNames=labelNames) + print(data) + return data + +def load_from_folder(folder, labelNames): + pass + +def load_from_file(folder, labelNames): + fileNames = [labelName + ".xlsx" for labelName in labelNames] + # 获取数据的最大行数 + max_row_length = get_max_row_len(folder, fileNames) + all_features = [] + for i, fileName in enumerate(fileNames): + features = load_xlsx(folder + '/' + fileName, labelNames[i], max_row_length, 'zero') + all_features.append(features) + return pd.concat(all_features, ignore_index = True) + + +def load_xlsx(fileName, labelName, max_row_length = 1000, fill_rule = None): + df = pd.read_excel(fileName) + + # 提取偶数列 + features = df.iloc[0:, 1::2] + features.dropna(inplace=True) + features.reset_index(drop=True, inplace=True) + + features = features.T + + # 补全每一行到指定长度 + features = features.apply(lambda row: fill_to_len(row, max_row_length, fill_rule), axis=1) + + features['label'] = labelName + features.columns = [f'feature{i+1}' for i in range(max_row_length)] + ['label'] + + return features + +def fill_to_len(row, length = 1000, rule = None): + fill_value = 0 + + if rule == 'min': + fill_value = row.min() + elif rule == 'mean': + fill_value = row.mean() + elif rule == 'zero': + fill_value = 0 + fill_values = pd.Series([fill_value] * (length - len(row))) + + return pd.concat([row, fill_values], ignore_index=True) + +def get_max_row_len(folder, filenames): + max_len = 0 + for filename in filenames: + df = pd.read_excel(os.path.join(folder, filename)) + max_len = max(max_len, df.shape[0]) + return max_len + +__all__ = ['load_data'] diff --git a/Qfunctions/saveToxlsx.py b/Qfunctions/saveToxlsx.py new file mode 100644 index 0000000..9f8e5b4 --- /dev/null +++ b/Qfunctions/saveToxlsx.py @@ -0,0 +1,13 @@ +import os + +def save_to_xlsx(project_name, file_name, data): + os.makedirs(f'Result/{project_name}', exist_ok=True) + data.to_excel(f'Result/{project_name}/{file_name}.xlsx', index=True) + print("Save successed to " + f'Result/{project_name}/{file_name}.xlsx') + + + # for filename,data in save_maps.items(): + # data.to_excel(f'Result/{project_name}/{filename}.xlsx', index=True) + # print("Save successed to " + f'Result/{project_name}/{filename}.xlsx') + # print('Save to xlsx done!') + return diff --git a/Qfunctions/test.py b/Qfunctions/test.py new file mode 100644 index 0000000..d4c26dd --- /dev/null +++ b/Qfunctions/test.py @@ -0,0 +1,17 @@ +import time +from sklearn.neural_network import MLPClassifier +from sklearn.metrics import classification_report, accuracy_score + +def MLP(X_train, X_test, y_train, y_test): + start_time = time.time() + # 训练 MLP 分类器 + mlp = MLPClassifier(hidden_layer_sizes=(100,), max_iter=300, random_state=42) + mlp.fit(X_train, y_train) + y_pred = mlp.predict(X_test) + end_time = time.time() + # 打印训练时间 + print("Training Time:", end_time - start_time, "seconds") + # 评估模型 + print("Accuracy:", accuracy_score(y_test, y_pred)) + print("Classification Report:") + print(classification_report(y_test, y_pred)) \ No newline at end of file diff --git a/Qtorch/Models/QSVM.py b/Qtorch/Models/QSVM.py new file mode 100644 index 0000000..b0c5b35 --- /dev/null +++ b/Qtorch/Models/QSVM.py @@ -0,0 +1,14 @@ +from Qtorch.Models.Qnn import Qnn +from abc import ABC, abstractmethod + +class QSVM(Qnn, ABC): + def __init__(self, data, labels=None, test_size=0.2, random_state=None): + super().__init__(data, labels, test_size, random_state) + self.result.update({ + "pca_2d" : None, + "pca_3d" : None + }) + + @abstractmethod + def train_model(self, train_loader, test_loader, epochs): + return super().train_model(train_loader, test_loader, epochs) diff --git a/Qtorch/Models/QSVM_BRF.py b/Qtorch/Models/QSVM_BRF.py new file mode 100644 index 0000000..9e42baf --- /dev/null +++ b/Qtorch/Models/QSVM_BRF.py @@ -0,0 +1,74 @@ +import torch +import torch.nn as nn +import torch.optim as optim + +from Qtorch.Models.QSVM import QSVM as svm + +class QSVM_BRF(svm): + def __init__(self, data, labels=None, test_size=0.2, random_state=None, + gamma=1.0, C=100, batch_size = 64, learning_rate=0.01): + super().__init__(data, labels, test_size, random_state) + self.gamma, self.C, self.n_features = gamma, C, data.shape[0] - 1 + self.support_vectors = torch.cat([batch[0] for batch in self.train_loader]) + self.alpha = nn.Parameter(torch.zeros(self.support_vectors.shape[0])) + self.b = nn.Parameter(torch.zeros(1)) + self.batch_size = batch_size + self.learning_rate = learning_rate + self.optimizer = optim.SGD(self.parameters(), lr=self.learning_rate) + + def rbf_kernel(self, X, Y): + X_norm = (X**2).sum(1).view(-1, 1) + Y_norm = (Y**2).sum(1).view(1, -1) + dist = X_norm + Y_norm - 2.0 * torch.mm(X, Y.t()) + return torch.exp(-self.gamma * dist) + + def forward(self, X): + K = self.rbf_kernel(X, self.support_vectors) + return torch.mm(K, self.alpha.unsqueeze(1)).squeeze() + self.b + + def hinge_loss(self, outputs, targets): + return torch.mean(torch.clamp(1 - outputs * targets, min=0)) + + def regularization(self): + return 0.5 * (self.alpha ** 2).sum() + + def train_model(self, epoch_times=100, learning_rate=0.01): + + losses, train_accs, test_accs = [], [], [] + + for epoch in range(epoch_times): + self.train() + epoch_loss, correct_train, total_train = 0, 0, 0 + + for batch_X, batch_y in self.train_loader: + + self.optimizer.zero_grad() + outputs = self(batch_X) + loss = self.hinge_loss(outputs, batch_y) + self.C * self.regularization() + loss.backward() + self.optimizer.step() + + epoch_loss += loss.item() + predicted = torch.sign(outputs) + correct_train += (predicted == batch_y).sum().item() + total_train += batch_y.size(0) + + train_acc = correct_train / total_train + test_acc = self.evaluate() + + losses.append(epoch_loss / len(self.train_loader)) + train_accs.append(train_acc) + test_accs.append(test_acc) + print(f'Epoch [{epoch+1}/{epoch_times}], Loss: {losses[-1]:.4f}, Train Acc: {train_acc:.4f}, Test Acc: {test_acc:.4f}') + + def evaluate(self): + self.eval() + correct = 0 + total = 0 + with torch.no_grad(): + for batch_X, batch_y in self.test_loader: + outputs = self(batch_X) + predicted = torch.sign(outputs) + correct += (predicted == batch_y).sum().item() + total += batch_y.size(0) + return correct / total diff --git a/Qtorch/Models/Qmlp.py b/Qtorch/Models/Qmlp.py new file mode 100644 index 0000000..841bb90 --- /dev/null +++ b/Qtorch/Models/Qmlp.py @@ -0,0 +1,180 @@ +import torch +import torch.nn as nn +from torch.utils.data import DataLoader, TensorDataset +from sklearn.preprocessing import LabelEncoder +from sklearn.metrics import confusion_matrix +import pandas as pd + +LABEL_ENCODER = LabelEncoder() +DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + +class Qmlp(nn.Module): + + epoch_data = { + 'epoch': [], + 'train_loss': [], + 'train_accuracy': [], + 'test_accuracy': [] + } + + labels = None + + def __init__(self, X_train, y_train, X_test, y_test, + hidden_layers, + labels=None, + dropout_rate=0.3 + ): + super(Qmlp, self).__init__() + + self.X_train, self.y_train, self.X_test, self.y_test = X_train, y_train, X_test, y_test + + self.labels = labels + + input_size = X_train.shape[1] + # input_size = 5 + print(input_size) + num_classes = len(set(y_train)) + + self.layers = nn.ModuleList() + + # Input layer to first hidden layer + self.layers.append(nn.Linear(input_size, hidden_layers[0])) + self.layers.append(nn.BatchNorm1d(hidden_layers[0])) + self.layers.append(nn.ReLU()) + self.layers.append(nn.Dropout(dropout_rate)) + + # Create hidden layers + for i in range(1, len(hidden_layers)): + self.layers.append(nn.Linear(hidden_layers[i-1], hidden_layers[i])) + self.layers.append(nn.BatchNorm1d(hidden_layers[i])) + self.layers.append(nn.ReLU()) + self.layers.append(nn.Dropout(dropout_rate)) + + # Output layer + self.layers.append(nn.Linear(hidden_layers[-1], num_classes)) + self.__init_weights() + + def forward(self, x): + for layer in self.layers: + x = layer(x) + return x + + def __prepare_data(self): + + # Step 2: Prepare the data + X_train_tensor = torch.tensor(self.X_train, dtype=torch.float32) + self.y_train = LABEL_ENCODER.fit_transform(self.y_train) + y_train_tensor = torch.tensor(self.y_train, dtype=torch.long) + + X_test_tensor = torch.tensor(self.X_test, dtype=torch.float32) + self.y_test = LABEL_ENCODER.transform(self.y_test) + y_test_tensor = torch.tensor(self.y_test, dtype=torch.long) + + train_dataset = TensorDataset(X_train_tensor, y_train_tensor) + test_dataset = TensorDataset(X_test_tensor, y_test_tensor) + + train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True) + test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False) + + return train_loader, test_loader + + def __train_model(self, train_loader, test_loader, epochs_times=100): + + model = self.to(DEVICE) + + criterion = nn.CrossEntropyLoss() + optimizer = torch.optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-5) + scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=10) + best_test_accuracy = 0 + patience = 100 + counter = 0 + accuracy_threshold = 0.99 # 99% 的准确率阈值 + + for epoch in range(epochs_times): + + model.train() + running_loss = 0.0 + correct_train = 0 + total_train = 0 + + for inputs, labels in train_loader: + inputs, labels = inputs.to(DEVICE), labels.to(DEVICE) + + optimizer.zero_grad() + outputs = model(inputs) + loss = criterion(outputs, labels) + loss.backward() + optimizer.step() + + running_loss += loss.item() + _, predicted = torch.max(outputs.data, 1) + total_train += labels.size(0) + correct_train += (predicted == labels).sum().item() + train_accuracy = correct_train / total_train + train_loss = running_loss / len(train_loader) + + model.eval() + correct_test = 0 + total_test = 0 + all_labels = [] + all_predicted = [] + all_prob = [] + with torch.no_grad(): + for inputs, labels in test_loader: + inputs, labels = inputs.to(DEVICE), labels.to(DEVICE) + outputs = model(inputs) + prob = torch.nn.functional.softmax(outputs, dim=1) + _, predicted = torch.max(outputs.data, 1) + total_test += labels.size(0) + correct_test += (predicted == labels).sum().item() + all_labels.extend(labels.cpu().numpy()) + all_predicted.extend(predicted.cpu().numpy()) + all_prob.extend(prob.cpu().numpy()) + + test_accuracy = correct_test / total_test + print(f'Epoch [{epoch+1}/{epochs_times}], Loss: {train_loss:.4f}, Train Accuracy: {train_accuracy * 100:.2f}%, Test Accuracy: {test_accuracy*100:.2f}%') + + self.epoch_data['epoch'].append(epoch+1) + self.epoch_data['train_loss'].append(train_loss) + self.epoch_data['train_accuracy'].append(train_accuracy) + self.epoch_data['test_accuracy'].append(test_accuracy) + + scheduler.step(train_loss) + + if test_accuracy > best_test_accuracy: + best_test_accuracy = test_accuracy + counter = 0 + else: + counter += 1 + + if counter >= patience and best_test_accuracy >= accuracy_threshold: + print(f"Early stopping at epoch {epoch+1}") + break + + if self.labels: + # labels_encoded = LABEL_ENCODER.fit(self.labels) + self.cm = confusion_matrix(all_labels, all_predicted, normalize='true') + else: + self.cm = confusion_matrix(all_labels, all_predicted, normalize='true') + + + # self.cm = confusion_matrix(all_labels, all_predicted, normalize='true') + print(self.cm) + return + + def get_cm(self): + return pd.DataFrame(self.cm, columns=self.labels, index=self.labels) + + def get_epoch_data(self): + return pd.DataFrame(self.epoch_data) + + def fit(self, epoch_times = 100): + + train_loader, test_loader = self.__prepare_data() + self.__train_model(train_loader, test_loader, epochs_times=epoch_times) + return + def __init_weights(self): + for m in self.modules(): + if isinstance(m, nn.Linear): + nn.init.xavier_uniform_(m.weight) + nn.init.zeros_(m.bias) \ No newline at end of file diff --git a/Qtorch/Models/Qnn.py b/Qtorch/Models/Qnn.py new file mode 100644 index 0000000..b35b439 --- /dev/null +++ b/Qtorch/Models/Qnn.py @@ -0,0 +1,105 @@ +import torch +import torch.nn as nn +import pandas as pd +from abc import ABC, abstractmethod + +from sklearn.metrics import confusion_matrix as cm + +from torch.utils.data import DataLoader, TensorDataset +from Qfunctions.divSet import divSet as ds +from Qfunctions.saveToxlsx import save_to_xlsx as stx + + +class Qnn(nn.Module, ABC): + + def __init__(self, data, labels=None, test_size=0.2, random_state=None): + super(Qnn, self).__init__() + + self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + + # 保存原始labe, 混淆矩阵使用 + self.original_labels = labels + + # 划分训练集和测试集 + X_train, X_test, y_train, y_test, self.labels = ds( + data=data, + labels=labels, + test_size=test_size, + random_state=random_state + ) + + self.train_loader, self.test_loader = self.__prepare_data( + X_train=X_train, + y_train=y_train, + X_test=X_test, + y_test=y_test + ) + + # 定义结果 + self.result = { + 'acc_and_loss' : { + 'epoch' : [], + 'loss': [], + 'train_accuracy': [], + 'test_accuracy': [], + }, + 'confusion_matrix': None, + } + + def accuracy(self, output, target): + pass + + # 定义损失函数 + def hinge_loss(self, output, target): + pass + + @abstractmethod + def train_model(self, train_loader, test_loader, epochs): + pass + + def confusion_matrix(self, test_outputs): + predicted = torch.argmax(test_outputs, dim=1) + true_label = torch.argmax(self.y_test, dim=1) + return cm(predicted.cpu(), true_label.cpu()) + + def fit(self, epochs = 100): + self.train_model(epochs) + + def save(self, project_name): + for filename, data in self.result.items(): + if filename == 'confusion_matrix': + data = pd.DataFrame(data, columns=self.original_labels, index=self.original_labels) + stx(project_name, filename, data) + else: + data = pd.DataFrame(data) + stx(project_name, filename, data) + + def __prepare_data(self, X_train, y_train, X_test, y_test): + + X_train_tensor = torch.tensor(X_train, dtype=torch.float32) + y_train_tensor = torch.tensor(y_train, dtype=torch.long) + + X_test_tensor = torch.tensor(X_test, dtype=torch.float32) + y_test_tensor = torch.tensor(y_test, dtype=torch.long) + + train_dataset = TensorDataset(X_train_tensor, y_train_tensor) + test_dataset = TensorDataset(X_test_tensor, y_test_tensor) + + train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True) + test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False) + + print(train_loader, test_loader) + + return train_loader, test_loader + + + + + + + + + + + + diff --git a/Qtorch/Models/__init__.py b/Qtorch/Models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Qtorch/Models/__pycache__/QSVM.cpython-312.pyc b/Qtorch/Models/__pycache__/QSVM.cpython-312.pyc new file mode 100644 index 0000000..bd426d9 Binary files /dev/null and b/Qtorch/Models/__pycache__/QSVM.cpython-312.pyc differ diff --git a/Qtorch/Models/__pycache__/QSVM_BRF.cpython-312.pyc b/Qtorch/Models/__pycache__/QSVM_BRF.cpython-312.pyc new file mode 100644 index 0000000..d5ebbd3 Binary files /dev/null and b/Qtorch/Models/__pycache__/QSVM_BRF.cpython-312.pyc differ diff --git a/Qtorch/Models/__pycache__/Qmlp.cpython-310.pyc b/Qtorch/Models/__pycache__/Qmlp.cpython-310.pyc new file mode 100644 index 0000000..12a7552 Binary files /dev/null and b/Qtorch/Models/__pycache__/Qmlp.cpython-310.pyc differ diff --git a/Qtorch/Models/__pycache__/Qmlp.cpython-312.pyc b/Qtorch/Models/__pycache__/Qmlp.cpython-312.pyc new file mode 100644 index 0000000..5d11c6f Binary files /dev/null and b/Qtorch/Models/__pycache__/Qmlp.cpython-312.pyc differ diff --git a/Qtorch/Models/__pycache__/Qnn.cpython-312.pyc b/Qtorch/Models/__pycache__/Qnn.cpython-312.pyc new file mode 100644 index 0000000..85726f7 Binary files /dev/null and b/Qtorch/Models/__pycache__/Qnn.cpython-312.pyc differ diff --git a/Qtorch/Models/__pycache__/__init__.cpython-310.pyc b/Qtorch/Models/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..2cab929 Binary files /dev/null and b/Qtorch/Models/__pycache__/__init__.cpython-310.pyc differ diff --git a/Qtorch/Models/__pycache__/__init__.cpython-312.pyc b/Qtorch/Models/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..e38d906 Binary files /dev/null and b/Qtorch/Models/__pycache__/__init__.cpython-312.pyc differ diff --git a/Qtorch/__init__.py b/Qtorch/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Qtorch/__pycache__/Qmlp.cpython-312.pyc b/Qtorch/__pycache__/Qmlp.cpython-312.pyc new file mode 100644 index 0000000..6bcc4c2 Binary files /dev/null and b/Qtorch/__pycache__/Qmlp.cpython-312.pyc differ diff --git a/Qtorch/__pycache__/Qnn.cpython-312.pyc b/Qtorch/__pycache__/Qnn.cpython-312.pyc new file mode 100644 index 0000000..bc3f366 Binary files /dev/null and b/Qtorch/__pycache__/Qnn.cpython-312.pyc differ diff --git a/Qtorch/__pycache__/__init__.cpython-310.pyc b/Qtorch/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..807caaf Binary files /dev/null and b/Qtorch/__pycache__/__init__.cpython-310.pyc differ diff --git a/Qtorch/__pycache__/__init__.cpython-312.pyc b/Qtorch/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..3837539 Binary files /dev/null and b/Qtorch/__pycache__/__init__.cpython-312.pyc differ diff --git a/SVM b/SVM new file mode 160000 index 0000000..3aec5f2 --- /dev/null +++ b/SVM @@ -0,0 +1 @@ +Subproject commit 3aec5f294e817679e61b0833d4f750b9f118cfbc diff --git a/catplus b/catplus new file mode 100755 index 0000000..5ba5acc --- /dev/null +++ b/catplus @@ -0,0 +1,49 @@ +#!/bin/bash + +# 输出的Markdown文件名 +output_file="python_files_output.md" + +# 清空或创建输出文件 +> "$output_file" + +# 递归函数来处理目录 +process_directory() { + local dir="$1" + local depth="$2" + + # 添加目录作为标题 + echo "$(printf '%0.s#' $(seq 1 $depth)) ${dir##*/}" >> "$output_file" + echo "" >> "$output_file" + + # 遍历当前目录中的所有.py文件 + for file in "$dir"/*.py; do + # 检查文件是否存在(以防止没有.py文件的情况) + if [ -f "$file" ]; then + # 将文件名作为子标题写入md文件 + echo "$(printf '%0.s#' $(seq 1 $((depth + 1)))) ${file##*/}" >> "$output_file" + echo "" >> "$output_file" + + # 添加代码块开始标记 + echo '```python' >> "$output_file" + + # 将Python文件内容添加到md文件 + cat "$file" >> "$output_file" + + # 添加代码块结束标记 + echo '```' >> "$output_file" + echo "" >> "$output_file" + fi + done + + # 递归处理子目录 + for subdir in "$dir"/*/; do + if [ -d "$subdir" ]; then + process_directory "$subdir" $((depth + 1)) + fi + done +} + +# 从当前目录开始处理 +process_directory "." 1 + +echo "Markdown文件已生成: $output_file" diff --git a/main.py b/main.py new file mode 100644 index 0000000..bcfdbb2 --- /dev/null +++ b/main.py @@ -0,0 +1,189 @@ +# frofrom Qtorch.Functions import dLoader +from Qtorch.Models.Qmlp import Qmlp +from Qfunctions.divSet import divSet +from Qfunctions.loaData import load_data as dLoader +from sklearn.decomposition import PCA + +import torch + +def main(): + projet_name = '20241005Sound' + label_names =["Accuracy", "Compress", "Distance", "Loss", "Metal", "Python"] + data = dLoader(projet_name, label_names, isDir=False) + X_train, X_test, y_train, y_test, encoder = divSet( + data=data, labels=label_names, test_size= 0.5 + ) + + print(y_train) + + import pandas as pd + pca = PCA(n_components=2) # 保留两个主成分 + principalComponents = pca.fit_transform(X_train) + df_pca2d = pd.DataFrame(data=principalComponents, columns=['PC1', 'PC2']) + df_pca2d['labels'] = y_train + + pca = PCA(n_components=3) # 保留三个主成分 + principalComponents = pca.fit_transform(X_train) + df_pca3d = pd.DataFrame(data=principalComponents, columns=['PC1', 'PC2', 'PC3']) + df_pca3d['labels'] = y_train + + # 保存为CSV文件 + import os + folder = os.path.join("./Result", projet_name) + df_pca2d.to_excel(os.path.join(folder, 'pca_2d_points_with_labels.xlsx'), index=False) + df_pca3d.to_excel(os.path.join(folder, 'pca_3d_points_with_labels.xlsx'), index=False) + + + + # model = Qmlp( + # X_train=X_train, X_test=X_test, y_train=y_train, y_test= y_test, + # hidden_layers=[32, 32, 32], + # dropout_rate=0 + # ) + # model.fit(100) + + # cm = model.get_cm() + # epoch_data = model.get_epoch_data() + + # from Qfunctions.saveToxlsx import save_to_xlsx as stx + # stx(project_name=projet_name, file_name="cm", data=cm) + # stx(project_name=projet_name, file_name="acc_and_loss", data=epoch_data) + # print("Done") + +if __name__ == '__main__': + main() + + + + +# from sklearn.model_selection import train_test_split +# from sklearn.preprocessing import StandardScaler +# from sklearn.svm import SVC +# from sklearn.model_selection import GridSearchCV +# from sklearn.metrics import accuracy_score, classification_report, confusion_matrix +# import pandas as pd + +# if __name__ == '__main__': + +# project_name = '20240829Letters' +# labels = None + +# data = ld(project_name, labels) + + + + + # svm = SVM( + # data=data, + # labels=labels + # ) + + # svm.fit() + + # X, y = data.iloc[:, :-1], data.iloc[:, -1] + + # # 分割数据 + # X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=None) + + # # 标准化数据 + # scaler = StandardScaler() + # X_train_scaled = scaler.fit_transform(X_train) + # X_test_scaled = scaler.transform(X_test) + + # # 创建 SVM 分类器 + # svm = SVC(kernel='rbf', random_state=42) + + # # 定义参数网格 + # param_grid = { + # 'C': [0.1, 1, 10, 100], + # 'gamma': ['scale', 'auto', 0.1, 1, 10] + # } + + # # 使用网格搜索进行超参数调优 + # grid_search = GridSearchCV(svm, param_grid, cv=5, n_jobs=-1, verbose=2) + # grid_search.fit(X_train_scaled, y_train) + + # # 打印最佳参数 + # print("Best parameters:", grid_search.best_params_) + + # # 使用最佳参数的模型 + # best_svm = grid_search.best_estimator_ + + # # 计算训练集和测试集准确率 + # y_train_pred = best_svm.predict(X_train_scaled) + # train_acc = accuracy_score(y_train, y_train_pred) + + # y_test_pred = best_svm.predict(X_test_scaled) + # test_acc = accuracy_score(y_test, y_test_pred) + + # # 在测试集上进行预测 + # y_pred = best_svm.predict(X_test_scaled) + + # # 计算准确率 + # accuracy = accuracy_score(y_test, y_pred) + # print(f"Accuracy: {accuracy}") + + # # 打印详细的分类报告 + # print(classification_report(y_test, y_pred)) + # # 计算并可视化混淆矩阵 + # cm = confusion_matrix(y_test, y_test_pred, normalize='true') + + # print(cm) + # # model = QSVM( + # # data=data, + # # labels=labels + # # ) + + # # model.fit(300) + # # model.save(project_name) + + + # # 创建一个 Excel 写入器 + # # 将分类报告转换为DataFrame + # # 获取分类报告 + + # report = classification_report(y_test, y_test_pred, output_dict=True) + + # df_report = pd.DataFrame(report).transpose() + # with pd.ExcelWriter(f'./Result/{project_name}/svm_results.xlsx') as writer: + # from sklearn.decomposition import PCA + # pca = PCA() + # X_pca = pca.fit_transform(X) + # # 创建 2D PCA 坐标的 DataFrame + # df_pca_2d = pd.DataFrame(data = X_pca[:, :2], columns = ['First Principal Component', 'Second Principal Component']) + # df_pca_2d['Label'] = y + # # 创建 3D PCA 坐标的 DataFrame + # df_pca_3d = pd.DataFrame(data = X_pca[:, :3], columns = ['First Principal Component', 'Second Principal Component', 'Third Principal Component']) + # df_pca_3d['Label'] = y + + # # 将 2D PCA 坐标写入 Excel + # df_pca_2d.to_excel(writer, sheet_name='PCA 2D Coordinates', index=False) + # df_pca_3d.to_excel(writer, sheet_name='PCA 3D Coordinates', index=False) + + + # # 将分类报告写入Excel + # df_report.to_excel(writer, sheet_name='Classification Report') + + # # 将最佳参数写入Excel + # pd.DataFrame([grid_search.best_params_]).to_excel(writer, sheet_name='Best Parameters') + + # # 如果你想保存混淆矩阵 + # from sklearn.metrics import confusion_matrix + # # 创建混淆矩阵并添加标签 + # cm = confusion_matrix(y_test, y_test_pred, normalize='true') + # df_cm = pd.DataFrame(cm, index=labels, columns=labels) + # df_cm.index.name = 'True' + # df_cm.columns.name = 'Predicted' + + # # 将混淆矩阵写入Excel + # df_cm.to_excel(writer, sheet_name='Confusion Matrix') + + # # 如果你想保存训练集和测试集的准确率 + # train_accuracy = best_svm.score(X_train_scaled, y_train) + # test_accuracy = best_svm.score(X_test_scaled, y_test) + # pd.DataFrame({ + # 'Train Accuracy': [train_accuracy], + # 'Test Accuracy': [test_accuracy] + # }).to_excel(writer, sheet_name='Accuracy') + + # print("Results have been saved to 'svm_results.xlsx'") \ No newline at end of file diff --git a/remake/.vscode/launch.json b/remake/.vscode/launch.json new file mode 100644 index 0000000..14b7790 --- /dev/null +++ b/remake/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python Debugger: Current File", + "type": "debugpy", + "request": "launch", + "program": "main.py", + "console": "integratedTerminal" + } + ] +} \ No newline at end of file diff --git a/remake/Qtorch/Functions/__init__.py b/remake/Qtorch/Functions/__init__.py new file mode 100644 index 0000000..e2eb142 --- /dev/null +++ b/remake/Qtorch/Functions/__init__.py @@ -0,0 +1,5 @@ +from .dataLoader import dLoader +from .dataSplitter import dsplit +from .resSaver import save_to_xlsx + +__all__ = ['dLoader', 'dsplit', 'save_to_xlsx'] \ No newline at end of file diff --git a/remake/Qtorch/Functions/__pycache__/__init__.cpython-312.pyc b/remake/Qtorch/Functions/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..3412e26 Binary files /dev/null and b/remake/Qtorch/Functions/__pycache__/__init__.cpython-312.pyc differ diff --git a/remake/Qtorch/Functions/__pycache__/dataLoader.cpython-312.pyc b/remake/Qtorch/Functions/__pycache__/dataLoader.cpython-312.pyc new file mode 100644 index 0000000..257c78d Binary files /dev/null and b/remake/Qtorch/Functions/__pycache__/dataLoader.cpython-312.pyc differ diff --git a/remake/Qtorch/Functions/__pycache__/dataSplitter.cpython-312.pyc b/remake/Qtorch/Functions/__pycache__/dataSplitter.cpython-312.pyc new file mode 100644 index 0000000..7e7e830 Binary files /dev/null and b/remake/Qtorch/Functions/__pycache__/dataSplitter.cpython-312.pyc differ diff --git a/remake/Qtorch/Functions/__pycache__/resSaver.cpython-312.pyc b/remake/Qtorch/Functions/__pycache__/resSaver.cpython-312.pyc new file mode 100644 index 0000000..55919bb Binary files /dev/null and b/remake/Qtorch/Functions/__pycache__/resSaver.cpython-312.pyc differ diff --git a/remake/Qtorch/Functions/dataLoader.py b/remake/Qtorch/Functions/dataLoader.py new file mode 100644 index 0000000..090d3cf --- /dev/null +++ b/remake/Qtorch/Functions/dataLoader.py @@ -0,0 +1,91 @@ +import os +import pandas as pd + +STATIC_PATH = './Static' + +def dLoader(folder, label_names=None): + + """ + Load data from Excel files in a specified folder. + + Args: + folder (str): Name of the folder containing Excel files. + label_names (list): Optional list of label names. If not provided, file names will be used. + + Returns: + pandas.DataFrame: Loaded and processed data. + """ + + folder_path = os.path.join(STATIC_PATH, folder) + file_names = [f for f in os.listdir(folder_path) if f.endswith('.xlsx')] + + + if not label_names: + label_names = [f.split('.')[0] for f in file_names] + + max_row_length = get_max_row_len(folder_path, file_names) + + all_features = [] + for i, file_name in enumerate(file_names): + features = load_xlsx(os.path.join(folder_path, file_name), label_names[i], max_row_length) + all_features.append(features) + + return pd.concat(all_features, ignore_index=True) + +def load_xlsx(file_name, label_name, max_row_length, fill_rule='mean'): + """ + Load and process data from a single Excel file. + + Args: + file_name (str): Path to the Excel file. + label_name (str): Label for the data in this file. + max_row_length (int): Maximum number of rows to consider. + fill_rule (str): Rule for filling missing values ('min', 'mean', or None). + + Returns: + pandas.DataFrame: Processed data from the Excel file. + """ + df = pd.read_excel(file_name) + features = df.iloc[0:, 1::2] + features.dropna(inplace=True) + features.reset_index(drop=True, inplace=True) + features = features.T + features = features.apply(lambda row: fill_to_len(row, max_row_length, fill_rule), axis=1) + + features['label'] = label_name + features.columns = [f'feature{i+1}' for i in range(max_row_length)] + ['label'] + + return features + +def fill_to_len(row, length=1000, rule=None): + """ + Fill a row to a specified length. + + Args: + row (pandas.Series): Row to fill. + length (int): Desired length of the row. + rule (str): Rule for filling ('min', 'mean', or None). + + Returns: + pandas.Series: Filled row. + """ + fill_value = 0 + if rule == 'min': + fill_value = row.min() + elif rule == 'mean': + fill_value = row.mean() + fill_values = pd.Series([fill_value] * (length - len(row))) + return pd.concat([row, fill_values], ignore_index=True) + +def get_max_row_len(folder, filenames): + """ + Get the maximum row length across all Excel files in a folder. + + Args: + folder (str): Path to the folder containing Excel files. + filenames (list): List of Excel file names. + + Returns: + int: Maximum row length. + """ + return max(pd.read_excel(os.path.join(folder, filename)).shape[0] for filename in filenames) \ No newline at end of file diff --git a/remake/Qtorch/Functions/dataSplitter.py b/remake/Qtorch/Functions/dataSplitter.py new file mode 100644 index 0000000..ef9e421 --- /dev/null +++ b/remake/Qtorch/Functions/dataSplitter.py @@ -0,0 +1,37 @@ +from sklearn.model_selection import train_test_split +from sklearn.preprocessing import StandardScaler, LabelEncoder + +def dsplit(data, labels=None, test_size=0.2, random_state=None): + """ + Split the dataset into training and testing sets. + + Args: + data (pandas.DataFrame): Input data. + labels (list): Optional list of labels. + test_size (float): Proportion of the dataset to include in the test split. + random_state (int): Random state for reproducibility. + + Returns: + tuple: X_train, X_test, y_train, y_test, encoded_labels + """ + encoder = LabelEncoder() + + X = data.iloc[:, :-1] + y = data.iloc[:, -1] + + if labels is not None: + encoded_labels = encoder.fit_transform(labels) + else: + encoder.fit(y) + encoded_labels = None + + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=random_state) + + scaler = StandardScaler() + X_train = scaler.fit_transform(X_train) + X_test = scaler.transform(X_test) + + y_train = encoder.transform(y_train.values.ravel()) + y_test = encoder.transform(y_test.values.ravel()) + + return X_train, X_test, y_train, y_test, encoded_labels \ No newline at end of file diff --git a/remake/Qtorch/Functions/resSaver.py b/remake/Qtorch/Functions/resSaver.py new file mode 100644 index 0000000..2713e36 --- /dev/null +++ b/remake/Qtorch/Functions/resSaver.py @@ -0,0 +1,15 @@ +import os + +def save_to_xlsx(project_name, file_name, data): + """ + Save data to an Excel file. + + Args: + project_name (str): Name of the project (used for folder name). + file_name (str): Name of the file to save. + data (pandas.DataFrame): Data to save. + """ + os.makedirs(f'Result/{project_name}', exist_ok=True) + file_path = f'Result/{project_name}/{file_name}.xlsx' + data.to_excel(file_path, index=True) + print(f"Data saved successfully to {file_path}") \ No newline at end of file diff --git a/remake/Qtorch/__init__.py b/remake/Qtorch/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/remake/Qtorch/__pycache__/__init__.cpython-312.pyc b/remake/Qtorch/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..656b4ef Binary files /dev/null and b/remake/Qtorch/__pycache__/__init__.cpython-312.pyc differ diff --git a/remake/Qtorch/models/QSVM.py b/remake/Qtorch/models/QSVM.py new file mode 100644 index 0000000..73e22c8 --- /dev/null +++ b/remake/Qtorch/models/QSVM.py @@ -0,0 +1,21 @@ +from .Qnn import Qnn + +class QSVM(Qnn): + def __init__(self, data, labels=None, test_size=0.2, random_state=None): + super(QSVM, self).__init__(data, labels, test_size, random_state) + self.result.update({ + "pca_2d": None, + "pca_3d": None + }) + + def forward(self, x): + # Implement SVM forward pass + pass + + def train_model(self, epochs): + # Implement SVM training logic + pass + + def hinge_loss(self, output, target): + # Implement hinge loss + pass \ No newline at end of file diff --git a/remake/Qtorch/models/Qnn.py b/remake/Qtorch/models/Qnn.py new file mode 100644 index 0000000..dddb709 --- /dev/null +++ b/remake/Qtorch/models/Qnn.py @@ -0,0 +1,72 @@ +import torch +import torch.nn as nn +import pandas as pd +from abc import ABC, abstractmethod +from Qtorch.Functions import dsplit +from Qtorch.Functions import save_to_xlsx as stx +# from sklearn.metrics import confusion_matrix + +class Qnn(nn.Module, ABC): + def __init__(self, data, labels=None, test_size=0.2, random_state=None): + super(Qnn, self).__init__() + self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + self.original_labels = labels + + # Split data + self.X_train, self.X_test, self.y_train, self.y_test, self.labels = dsplit( + data=data, + labels=labels, + test_size=test_size, + random_state=random_state + ) + + self.train_loader, self.test_loader = self._prepare_data() + + self.result = { + 'acc_and_loss': { + 'epoch': [], + 'loss': [], + 'train_accuracy': [], + 'test_accuracy': [], + }, + 'confusion_matrix': None, + } + + @abstractmethod + def forward(self, x): + pass + + @abstractmethod + def train_model(self, epochs): + pass + + def fit(self, epochs=100): + self.train_model(epochs) + + def save(self, project_name): + for filename, data in self.result.items(): + if filename == 'confusion_matrix': + data = pd.DataFrame(data, columns=self.original_labels, index=self.original_labels) + else: + data = pd.DataFrame(data) + stx(project_name, filename, data) + + def _prepare_data(self): + X_train_tensor = torch.tensor(self.X_train, dtype=torch.float32) + y_train_tensor = torch.tensor(self.y_train, dtype=torch.long) + + X_test_tensor = torch.tensor(self.X_test, dtype=torch.float32) + y_test_tensor = torch.tensor(self.y_test, dtype=torch.long) + + train_dataset = torch.utils.data.TensorDataset(X_train_tensor, y_train_tensor) + test_dataset = torch.utils.data.TensorDataset(X_test_tensor, y_test_tensor) + + train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True) + test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False) + + return train_loader, test_loader + + # def confusion_matrix(self, test_outputs): + # predicted = torch.argmax(test_outputs, dim=1) + # true_label = torch.argmax(self.y_test, dim=1) + # return confusion_matrix(predicted.cpu(), true_label.cpu()) \ No newline at end of file diff --git a/remake/Qtorch/models/Qsvm_brf.py b/remake/Qtorch/models/Qsvm_brf.py new file mode 100644 index 0000000..d94474b --- /dev/null +++ b/remake/Qtorch/models/Qsvm_brf.py @@ -0,0 +1,114 @@ +import torch +import torch.nn as nn +import torch.optim as optim +from tqdm import tqdm +from .QSVM import QSVM +from sklearn.metrics import confusion_matrix + +class Qsvm_brf(QSVM): + def __init__(self, data, labels=None, test_size=0.2, random_state=None, + gamma=1.0, C=100, batch_size=64, learning_rate=0.01): + super(Qsvm_brf, self).__init__(data, labels, test_size, random_state) + self.to(self.device) + self.gamma = gamma + self.C = C + self.n_features = data.shape[1] - 1 + self.support_vectors = torch.cat([batch[0] for batch in self.train_loader]).to(self.device) + self.alpha = nn.Parameter(torch.zeros(self.support_vectors.shape[0])).to(self.device) + self.b = nn.Parameter(torch.zeros(1)).to(self.device) + self.batch_size = batch_size + self.learning_rate = learning_rate + print(self.b, self.alpha) + print(list(self.parameters())) + + def train_model(self, epochs): + self.to(self.device) + self.optimizer = optim.SGD(self.parameters(), lr=self.learning_rate) + + for epoch in range(epochs): + self.train() + total_loss = 0 + correct = 0 + total = 0 + + progress_bar = tqdm(self.train_loader, desc=f'Epoch {epoch+1}/{epochs}') + for batch_X, batch_y in progress_bar: + batch_X, batch_y = batch_X.to(self.device), batch_y.to(self.device) + + self.optimizer.zero_grad() + + outputs = self(batch_X) + loss = self.hinge_loss(outputs, batch_y) + self.C * self.regularization() + + loss.backward() + self.optimizer.step() + + total_loss += loss.item() + predicted = torch.sign(outputs) + correct += (predicted == batch_y).sum().item() + total += batch_y.size(0) + + progress_bar.set_postfix({ + 'Loss': total_loss / (progress_bar.n + 1), + 'Acc': 100. * correct / total + }) + + train_accuracy = correct / total + test_accuracy = self.evaluate() + + self.result['acc_and_loss']['epoch'].append(epoch + 1) + self.result['acc_and_loss']['loss'].append(total_loss / len(self.train_loader)) + self.result['acc_and_loss']['train_accuracy'].append(train_accuracy) + self.result['acc_and_loss']['test_accuracy'].append(test_accuracy) + + print(f'Epoch [{epoch+1}/{epochs}], Loss: {total_loss/len(self.train_loader):.4f}, ' + f'Train Acc: {train_accuracy:.4f}, Test Acc: {test_accuracy:.4f}') + + # 计算最终的混淆矩阵 + self.result['confusion_matrix'] = self.compute_confusion_matrix() + + def compute_confusion_matrix(self): + self.eval() + all_predictions = [] + all_labels = [] + + with torch.no_grad(): + for batch_X, batch_y in self.test_loader: + batch_X, batch_y = batch_X.to(self.device), batch_y.to(self.device) + outputs = self(batch_X) + predicted = torch.sign(outputs) + + all_predictions.extend(predicted.cpu().numpy()) + all_labels.extend(batch_y.cpu().numpy()) + + return confusion_matrix(all_labels, all_predictions) + + def evaluate(self): + self.eval() + correct = 0 + total = 0 + with torch.no_grad(): + for batch_X, batch_y in self.test_loader: + batch_X, batch_y = batch_X.to(self.device), batch_y.to(self.device) + outputs = self(batch_X) + predicted = torch.sign(outputs) + correct += (predicted == batch_y).sum().item() + total += batch_y.size(0) + return correct / total + + def rbf_kernel(self, X, Y): + X_norm = (X**2).sum(1).view(-1, 1) + Y_norm = (Y**2).sum(1).view(1, -1) + dist = X_norm + Y_norm - 2.0 * torch.mm(X, Y.t()) + return torch.exp(-self.gamma * dist) + + def forward(self, X): + X = X.to(self.device) + K = self.rbf_kernel(X, self.support_vectors) + return torch.mm(K, self.alpha.unsqueeze(1)).squeeze() + self.b + + def hinge_loss(self, outputs, targets): + return torch.mean(torch.clamp(1 - outputs * targets, min=0)) + + def regularization(self): + return 0.5 * (self.alpha ** 2).sum() \ No newline at end of file diff --git a/remake/Qtorch/models/__init__.py b/remake/Qtorch/models/__init__.py new file mode 100644 index 0000000..2d60838 --- /dev/null +++ b/remake/Qtorch/models/__init__.py @@ -0,0 +1,3 @@ +from .Qsvm_brf import Qsvm_brf + +__all__ = ['Qsvm_brf'] \ No newline at end of file diff --git a/remake/Qtorch/models/__pycache__/QSVM.cpython-312.pyc b/remake/Qtorch/models/__pycache__/QSVM.cpython-312.pyc new file mode 100644 index 0000000..2a1814b Binary files /dev/null and b/remake/Qtorch/models/__pycache__/QSVM.cpython-312.pyc differ diff --git a/remake/Qtorch/models/__pycache__/Qnn.cpython-312.pyc b/remake/Qtorch/models/__pycache__/Qnn.cpython-312.pyc new file mode 100644 index 0000000..46cccba Binary files /dev/null and b/remake/Qtorch/models/__pycache__/Qnn.cpython-312.pyc differ diff --git a/remake/Qtorch/models/__pycache__/Qsvm_brf.cpython-312.pyc b/remake/Qtorch/models/__pycache__/Qsvm_brf.cpython-312.pyc new file mode 100644 index 0000000..103739a Binary files /dev/null and b/remake/Qtorch/models/__pycache__/Qsvm_brf.cpython-312.pyc differ diff --git a/remake/Qtorch/models/__pycache__/__init__.cpython-312.pyc b/remake/Qtorch/models/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..d8dbabf Binary files /dev/null and b/remake/Qtorch/models/__pycache__/__init__.cpython-312.pyc differ diff --git a/remake/README.md b/remake/README.md new file mode 100644 index 0000000..e69de29 diff --git a/remake/main.py b/remake/main.py new file mode 100644 index 0000000..31946fa --- /dev/null +++ b/remake/main.py @@ -0,0 +1,23 @@ +from Qtorch.Functions import dLoader +from Qtorch.Models.Qmlp import Qmlp +from Qfuctions.divSet import divSet + +def main(): + projet_name = '20240821Sound' + label_names = None + + data = dLoader(projet_name, label_names) + + X_train, X_test, y_train, y_test, encoded_labels = + + + + + + + + + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/test.py b/test.py new file mode 100644 index 0000000..174b196 --- /dev/null +++ b/test.py @@ -0,0 +1,110 @@ +from graphviz import Digraph +import os + + +class layer: + def __init__(self, graph, name, size, color): + self.name = name + self.size = size + self.color = color + self.graph = graph + + def draw(): + pass + +class input_layer(layer): + def __init__(self, graph, size): + super().__init__(graph, f"Input Layer({size})", size) + self.graph.node(self.name, shape='circle', style='filled', fillcolor=self.color, label=" ") + self.graph.attr(label=f'{self.name} Layer({self.size})', fontname='Times New Roman', fontweight='bold', fontsize='36') + + +def draw_neural_net(input_size, hidden_sizes, num_classes, show_hidden=3): + g = Digraph('G', filename='neural_network', format='png') + g.attr(rankdir='LR', size='10,8', nodesep='1', ranksep='2', bgcolor='transparent', dpi='300') + + # Input layer + with g.subgraph(name='cluster_input') as c: + c.attr(color='white') + for i in range(input_size): + c.node(f'input_{i}', shape='circle', style='filled', fillcolor='darkorange:orange', label=" ") + c.attr(label=f'Input Layer({input_size})', fontname='Times New Roman', fontweight='bold', fontsize='36') + + # Hidden layers + previous_layer = 'input' + previous_layer_size = input_size + for layer_idx, hidden_size in enumerate(hidden_sizes): + with g.subgraph(name=f'cluster_hidden_{layer_idx}') as c: + c.attr(color='white') + for i in range(show_hidden): + c.node(f'hidden_{layer_idx}_{i}', shape='circle', style='filled', fillcolor='darkgreen:lightgreen', label=" ") + if hidden_size > show_hidden * 2: + c.node(f'ellipsis_{layer_idx}', shape='plaintext', label='...') + for i in range(hidden_size - show_hidden, hidden_size): + c.node(f'hidden_{layer_idx}_{i}', shape='circle', style='filled', fillcolor='darkgreen:lightgreen', label=" ") + c.attr(label=f'Hidden Layer {layer_idx + 1}({hidden_size})', fontname='Times New Roman', fontweight='bold', fontsize='36') + + # Add edges from previous layer to current hidden layer + if layer_idx == 0: # Only connect input layer to first hidden layer + for i in range(previous_layer_size): + for j in range(show_hidden): + g.edge(f'{previous_layer}_{i}', f'hidden_{layer_idx}_{j}') + for j in range(hidden_size - show_hidden, hidden_size): + g.edge(f'{previous_layer}_{i}', f'hidden_{layer_idx}_{j}') + else: + for i in range(show_hidden): + for j in range(show_hidden): + g.edge(f'hidden_{layer_idx - 1}_{i}', f'hidden_{layer_idx}_{j}') + for j in range(hidden_size - show_hidden, hidden_size): + g.edge(f'hidden_{layer_idx - 1}_{i}', f'hidden_{layer_idx}_{j}') + for i in range(hidden_size - show_hidden, hidden_size): + for j in range(show_hidden): + g.edge(f'hidden_{layer_idx - 1}_{i}', f'hidden_{layer_idx}_{j}') + for j in range(hidden_size - show_hidden, hidden_size): + g.edge(f'hidden_{layer_idx - 1}_{i}', f'hidden_{layer_idx}_{j}') + + previous_layer = f'hidden_{layer_idx}' + previous_layer_size = hidden_size + + # Output layer + with g.subgraph(name='cluster_output') as c: + c.attr(color='white') + for i in range(num_classes): + c.node(f'output_{i}', shape='circle', style='filled', fillcolor='darkorange:orange', label=" ") + c.attr(label=f'Output Layer({num_classes})', fontname='Times New Roman', fontweight='bold', fontsize='36') + + # Add edges from last hidden layer to output layer + # for i in range(previous_layer_size): + # for j in range(num_classes): + # g.edge(f'{previous_layer}_{i}', f'output_{j}') + # # Add edges + # # Add edges from input to visible hidden nodes + # for i in range(input_size): + # for j in range(show_hidden): + # g.edge(f'input_{i}', f'hidden_{j}') + # for i in range(input_size): + # for j in range(hidden_size - show_hidden, hidden_size): + # g.edge(f'input_{i}', f'hidden_{j}') + + # # Add edges from visible hidden nodes to output layer + # for i in range(show_hidden): + # for j in range(num_classes): + # g.edge(f'hidden_{i}', f'output_{j}') + # for i in range(hidden_size - show_hidden, hidden_size): + # for j in range(num_classes): + # g.edge(f'hidden_{i}', f'output_{j}') + # Add edges from last hidden layer to output layer + for i in range(show_hidden): + for j in range(num_classes): + g.edge(f'{previous_layer}_{i}', f'output_{j}') + for i in range(previous_layer_size - show_hidden, previous_layer_size): + for j in range(num_classes): + g.edge(f'{previous_layer}_{i}', f'output_{j}') + + return g + +if __name__ == '__main__': + g = draw_neural_net(7, [60, 60], 7) + output_path = g.render(view=False) + print(output_path) + os.system(f'explorer.exe neural_network.png') \ No newline at end of file diff --git a/test2.py b/test2.py new file mode 100644 index 0000000..b5c13f4 --- /dev/null +++ b/test2.py @@ -0,0 +1,55 @@ +import pandas as pd +import torch +from torch.utils.data import DataLoader, TensorDataset + +# 读取Excel文件 +df = pd.read_excel('loss-metal-compress.xlsx') + +# 假设你的模型需要的数据是前300行 +data = df.iloc[300:600, 1].values + + +# 将数据转换为Tensor +data_tensor = torch.tensor(data, dtype=torch.float32).unsqueeze(0) # 增加一个批次维度 + +# 需要填充的0的数量 +padding_size = 371 - data_tensor.size(1) + +# 如果需要填充的0的数量大于0,则进行填充 +if padding_size > 0: + # 创建一个形状为[1, padding_size]的0张量 + padding_tensor = torch.zeros(1, padding_size, dtype=torch.float32) + # 将原始数据和0张量拼接起来 + data_tensor_padded = torch.cat((data_tensor, padding_tensor), dim=1) +else: + data_tensor_padded = data_tensor + +# 包装成TensorDataset和DataLoader +dataset = TensorDataset(data_tensor_padded) +dataloader = DataLoader(dataset, batch_size=1, shuffle=False) + +# 确定设备 +device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") +# device = 'cpu' +print(f"Using device: {device}") + +# 加载你的模型 +model = torch.load('Sound.pth', map_location=device) # 确保模型加载到正确的设备 +model.to(device) # 再次确保模型在正确的设备上 +model.eval() # 设置为评估模式 + +# 进行预测 +predictions = [] +with torch.no_grad(): + for batch in dataloader: + inputs = batch[0].to(device) # 将输入数据移动到相同的设备 + outputs = model(inputs) + _, predicted = torch.max(outputs, 1) + predictions.extend(predicted.cpu().numpy()) # 将预测结果移动回CPU并转换为numpy数组 + +# 打印预测结果 +print(predictions) + + + +