Python,Pytorch使用1D CNN-SVM,对一维信号分类源程序。工作如下:
1、加载数据,正常和异常分别为200条一维信号,数据长度为500,原始数据为Excel。
2、构建数据集,并随机划分训练集(80%)、测试集(20%)。
3、搭建CNN网络,训练。
4、训练好模型后,使用训练好的CNN提取特征。将训练集、测试集样本分别输入CNN,每个样本取出16个特征,视为CNN提取的特征。
5、用训练集特征训练SVM。
6、用测试集特征测试SVM,计算Acc、Pre、Recall、F1-score,绘制混淆矩阵。
注:程序没有画训练集acc和loss曲线,需要自己补充。原始数据为excel,可替换为自己的数据。
项目介绍:基于1D CNN-SVM的一维信号分类
项目名称
1D CNN-SVM for One-Dimensional Signal Classification
项目概述
本项目旨在使用PyTorch框架结合一维卷积神经网络(1D CNN)和支持向量机(SVM)对一维信号进行分类。项目包括数据加载、数据集构建、模型训练、特征提取、SVM训练与测试等步骤。通过这种方法,可以有效地利用CNN的特征提取能力,并结合SVM的分类性能,实现高精度的信号分类。
项目特点
- 端到端处理:从数据加载到最终分类结果的全过程。
- 混合模型:结合了1D CNN的强大特征提取能力和SVM的高效分类性能。
- 数据集划分:随机划分训练集和测试集,确保模型的泛化能力。
- 评估指标:计算准确率(Accuracy)、精确率(Precision)、召回率(Recall)和F1分数,并绘制混淆矩阵。
- 可扩展性:用户可以轻松替换自己的数据,并根据需要调整参数。
项目结构
1D_CNN_SVM_Signal_Classification/
├── main.py # 主程序
├── data/ # 数据文件夹
│ ├── normal_signals.xlsx # 正常信号数据
│ └── abnormal_signals.xlsx # 异常信号数据
├── models/ # 模型文件夹
│ └── cnn_model.pth # 训练好的CNN模型
└── README.md # 项目说明文档
数据格式
- 原始数据:正常和异常信号分别保存在两个Excel文件中,每个文件包含200条一维信号,每条信号长度为500。
- 类别信息:正常信号标记为0,异常信号标记为1。
项目工作流程
- 加载数据:从Excel文件中读取正常和异常信号数据。
- 构建数据集:将数据转换为适合PyTorch的数据集,并随机划分训练集(80%)和测试集(20%)。
- 搭建CNN网络:定义1D CNN模型并进行训练。
- 特征提取:使用训练好的CNN模型提取训练集和测试集的特征。
- SVM训练:用提取的特征训练SVM分类器。
- SVM测试:用测试集特征测试SVM分类器,计算评估指标并绘制混淆矩阵。
代码示例
1. 主程序 main.py
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
# 1. 加载数据
def load_data(normal_file, abnormal_file):
normal_df = pd.read_excel(normal_file)
abnormal_df = pd.read_excel(abnormal_file)
normal_signals = normal_df.values
abnormal_signals = abnormal_df.values
X = np.vstack((normal_signals, abnormal_signals))
y = np.hstack((np.zeros(len(normal_signals)), np.ones(len(abnormal_signals))))
return X, y
# 2. 构建数据集
def create_dataset(X, y):
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
train_dataset = TensorDataset(torch.tensor(X_train, dtype=torch.float32), torch.tensor(y_train, dtype=torch.long))
test_dataset = TensorDataset(torch.tensor(X_test, dtype=torch.float32), torch.tensor(y_test, dtype=torch.long))
return train_dataset, test_dataset
# 3. 搭建CNN网络
class Simple1DCNN(nn.Module):
def __init__(self):
super(Simple1DCNN, self).__init__()
self.conv1 = nn.Conv1d(1, 16, kernel_size=3, stride=1, padding=1)
self.relu = nn.ReLU()
self.pool = nn.MaxPool1d(kernel_size=2, stride=2)
self.fc1 = nn.Linear(16 * 250, 128)
self.fc2 = nn.Linear(128, 16)
def forward(self, x):
x = self.conv1(x)
x = self.relu(x)
x = self.pool(x)
x = x.view(-1, 16 * 250)
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
# 4. 训练CNN
def train_cnn(train_loader, model, criterion, optimizer, num_epochs=10):
model.train()
for epoch in range(num_epochs):
for inputs, labels in train_loader:
inputs = inputs.unsqueeze(1) # 增加通道维度
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
# 5. 提取特征
def extract_features(dataloader, model):
model.eval()
features = []
labels = []
with torch.no_grad():
for inputs, targets in dataloader:
inputs = inputs.unsqueeze(1)
outputs = model(inputs)
features.append(outputs.numpy())
labels.append(targets.numpy())
return np.vstack(features), np.hstack(labels)
# 6. 训练SVM
def train_svm(X_train, y_train):
svm = SVC(kernel='linear')
svm.fit(X_train, y_train)
return svm
# 7. 测试SVM
def test_svm(svm, X_test, y_test):
y_pred = svm.predict(X_test)
acc = accuracy_score(y_test, y_pred)
pre = precision_score(y_test, y_pred)
rec = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)
cm = confusion_matrix(y_test, y_pred)
return acc, pre, rec, f1, cm
# 主程序
if __name__ == "__main__":
# 1. 加载数据
X, y = load_data('data/normal_signals.xlsx', 'data/abnormal_signals.xlsx')
# 2. 构建数据集
train_dataset, test_dataset = create_dataset(X, y)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)
# 3. 搭建CNN网络
model = Simple1DCNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 4. 训练CNN
train_cnn(train_loader, model, criterion, optimizer, num_epochs=10)
# 5. 提取特征
X_train_features, y_train = extract_features(train_loader, model)
X_test_features, y_test = extract_features(test_loader, model)
# 6. 训练SVM
svm = train_svm(X_train_features, y_train)
# 7. 测试SVM
acc, pre, rec, f1, cm = test_svm(svm, X_test_features, y_test)
# 输出结果
print(f'Accuracy: {acc:.4f}')
print(f'Precision: {pre:.4f}')
print(f'Recall: {rec:.4f}')
print(f'F1 Score: {f1:.4f}')
print('Confusion Matrix:')
print(cm)
使用说明
- 准备数据:将你的正常和异常信号数据分别保存在
data/normal_signals.xlsx
和data/abnormal_signals.xlsx
中,每条信号长度为500。 - 修改路径:如果数据文件路径不同,请相应修改
load_data
函数中的文件路径。 - 运行主程序:在Python环境中运行
main.py
脚本。 - 检查输出:查看控制台输出的评估指标和混淆矩阵。
注意事项
- 数据格式:确保你的信号数据格式正确,且每条信号长度一致。
- 超参数调整:根据实际情况调整CNN的层数、卷积核大小、学习率等超参数。
- 模型保存:如果需要保存训练好的CNN模型,可以在训练结束后使用
torch.save(model.state_dict(), 'models/cnn_model.pth')
。 - 训练曲线:可以通过记录每个epoch的损失值和准确率来绘制训练曲线,这部分代码需要自行添加。
通过上述步骤,你可以轻松地使用1D CNN-SVM对一维信号进行分类,并获得详细的评估指标。希望这个项目能帮助你更好地理解和应用深度学习技术。