多模型融合的八分类任务:使用CNN和BiGRU进行特征提取
在训练集、验证集和测试集三个txt文件夹中有如下格式的数据集,每条样本前23位为特征值,最后一位为分类标签,标签共有8个类别,现使用CNN和BiGRU模型并行做为特征提取器,其中输入cnn的输入数据需要将其转化为图片格式,输入BiGRU的数据为原始数据的23位特征值,然后将两提取器的结果进行contact特征融合,再使用全连接层对融合的结果进行八分类,训练过程有训练、验证和测试,使用pytorch写出正确完整的python代码内容:以下是使用PyTorch编写的代码示例,实现了CNN和BiGRU模型的特征提取和融合,以及全连接层进行八分类的训练过程。
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
# 定义CNN模型
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Conv2d(1, 16, kernel_size=3, stride=1, padding=1)
self.relu = nn.ReLU()
self.maxpool = nn.MaxPool2d(kernel_size=2, stride=2)
self.conv2 = nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1)
self.fc1 = nn.Linear(32 * 8 * 8, 256)
def forward(self, x):
x = self.conv1(x)
x = self.relu(x)
x = self.maxpool(x)
x = self.conv2(x)
x = self.relu(x)
x = self.maxpool(x)
x = x.view(x.size(0), -1)
x = self.fc1(x)
return x
# 定义BiGRU模型
class BiGRU(nn.Module):
def __init__(self, input_size, hidden_size, num_layers):
super(BiGRU, self).__init__()
self.hidden_size = hidden_size
self.num_layers = num_layers
self.gru = nn.GRU(input_size, hidden_size, num_layers, batch_first=True, bidirectional=True)
self.fc = nn.Linear(hidden_size*2, 256)
def forward(self, x):
h0 = torch.zeros(self.num_layers*2, x.size(0), self.hidden_size).to(device)
out, _ = self.gru(x, h0)
out = self.fc(out[:, -1, :]) # 取最后一个时刻的输出
return out
# 定义数据集类
class MyDataset(Dataset):
def __init__(self, file_path):
self.data = []
self.labels = []
with open(file_path, 'r') as file:
lines = file.readlines()
for line in lines:
values = line.strip().split(',')
self.data.append([float(v) for v in values[:-1]])
self.labels.append(int(values[-1]))
def __getitem__(self, index):
x = torch.tensor(self.data[index], dtype=torch.float32)
y = torch.tensor(self.labels[index], dtype=torch.long)
return x, y
def __len__(self):
return len(self.data)
# 定义特征融合模型
class FusionModel(nn.Module):
def __init__(self, cnn_model, rnn_model, num_classes):
super(FusionModel, self).__init__()
self.cnn_model = cnn_model
self.rnn_model = rnn_model
self.fc = nn.Linear(512, num_classes)
def forward(self, x, y):
cnn_output = self.cnn_model(x)
rnn_output = self.rnn_model(y)
fused_output = torch.cat((cnn_output, rnn_output), dim=1)
output = self.fc(fused_output)
return output
# 设置设备
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# 定义超参数
num_epochs = 10
batch_size = 32
learning_rate = 0.001
# 加载数据集
train_dataset = MyDataset('训练集.txt')
valid_dataset = MyDataset('验证集.txt')
test_dataset = MyDataset('测试集.txt')
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
valid_loader = DataLoader(valid_dataset, batch_size=batch_size, shuffle=False)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
# 创建模型
cnn_model = CNN().to(device)
rnn_model = BiGRU(input_size=23, hidden_size=128, num_layers=2).to(device)
fusion_model = FusionModel(cnn_model, rnn_model, num_classes=8).to(device)
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(fusion_model.parameters(), lr=learning_rate)
# 训练模型
for epoch in range(num_epochs):
fusion_model.train()
for i, (inputs, labels) in enumerate(train_loader):
inputs = inputs.unsqueeze(1).to(device) # 转换为图片格式,增加通道维度
inputs = inputs.view(inputs.size(0), 1, 23, 1) # 调整图片大小
labels = labels.to(device)
optimizer.zero_grad()
outputs = fusion_model(inputs, inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
if (i+1) % 10 == 0:
print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, i+1, len(train_loader), loss.item()))
# 在验证集上评估模型
fusion_model.eval()
with torch.no_grad():
correct = 0
total = 0
for inputs, labels in valid_loader:
inputs = inputs.unsqueeze(1).to(device)
inputs = inputs.view(inputs.size(0), 1, 23, 1)
labels = labels.to(device)
outputs = fusion_model(inputs, inputs)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
accuracy = 100 * correct / total
print('Validation Accuracy: {:.2f}%'.format(accuracy))
# 在测试集上评估模型
fusion_model.eval()
with torch.no_grad():
correct = 0
total = 0
for inputs, labels in test_loader:
inputs = inputs.unsqueeze(1).to(device)
inputs = inputs.view(inputs.size(0), 1, 23, 1)
labels = labels.to(device)
outputs = fusion_model(inputs, inputs)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
accuracy = 100 * correct / total
print('Test Accuracy: {:.2f}%'.format(accuracy))
请根据实际情况修改文件路径、超参数和模型结构,并根据需要添加必要的数据预处理步骤。
原文地址: http://www.cveoy.top/t/topic/lHqa 著作权归作者所有。请勿转载和采集!