使用 Python 构建 DNN 神经网络,根据基因表达量预测患者疾病状态
导入所需模块
import numpy as np import pandas as pd import torch import torch.nn as nn 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 sklearn.metrics import roc_curve, auc import matplotlib.pyplot as plt
定义数据集类
class GeneDataset(Dataset): def init(self, data): self.data = data
def __len__(self):
return len(self.data)
def __getitem__(self, idx):
x = self.data.iloc[idx, 1:].values.astype(np.float32)
y = self.data.iloc[idx, 0]
return x, y
定义注意力层
class Attention(nn.Module): def init(self, input_size, hidden_size): super(Attention, self).init() self.input_size = input_size self.hidden_size = hidden_size self.fc1 = nn.Linear(input_size, hidden_size) self.fc2 = nn.Linear(hidden_size, 1)
def forward(self, x):
x = nn.functional.relu(self.fc1(x))
x = self.fc2(x)
x = nn.functional.softmax(x, dim=0)
return x
定义神经网络模型
class DNN(nn.Module): def init(self, input_size, hidden_size, num_layers, dropout_rate): super(DNN, self).init() self.input_size = input_size self.hidden_size = hidden_size self.num_layers = num_layers self.dropout_rate = dropout_rate self.fc1 = nn.Linear(input_size, hidden_size) self.attention = Attention(hidden_size, hidden_size) self.dropout = nn.Dropout(p=dropout_rate) self.fcs = nn.ModuleList([ nn.Linear(hidden_size, hidden_size) for i in range(num_layers-1) ]) self.fc2 = nn.Linear(hidden_size, 1)
def forward(self, x):
x = nn.functional.relu(self.fc1(x))
x = self.attention(x) * x
x = self.dropout(x)
for fc in self.fcs:
x = nn.functional.relu(fc(x))
x = self.dropout(x)
x = torch.sigmoid(self.fc2(x))
return x
定义训练函数
def train(model, train_loader, criterion, optimizer, device): model.train() total_loss = 0.0 total_correct = 0 total_data = 0 for x, y in train_loader: x, y = x.to(device), y.to(device) optimizer.zero_grad() y_pred = model(x) loss = criterion(y_pred, y.unsqueeze(1)) loss.backward() optimizer.step() total_loss += loss.item() * x.size(0) total_correct += ((y_pred > 0.5).int() == y.unsqueeze(1)).sum().item() total_data += x.size(0) accuracy = total_correct / total_data loss = total_loss / total_data return accuracy, loss
定义测试函数
def test(model, test_loader, criterion, device): model.eval() total_loss = 0.0 total_correct = 0 total_data = 0 y_true = [] y_pred = [] with torch.no_grad(): for x, y in test_loader: x, y = x.to(device), y.to(device) y_pred_ = model(x) loss = criterion(y_pred_, y.unsqueeze(1)) total_loss += loss.item() * x.size(0) total_correct += ((y_pred_ > 0.5).int() == y.unsqueeze(1)).sum().item() total_data += x.size(0) y_true.append(y.item()) y_pred.append(y_pred_.item()) accuracy = total_correct / total_data loss = total_loss / total_data fpr, tpr, _ = roc_curve(y_true, y_pred) roc_auc = auc(fpr, tpr) return accuracy, loss, fpr, tpr, roc_auc
定义贝叶斯优化函数
@use_named_args([ Real(1e-6, 1e-3, name='learning_rate'), Integer(16, 64, name='hidden_size'), Integer(1, 5, name='num_layers'), Real(0.1, 0.5, name='dropout_rate') ]) def optimize(learning_rate, hidden_size, num_layers, dropout_rate): # 读取数据 data = pd.read_excel('C:\Users\lenovo\Desktop\HIV\DNN神经网络测试\data1.xlsx') # 划分训练集和测试集 train_data = data.sample(frac=0.8, random_state=42) test_data = data.drop(train_data.index) # 定义数据集和数据加载器 train_dataset = GeneDataset(train_data) test_dataset = GeneDataset(test_data) train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False) # 定义设备 device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 定义模型 model = DNN(input_size=16, hidden_size=hidden_size, num_layers=num_layers, dropout_rate=dropout_rate) model.to(device) # 定义损失函数和优化器 criterion = nn.BCELoss() optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate) # 训练模型 for epoch in range(20): train_accuracy, train_loss = train(model, train_loader, criterion, optimizer, device) test_accuracy, test_loss, fpr, tpr, roc_auc = test(model, test_loader, criterion, device) print('Epoch {}, Train Accuracy: {:.4f}, Train Loss: {:.4f}, Test Accuracy: {:.4f}, Test Loss: {:.4f}'.format(epoch+1, train_accuracy, train_loss, test_accuracy, test_loss)) return -roc_auc
使用贝叶斯优化寻找最优参数
result = gp_minimize(optimize, [ Real(1e-6, 1e-3, name='learning_rate'), Integer(16, 64, name='hidden_size'), Integer(1, 5, name='num_layers'), Real(0.1, 0.5, name='dropout_rate') ], n_calls=50, random_state=42)
输出最优参数和最优ROC-AUC值
print('Best Parameters: ', result.x) print('Best ROC-AUC: {:.4f}'.format(-result.fun))
使用最优参数训练模型
data = pd.read_excel('C:\Users\lenovo\Desktop\HIV\DNN神经网络测试\data1.xlsx') train_dataset = GeneDataset(data) train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') model = DNN(input_size=16, hidden_size=result.x[1], num_layers=result.x[2], dropout_rate=result.x[3]) model.to(device) criterion = nn.BCELoss() optimizer = torch.optim.Adam(model.parameters(), lr=result.x[0]) for epoch in range(50): train_accuracy, train_loss = train(model, train_loader, criterion, optimizer, device) print('Epoch {}, Train Accuracy: {:.4f}, Train Loss: {:.4f}'.format(epoch+1, train_accuracy, train_loss))
绘制ROC曲线
_, _, fpr, tpr, roc_auc = test(model, train_loader, criterion, device) plt.figure() plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC curve (area = {:.4f})'.format(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()
绘制损失曲线
losses = [] for epoch in range(50): _, loss = train(model, train_loader, criterion, optimizer, device) losses.append(loss) plt.plot(losses) plt.xlabel('Epochs') plt.ylabel('Loss') plt.title('Training Loss') plt.show()
绘制准确率曲线
accuracies = [] for epoch in range(50): accuracy, _ = train(model, train_loader, criterion, optimizer, device) accuracies.append(accuracy) plt.plot(accuracies) plt.xlabel('Epochs') plt.ylabel('Accuracy') plt.title('Training Accuracy') plt.show()
原文地址: https://www.cveoy.top/t/topic/ndgN 著作权归作者所有。请勿转载和采集!