使用 Python 编写 DNN 神经网络根据基因表达量预测患者患病状态
导入所需库
import pandas as pd import numpy as np from sklearn.model_selection import train_test_split import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import Dataset, DataLoader from skopt import gp_minimize from skopt.space import Real, Integer from skopt.utils import use_named_args from skopt.plots import plot_objective, plot_convergence from sklearn.metrics import roc_curve, auc import matplotlib.pyplot as plt
读取数据
data = pd.read_excel('C:\Users\lenovo\Desktop\HIV\DNN神经网络测试\data1.xlsx')
将数据分为输入和输出
X = data.iloc[:, 1:].values.astype(np.float32) y = data.iloc[:, 0].values.astype(np.float32)
划分数据集为训练集和测试集
由于题目要求全部数据作为训练集,这里直接将数据用于训练
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
X_train = X y_train = y
定义数据集类
class GeneExpressionDataset(Dataset): def init(self, X, y): self.X = torch.from_numpy(X) self.y = torch.from_numpy(y)
def __len__(self):
return len(self.X)
def __getitem__(self, index):
return self.X[index], self.y[index]
定义 DNN 模型
class DNN(nn.Module): def init(self, input_size, hidden_size, output_size, n_hidden_layers): super(DNN, self).init() self.input_layer = nn.Linear(input_size, hidden_size) self.hidden_layers = nn.ModuleList([nn.Linear(hidden_size, hidden_size) for i in range(n_hidden_layers)]) self.output_layer = nn.Linear(hidden_size, output_size) self.attention_layer = nn.Linear(hidden_size, 1)
def forward(self, x):
x = nn.functional.relu(self.input_layer(x))
for layer in self.hidden_layers:
x = nn.functional.relu(layer(x))
attention_weights = nn.functional.softmax(self.attention_layer(x), dim=0)
attention_applied = x * attention_weights
output = nn.functional.sigmoid(self.output_layer(attention_applied.sum(dim=0)))
return output
定义训练函数
def train(model, dataloader, optimizer, criterion): model.train() running_loss = 0.0 running_corrects = 0 for inputs, labels in dataloader: optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() * inputs.size(0) running_corrects += torch.sum(torch.round(outputs) == labels.data) epoch_loss = running_loss / len(dataloader.dataset) epoch_acc = running_corrects.double() / len(dataloader.dataset) return epoch_loss, epoch_acc
定义贝叶斯优化函数
space = [Real(0.001, 0.1, name='lr'), Integer(32, 128, name='hidden_size'), Integer(2, 5, name='n_hidden_layers')]
@use_named_args(space) def objective(**params): lr = params['lr'] hidden_size = params['hidden_size'] n_hidden_layers = params['n_hidden_layers']
# 定义模型、损失函数和优化器
model = DNN(X_train.shape[1], hidden_size, 1, n_hidden_layers)
criterion = nn.BCELoss()
optimizer = optim.Adam(model.parameters(), lr=lr)
# 定义训练集
train_dataset = GeneExpressionDataset(X_train, y_train)
train_dataloader = DataLoader(train_dataset, batch_size=32, shuffle=True)
# 训练模型
for epoch in range(50):
train_loss, train_acc = train(model, train_dataloader, optimizer, criterion)
print(f'Epoch {epoch+1} - Train Loss: {train_loss:.4f} Train Accuracy: {train_acc:.4f}')
# 计算在测试集上的准确率
# 由于题目要求全部数据作为训练集,这里没有测试集
# test_dataset = GeneExpressionDataset(X_test, y_test)
# test_dataloader = DataLoader(test_dataset, batch_size=32, shuffle=False)
# model.eval()
# running_corrects = 0
# for inputs, labels in test_dataloader:
# outputs = model(inputs)
# running_corrects += torch.sum(torch.round(outputs) == labels.data)
# test_acc = running_corrects.double() / len(test_dataloader.dataset)
# 返回训练集上的准确率
return -train_acc
进行贝叶斯优化
res_gp = gp_minimize(objective, space, n_calls=100, random_state=42)
输出最优参数和准确率
print(f'Best Parameters: {res_gp.x}') print(f'Best Accuracy: {-res_gp.fun}')
绘制准确率变化图
plot_convergence(res_gp)
绘制损失变化图
plot_objective(res_gp)
绘制 ROC 图
model = DNN(X_train.shape[1], res_gp.x[1], 1, res_gp.x[2]) criterion = nn.BCELoss() optimizer = optim.Adam(model.parameters(), lr=res_gp.x[0]) train_dataset = GeneExpressionDataset(X, y) train_dataloader = DataLoader(train_dataset, batch_size=32, shuffle=True) for epoch in range(50): train_loss, train_acc = train(model, train_dataloader, optimizer, criterion)
test_dataset = GeneExpressionDataset(X_test, y_test)
test_dataloader = DataLoader(test_dataset, batch_size=32, shuffle=False)
model.eval() probabilities = [] true_labels = [] for inputs, labels in train_dataloader: outputs = model(inputs) probabilities.extend(outputs.data.numpy().tolist()) true_labels.extend(labels.data.numpy().tolist()) fpr, tpr, thresholds = roc_curve(true_labels, probabilities) roc_auc = auc(fpr, tpr) plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC curve (area = %0.2f)' % roc_auc) plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--') plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('Receiver operating characteristic') plt.legend(loc="lower right") plt.show()
原文地址: https://www.cveoy.top/t/topic/ndfq 著作权归作者所有。请勿转载和采集!