基于CNN和BiGRU的特征融合模型用于多分类任务
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
# 定义CNN模型
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Conv2d(1, 16, kernel_size=3)
self.conv2 = nn.Conv2d(16, 32, kernel_size=3)
self.fc1 = nn.Linear(32 * 6 * 6, 128)
def forward(self, x):
x = x.unsqueeze(1) # 将输入数据转换为图片格式,添加一个通道维度
x = F.relu(self.conv1(x))
x = F.max_pool2d(x, 2)
x = F.relu(self.conv2(x))
x = F.max_pool2d(x, 2)
x = x.view(-1, 32 * 6 * 6)
x = F.relu(self.fc1(x))
return x
# 定义BiGRU模型
class BiGRU(nn.Module):
def __init__(self, input_size, hidden_size, num_layers):
super(BiGRU, self).__init__()
self.gru = nn.GRU(input_size, hidden_size, num_layers, batch_first=True, bidirectional=True)
def forward(self, x):
_, h = self.gru(x)
h = h.permute(1, 0, 2).contiguous().view(x.size(0), -1)
return h
# 定义融合模型
class FusionModel(nn.Module):
def __init__(self, input_size):
super(FusionModel, self).__init__()
self.cnn = CNN()
self.gru = BiGRU(input_size, 64, 2)
self.fc = nn.Linear(128 + 128, 8)
def forward(self, x):
img_data = x[:, :23] # 提取图片数据的特征
seq_data = x[:, 23:] # 提取序列数据的特征
img_feat = self.cnn(img_data)
seq_feat = self.gru(seq_data)
feat = torch.cat((img_feat, seq_feat), dim=1) # 进行特征融合
output = self.fc(feat)
return output
# 读取数据集
def load_dataset(file_path):
dataset = []
with open(file_path, 'r') as f:
lines = f.readlines()
for line in lines:
line = line.strip().split(',')
features = list(map(float, line[:-1]))
label = int(line[-1])
dataset.append((features, label))
return dataset
# 数据预处理
def preprocess_data(dataset):
max_value = np.max(dataset, axis=0)
min_value = np.min(dataset, axis=0)
dataset = (dataset - min_value) / (max_value - min_value) # 归一化
return dataset
# 划分数据集
def split_dataset(dataset, train_ratio, valid_ratio):
train_size = int(len(dataset) * train_ratio)
valid_size = int(len(dataset) * valid_ratio)
train_data = dataset[:train_size]
valid_data = dataset[train_size:train_size+valid_size]
test_data = dataset[train_size+valid_size:]
return train_data, valid_data, test_data
# 将数据集转换为张量
def convert_to_tensor(dataset):
features, labels = zip(*dataset)
features = torch.tensor(features, dtype=torch.float32)
labels = torch.tensor(labels, dtype=torch.long)
return features, labels
# 训练模型
def train(model, train_loader, valid_loader, criterion, optimizer, num_epochs):
for epoch in range(num_epochs):
model.train()
train_loss = 0.0
for inputs, labels in train_loader:
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
train_loss += loss.item() * inputs.size(0)
# 在验证集上评估模型
model.eval()
valid_loss = 0.0
valid_acc = 0.0
with torch.no_grad():
for inputs, labels in valid_loader:
outputs = model(inputs)
loss = criterion(outputs, labels)
valid_loss += loss.item() * inputs.size(0)
_, preds = torch.max(outputs, 1)
valid_acc += torch.sum(preds == labels.data)
train_loss = train_loss / len(train_loader.dataset)
valid_loss = valid_loss / len(valid_loader.dataset)
valid_acc = valid_acc / len(valid_loader.dataset)
print(f'Epoch {epoch+1}/{num_epochs}, Train Loss: {train_loss:.4f}, Valid Loss: {valid_loss:.4f}, Valid Acc: {valid_acc.item()*100:.2f}%')
# 测试模型
def test(model, test_loader):
model.eval()
test_acc = 0.0
with torch.no_grad():
for inputs, labels in test_loader:
outputs = model(inputs)
_, preds = torch.max(outputs, 1)
test_acc += torch.sum(preds == labels.data)
test_acc = test_acc / len(test_loader.dataset)
print(f'Test Acc: {test_acc.item()*100:.2f}%')
# 设置超参数
batch_size = 32
learning_rate = 0.001
num_epochs = 10
# 加载并预处理数据集
dataset = load_dataset('data.txt')
dataset = preprocess_data(dataset)
# 划分数据集
train_data, valid_data, test_data = split_dataset(dataset, 0.7, 0.1)
# 转换为张量
train_features, train_labels = convert_to_tensor(train_data)
valid_features, valid_labels = convert_to_tensor(valid_data)
test_features, test_labels = convert_to_tensor(test_data)
# 创建数据加载器
train_dataset = torch.utils.data.TensorDataset(train_features, train_labels)
valid_dataset = torch.utils.data.TensorDataset(valid_features, valid_labels)
test_dataset = torch.utils.data.TensorDataset(test_features, test_labels)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
valid_loader = torch.utils.data.DataLoader(valid_dataset, batch_size=batch_size)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size)
# 创建模型并定义损失函数和优化器
model = FusionModel(23)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
# 训练模型
train(model, train_loader, valid_loader, criterion, optimizer, num_epochs)
# 测试模型
test(model, test_loader)
请注意,上述代码中的模型结构和超参数可能需要根据实际情况进行调整。
原文地址: https://www.cveoy.top/t/topic/lHFE 著作权归作者所有。请勿转载和采集!