import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import pandas as pd
from sklearn.metrics import roc_auc_score
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

# 读取数据
path = 'C:\Users\lenovo\Desktop\HIV\DNN神经网络测试\data1.xlsx'
df = pd.read_excel(path)

# 划分数据
X = df.iloc[:, 1:].values
y = df.iloc[:, 0].values
# X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 定义DNN模型
class Net(nn.Module):
    def __init__(self, input_size, hidden_size1, hidden_size2, hidden_size3, output_size):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size1)
        self.fc2 = nn.Linear(hidden_size1, hidden_size2)
        self.fc3 = nn.Linear(hidden_size2, hidden_size3)
        self.fc4 = nn.Linear(hidden_size3, output_size)
        self.attention = nn.Linear(input_size, input_size)

    def forward(self, x):
        attn_weights = F.softmax(self.attention(x), dim=1)
        x = x * attn_weights
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = F.relu(self.fc3(x))
        x = torch.sigmoid(self.fc4(x))
        return x

# 定义损失函数和优化器
criterion = nn.BCELoss()
optimizer = optim.Adam

# 定义训练函数
def train(args, X, y):
    input_size, hidden_size1, hidden_size2, hidden_size3, output_size, lr, epochs = args

    # 定义模型
    model = Net(input_size, hidden_size1, hidden_size2, hidden_size3, output_size)
    optimizer = optim.Adam(model.parameters(), lr=lr)

    # 训练模型
    for epoch in range(epochs):
        model.train()
        optimizer.zero_grad()
        inputs = torch.Tensor(X)
        targets = torch.Tensor(y)
        outputs = model(inputs)
        loss = criterion(outputs, targets.unsqueeze(1))
        loss.backward()
        optimizer.step()

        # 计算准确率
        y_pred = (outputs > 0.5).float().squeeze()
        acc = (y_pred == targets).sum().item()/len(targets)

        # 输出准确率和损失值
        print(f'Epoch {epoch+1}/{epochs} | loss: {loss.item():.4f} | acc: {acc:.4f}')

    # 返回模型
    return model

# 定义贝叶斯优化函数
@use_named_args([
    ('input_size', Integer(16, 128)),
    ('hidden_size1', Integer(16, 128)),
    ('hidden_size2', Integer(16, 128)),
    ('hidden_size3', Integer(16, 128)),
    ('output_size', Integer(1, 2)),
    ('lr', Real(1e-4, 1e-1, 'log-uniform')),
    ('epochs', Integer(10, 200))
])
def objective(input_size, hidden_size1, hidden_size2, hidden_size3, output_size, lr, epochs):
    args = (input_size, hidden_size1, hidden_size2, hidden_size3, output_size, lr, epochs)
    model = train(args, X, y)

    # 计算AUC值
    with torch.no_grad():
        inputs = torch.Tensor(X)
        targets = torch.Tensor(y)
        outputs = model(inputs)
        y_pred = outputs.numpy().astype(float).squeeze()
        auc = roc_auc_score(targets, y_pred)

    # 输出AUC值
    print(f'AUC: {auc:.4f}')

    # 返回负AUC值
    return -auc

# 运行贝叶斯优化
result = gp_minimize(objective, 
                     dimensions=[Integer(16, 128), Integer(16, 128), Integer(16, 128), Integer(16, 128), Integer(1, 2), Real(1e-4, 1e-1, 'log-uniform'), Integer(10, 200)], 
                     n_calls=50)

# 输出最优参数
print(f'Best Parameters: {result.x}')
print(f'Best AUC: {-result.fun:.4f}')

# 绘制优化过程中AUC变化的图
plot_convergence(result)

# 训练模型并计算AUC值
input_size, hidden_size1, hidden_size2, hidden_size3, output_size, lr, epochs = result.x
model = train((input_size, hidden_size1, hidden_size2, hidden_size3, output_size, lr, epochs), X, y)
with torch.no_grad():
    inputs = torch.Tensor(X)
    targets = torch.Tensor(y)
    outputs = model(inputs)
    y_pred = outputs.numpy().astype(float).squeeze()
    auc = roc_auc_score(targets, y_pred)

# 绘制ROC曲线
# fpr, tpr, thresholds = roc_curve(targets, y_pred)
# plt.plot(fpr, tpr, label=f'AUC={auc:.4f}')
# plt.plot([0, 1], [0, 1], linestyle='--')
# plt.legend()
# plt.show()
基于Python的DNN神经网络基因表达量预测患者疾病状态

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

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