在序列数据分类任务中,一维卷积神经网络(1D-CNN)因其对局部特征的高效提取能力而被广泛应用。本文介绍一种简单高效的序列分类模型 SCCAN(Simple Convolutional Classifier for Attribute Networks),基于 PyTorch 实现完整的训练、评估与结果保存流程,适用于时间序列、特征序列等数据的多分类任务。
对应代码和数据链接:https://download.csdn.net/download/lestatlu/90691726
class SCCAN(nn.Module):
def __init__(self, input_dim, num_classes):
super(SCCAN, self).__init__()
self.conv1 = nn.Conv1d(1, 16, kernel_size=3, padding=1)
self.conv2 = nn.Conv1d(16, 32, kernel_size=3, padding=1)
self.conv3 = nn.Conv1d(32, 64, kernel_size=3, padding=1)
self.conv4 = nn.Conv1d(64, 128, kernel_size=3, padding=1)
self.conv5 = nn.Conv1d(128, 256, kernel_size=3, padding=1)
self.pool = nn.MaxPool1d(2)
self.global_avg_pool = nn.AdaptiveAvgPool1d(1)
self.fc1 = nn.Linear(256, 256)
self.fc2 = nn.Linear(256, num_classes)
self.dropout = nn.Dropout(0.5)
def forward(self, x):
x = F.relu(self.conv1(x))
x = self.pool(F.relu(self.conv2(x)))
x = self.pool(F.relu(self.conv3(x)))
x = self.pool(F.relu(self.conv4(x)))
x = F.relu(self.conv5(x))
x = self.global_avg_pool(x).squeeze(-1) # 全局平均池化
x = F.relu(self.fc1(x))
x = self.dropout(x)
x = self.fc2(x)
return x
# 加载全局数据(请将路径替换为你的数据存储路径)
X_all_samples = np.load(r'your_path\X_all_samples.npy')
y_all_samples = np.load(r'your_path\y_all_samples.npy')
train_indices = np.load(r'your_path\global_train_indices.npy')
test_indices = np.load(r'your_path\global_test_indices.npy')
# 划分训练集与测试集
X_train = X_all_samples[train_indices]
y_train = y_all_samples[train_indices]
X_test = X_all_samples[test_indices]
y_test = y_all_samples[test_indices]
# 确定类别数
num_classes = np.max(y_train) + 1
# 转换为Tensor并添加通道维度(1D-CNN输入需为[batch, channels, sequence_length])
x_train = torch.tensor(X_train[:, np.newaxis, :], dtype=torch.float32, device=device)
x_test = torch.tensor(X_test[:, np.newaxis, :], dtype=torch.float32, device=device)
y_train = torch.tensor(y_train, dtype=torch.long, device=device)
y_test = torch.tensor(y_test, dtype=torch.long, device=device)
# 创建数据加载器(支持批量训练)
train_loader = DataLoader(TensorDataset(x_train, y_train), batch_size=32, shuffle=True)
test_loader = DataLoader(TensorDataset(x_test, y_test), batch_size=32, shuffle=False)
np.newaxis
添加通道维度(从 [N, D] 到 [N, 1, D]),适配一维卷积输入DataLoader
实现批量处理,训练集随机打乱顺序提升泛化性n_epochs = 1000 # 训练轮次
lr = 0.001 # 学习率
batch_size = 32 # 批量大小
device = 'cuda' if torch.cuda.is_available() else 'cpu' # 自动选择设备
model = SCCAN(input_dim=x_train.shape[2], num_classes=num_classes).to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=lr)
for epoch in range(n_epochs):
model.train()
running_loss = 0.0
for inputs, labels in train_loader:
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
# 每100轮打印平均损失
if (epoch + 1) % 100 == 0:
avg_loss = running_loss / len(train_loader)
print(f"Epoch [{epoch+1}/{n_epochs}], Loss: {avg_loss:.4f}")
DataLoader
实现 mini-batch 训练from sklearn.metrics import accuracy_score, recall_score, precision_score, cohen_kappa_score
def evaluate_to_dataframe(y_true, y_pred, method_name):
oa = accuracy_score(y_true, y_pred) * 100 # 总体精度
aa = recall_score(y_true, y_pred, average='macro') * 100 # 宏平均召回率
pa = precision_score(y_true, y_pred, average=None) * 100 # 各类别精度
kappa = cohen_kappa_score(y_true, y_pred) # Kappa系数
metrics_dict = {
'Method': method_name,
'OA (%)': oa,
'AA (%)': aa,
'Kappa': kappa,
}
for i, precision in enumerate(pa):
metrics_dict[f'PA_Class_{i} (%)'] = round(precision, 2)
print(f"\n[{method_name}] Metrics:")
print(f"OA: {oa:.2f}%, AA: {aa:.2f}%, Kappa: {kappa:.4f}")
print(classification_report(y_true, y_pred))
return metrics_dict
model.eval()
y_true, y_pred = [], []
with torch.no_grad():
for inputs, labels in test_loader:
outputs = model(inputs)
_, predicted = torch.max(outputs, 1)
y_true.extend(labels.cpu().numpy())
y_pred.extend(predicted.cpu().numpy())
test_metrics = evaluate_to_dataframe(y_true, y_pred, "SCCAN")
metrics_df = pd.DataFrame([test_metrics])
metrics_df.to_excel('SCCAN.xlsx', index=False, float_format="%.2f")
print("Test results saved to 'SCCAN.xlsx'.")
# 设备选择
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")
start = time.time()
# 数据加载与预处理(见前文)
# 模型定义(见前文)
# 训练循环(见前文)
# 结果评估与保存(见前文)
# 计时输出
end = time.time()
print(f"Total training time: {end - start:.2f} seconds")
pip install torch pandas scikit-learn numpy
your_path
目录SCCAN.xlsx
参数 | 作用 | 建议范围 |
---|---|---|
batch_size |
批量大小 | 16/32/64 |
n_epochs |
训练轮次 | 500-2000 |
dropout |
随机失活率 | 0.3-0.7 |
kernel_size |
卷积核大小 | 3/5/7 |
本文通过 SCCAN 模型演示了一维卷积神经网络在序列分类中的完整应用流程,重点包括:
SCCAN 模型通过简单的卷积 - 池化 - 全连接结构,在保证精度的同时保持高效性。实际应用中,可通过调整卷积层数、通道数或添加注意力机制进一步优化性能。完整代码支持一键运行,适用于快速验证序列分类任务的基线模型。
结果展示:
对应代码和数据链接:https://download.csdn.net/download/lestatlu/90691726
请大家多多关注