使用 PyTorch 构建双层神经网络进行分类预测
import torch
import torch.nn as nn
import torch.optim as optim
import pandas as pd
from sklearn.preprocessing import StandardScaler
# 读入Excel表格
data = pd.read_excel('C:\Users\lenovo\Desktop\HIV\DNN神经网络测试\data1.xlsx')
x = data.iloc[:, 1:].values # 获取基因表达量
y = data.iloc[:, 0].values # 获取患者状态标志
# 数据标准化
scaler = StandardScaler()
x = scaler.fit_transform(x)
# 定义第一个模型
class FirstModel(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(FirstModel, self).__init__()
self.fc1 = nn.Linear(input_size, hidden_size)
self.fc2 = nn.Linear(hidden_size, hidden_size)
self.fc3 = nn.Linear(hidden_size, output_size)
self.dropout = nn.Dropout(p=0.5)
self.relu = nn.ReLU()
def forward(self, x):
x = self.dropout(self.relu(self.fc1(x)))
x = self.dropout(self.relu(self.fc2(x)))
x = self.fc3(x)
return x
# 定义第二个模型
class SecondModel(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(SecondModel, self).__init__()
self.fc1 = nn.Linear(input_size, hidden_size)
self.fc2 = nn.Linear(hidden_size, hidden_size)
self.fc3 = nn.Linear(hidden_size, output_size)
self.dropout = nn.Dropout(p=0.5)
self.relu = nn.ReLU()
def forward(self, x):
x = self.dropout(self.relu(self.fc1(x)))
x = self.dropout(self.relu(self.fc2(x)))
x = self.fc3(x)
return x
# 定义训练函数
def train(model, criterion, optimizer, x, y):
model.train()
running_loss = 0.0
running_corrects = 0
for inputs, labels in zip(x, y):
inputs = torch.from_numpy(inputs).float()
labels = torch.tensor(labels).long()
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
_, preds = torch.max(outputs, dim=1) # 修改此处
loss.backward()
optimizer.step()
running_loss += loss.item() * inputs.size(0)
running_corrects += torch.sum(preds == labels)
epoch_loss = running_loss / len(y)
epoch_acc = running_corrects.double() / len(y)
return epoch_loss, epoch_acc
# 定义参数
input_size = len(data.columns) - 1 # 输入大小为基因个数
hidden_size = 64
output_size = 4
lr = 0.01
num_epochs = 100
# 训练第一个模型
first_model = FirstModel(input_size, hidden_size, output_size)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(first_model.parameters(), lr=lr, momentum=0.9)
for epoch in range(num_epochs):
epoch_loss, epoch_acc = train(first_model, criterion, optimizer, x, y)
print('First Model: Epoch [{}/{}], Loss: {:.4f}, Acc: {:.4f}'.format(epoch+1, num_epochs, epoch_loss, epoch_acc))
# 获取第一个模型的输出
output1 = []
for inputs in x:
inputs = torch.from_numpy(inputs).float()
outputs = first_model(inputs)
output1.append(outputs.detach().numpy()) # 修改此处
# 将第一个模型的输出作为第二个模型的输入
input2 = torch.tensor(output1).float()
# 定义参数
input_size = output_size
hidden_size = 32
output_size = 2
lr = 0.01
num_epochs = 100
# 训练第二个模型
second_model = SecondModel(input_size, hidden_size, output_size)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(second_model.parameters(), lr=lr, momentum=0.9)
for epoch in range(num_epochs):
epoch_loss, epoch_acc = train(second_model, criterion, optimizer, input2, y)
print('Second Model: Epoch [{}/{}], Loss: {:.4f}, Acc: {:.4f}'.format(epoch+1, num_epochs, epoch_loss, epoch_acc))
# 获取第二个模型的输出
output2 = []
for inputs in input2:
inputs = inputs.unsqueeze(0) # 添加一维
outputs = second_model(inputs)
output2.append(outputs.detach().numpy()) # 修改此处
# 将第二个模型的输出作为每个样本所对应的概率输出
prob = nn.functional.softmax(torch.tensor(output2).transpose(0, 1), dim=2).detach().numpy() # 修改此处
解决Dimension out of range错误的代码修改:
- 在
train函数中,torch.max(outputs, dim=1)的第二个参数改为dim=1。 - 在获取第一个模型的输出时,
output1.append(outputs.detach().numpy())将outputs转换为numpy数组。 - 在获取第二个模型的输出时,
output2.append(outputs.detach().numpy())将outputs转换为numpy数组。 - 在计算softmax时,
torch.tensor(output2).transpose(0, 1)将维度转换为(num_classes, num_samples)。
通过这些修改,代码可以成功运行并输出每个样本所对应的概率。
原文地址: https://www.cveoy.top/t/topic/mC6q 著作权归作者所有。请勿转载和采集!