导入所需模块

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 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录