import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import pandas as pd
from sklearn.metrics import roc_auc_score
from skopt import gp_minimize
from skopt.space import Real, Categorical, Integer
from skopt.utils import use_named_args
import matplotlib.pyplot as plt

# 读取数据
data = pd.read_excel('C:\Users\lenovo\Desktop\HIV\DNN神经网络测试\data1.xlsx')
X = data.iloc[:, 1:].values
y = data.iloc[:, 0].values


# 定义神经网络模型
class DNN(nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim):
        super(DNN, self).__init__()
        self.fc1 = nn.Linear(input_dim, hidden_dim[0])
        self.fc2 = nn.Linear(hidden_dim[0], hidden_dim[1])
        self.fc3 = nn.Linear(hidden_dim[1], hidden_dim[2])
        self.fc4 = nn.Linear(hidden_dim[2], output_dim)
        self.dropout = nn.Dropout(p=0.5)
        self.attention = nn.MultiheadAttention(hidden_dim[2], 1)

    def forward(self, x):
        x = nn.functional.relu(self.fc1(x))
        x = self.dropout(x)
        x = nn.functional.relu(self.fc2(x))
        x = self.dropout(x)
        x = nn.functional.relu(self.fc3(x))
        x = self.dropout(x)
        x, _ = self.attention(x, x, x)
        x = nn.functional.sigmoid(self.fc4(x))
        return x


# 定义神经网络模型和优化器
def create_model(lr, hidden_dim1, hidden_dim2, hidden_dim3):
    model = DNN(input_dim=X.shape[1], hidden_dim=[hidden_dim1, hidden_dim2, hidden_dim3], output_dim=1)
    optimizer = optim.Adam(model.parameters(), lr=lr)
    return model, optimizer

# 定义损失函数
criterion = nn.BCELoss()

# 定义贝叶斯优化参数空间
space = [
    Real(0.001, 0.1, name='lr'),
    Integer(32, 128, name='batch_size'),
    Integer(16, 64, name='hidden_dim1'),
    Integer(16, 64, name='hidden_dim2'),
    Integer(16, 64, name='hidden_dim3')
]


# 定义贝叶斯优化函数
@use_named_args(space)
def objective(lr, batch_size, hidden_dim1, hidden_dim2, hidden_dim3):
    model, optimizer = create_model(lr, hidden_dim1, hidden_dim2, hidden_dim3)
    batch_num = X.shape[0] // batch_size
    train_acc_list = []
    train_loss_list = []
    for epoch in range(100):
        for i in range(batch_num):
            batch_X = torch.tensor(X[i * batch_size:(i + 1) * batch_size], dtype=torch.float32)
            batch_y = torch.tensor(y[i * batch_size:(i + 1) * batch_size], dtype=torch.float32).view(-1, 1)
            optimizer.zero_grad()
            outputs = model(batch_X)
            loss = criterion(outputs, batch_y)
            loss.backward()
            optimizer.step()
        # 计算训练集准确率和损失值
        with torch.no_grad():
            train_X = torch.tensor(X, dtype=torch.float32)
            train_y = torch.tensor(y, dtype=torch.float32).view(-1, 1)
            train_outputs = model(train_X)
            train_loss = criterion(train_outputs, train_y)
            train_pred = train_outputs.round().detach().numpy().flatten()
            train_acc = np.mean(train_pred == y)
            train_acc_list.append(train_acc)
            train_loss_list.append(train_loss.item())
            print('Epoch: %d, Train Loss: %.4f, Train Acc: %.4f' % (epoch + 1, train_loss.item(), train_acc))
    # 计算AUC-ROC值
    with torch.no_grad():
        test_X = torch.tensor(X, dtype=torch.float32)
        test_outputs = model(test_X)
        test_pred = test_outputs.detach().numpy().flatten()
        auc_roc = roc_auc_score(y, test_pred)
    return -auc_roc


# 进行贝叶斯优化
result = gp_minimize(objective, space, n_calls=50, random_state=0)

# 输出最优参数
print('Best Parameters: ', result.x)

# 绘制准确率变化的图
plt.plot(train_acc_list)
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.title('Accuracy Curve')
plt.show()

# 绘制损失变化的图
plt.plot(train_loss_list)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Loss Curve')
plt.show()

# 绘制ROC曲线
with torch.no_grad():
    test_X = torch.tensor(X, dtype=torch.float32)
    test_outputs = model(test_X)
    test_pred = test_outputs.detach().numpy().flatten()
    fpr, tpr, thresholds = roc_curve(y, test_pred)
    roc_auc = auc(fpr, tpr)
plt.plot(fpr, tpr, lw=1, alpha=0.8, label='ROC curve (AUC = %0.2f)' % (roc_auc))
plt.plot([0, 1], [0, 1], linestyle='--', lw=1, color='gray', alpha=.8)
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC Curve')
plt.legend(loc='lower right')
plt.show()
贝叶斯优化调参DNN模型,提升HIV预测准确率

原文地址: https://www.cveoy.top/t/topic/ndeC 著作权归作者所有。请勿转载和采集!

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