PyTorch 多层神经网络 (DNN) 训练 HIV 患者状态预测模型
PyTorch 多层神经网络 (DNN) 训练 HIV 患者状态预测模型
本代码使用 PyTorch 构建多层神经网络模型,通过训练多个模型,最终实现对 HIV 患者状态的预测。代码示例展示了如何读取数据、定义模型、训练模型以及解决训练过程中出现的错误。
import torch
import torch.nn as nn
import torch.optim as optim
import pandas as pd
# 读取 Excel 表格
data = pd.read_excel('C:\Users\lenovo\Desktop\HIV\DNN神经网络测试\data1.xlsx')
x = data.iloc[:, 1:].values # 取除第一列以外的所有列,即基因的表达量
y = data.iloc[:, 0].values # 取第一列,即患者状态标志 state
# 定义第一个模型,输出为 8 分类
class Model1(nn.Module):
def __init__(self):
super(Model1, self).__init__()
self.fc1 = nn.Linear(16, 128)
self.fc2 = nn.Linear(128, 64)
self.fc3 = nn.Linear(64, 32)
self.fc4 = nn.Linear(32, 16)
self.fc5 = nn.Linear(16, 8)
self.dropout = nn.Dropout(0.2)
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 = nn.functional.relu(self.fc4(x))
x = self.dropout(x)
x = self.fc5(x)
return x
# 定义第二个模型,输入为第一个模型的 8 分类输出,输出为 4 分类
class Model2(nn.Module):
def __init__(self):
super(Model2, self).__init__()
self.fc1 = nn.Linear(8, 16)
self.fc2 = nn.Linear(16, 8)
self.fc3 = nn.Linear(8, 4)
self.dropout = nn.Dropout(0.2)
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 = self.fc3(x)
return x
# 定义第三个模型,第三个模型为二分类模型,输入为第二个模型的 4 分类输出
class Model3(nn.Module):
def __init__(self):
super(Model3, self).__init__()
self.fc1 = nn.Linear(4, 8)
self.fc2 = nn.Linear(8, 1)
self.dropout = nn.Dropout(0.2)
def forward(self, x):
x = nn.functional.relu(self.fc1(x))
x = self.dropout(x)
x = torch.sigmoid(self.fc2(x))
return x
# 将数据转换为张量
x = torch.tensor(x).float()
y = torch.tensor(y).float().squeeze(0)
# 定义损失函数和优化器
criterion1 = nn.CrossEntropyLoss()
criterion2 = nn.CrossEntropyLoss()
criterion3 = nn.BCELoss()
model1 = Model1()
optimizer1 = optim.Adam(model1.parameters(), lr=0.001)
# 训练第一个模型
for epoch in range(100):
optimizer1.zero_grad()
output1 = model1(x)
loss1 = criterion1(output1, y.long())
loss1.backward()
optimizer1.step()
acc1 = (output1.argmax(dim=1) == y).float().mean()
print("Epoch [{}/{}], Loss: {:.4f}, Accuracy: {:.4f}".format(epoch+1, 100, loss1.item(), acc1.item()))
# 训练第二个模型
model2 = Model2()
output1 = model1(x)
output2 = model2(output1)
optimizer2 = optim.Adam(model2.parameters(), lr=0.001)
for epoch in range(100):
optimizer2.zero_grad()
loss2 = criterion2(output2, output1.argmax(dim=1).long())
loss2.backward(retain_graph=True) # 设置 retain_graph 参数为 True
optimizer2.step()
acc2 = (output2.argmax(dim=1) == output1.argmax(dim=1)).float().mean()
print("Epoch [{}/{}], Loss: {:.4f}, Accuracy: {:.4f}".format(epoch+1, 100, loss2.item(), acc2.item()))
# 训练第三个模型
model3 = Model3()
output3 = model3(output2)
optimizer3 = optim.Adam(model3.parameters(), lr=0.001)
for epoch in range(100):
optimizer3.zero_grad()
loss3 = criterion3(output3, y)
loss3.backward()
optimizer3.step()
acc3 = ((output3 > 0.5) == y).float().mean()
print("Epoch [{}/{}], Loss: {:.4f}, Accuracy: {:.4f}".format(epoch+1, 100, loss3.item(), acc3.item()))
解决错误:
在训练第二个模型时,出现了错误:Trying to backward through the graph a second time (or directly access saved tensors after they have already been freed). Saved intermediate values of the graph are freed when you call .backward() or autograd.grad(). Specify retain_graph=True if you need to backward through the graph a second time or if you need to access saved tensors after calling backward.
这是因为在计算梯度时,计算图被释放了,但在后续的计算中仍然试图访问已经释放的计算图,导致出现错误。
解决方法:
在每次计算梯度时,设置 retain_graph 参数为 True,表示保留计算图,以便后续计算使用。修改后的代码如上所示。
总结:
本代码展示了使用 PyTorch 构建多层神经网络模型并训练预测 HIV 患者状态的步骤。代码还解决了训练过程中常见的错误,并解释了如何通过设置 retain_graph 参数来解决该错误。
原文地址: https://www.cveoy.top/t/topic/myzx 著作权归作者所有。请勿转载和采集!