用pytorch写一段代码:以西储大学CWRU轴承故障的振动信号数据库作为模型的训练集,故障类型标签包括:正常、内圈故障、外圈故障和滚动体故障四类。首先将一维故障信号转换为二维灰度图作为CNN模型的输...
时间: 2024-05-07 10:19:01 浏览: 152
以下是一份使用PyTorch实现将CWRU轴承故障信号转换为二维灰度图以及使用CNN模型进行分类的代码:
```python
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
# 加载CWRU轴承故障信号数据集
data = np.load('cwru_fault_dataset.npy', allow_pickle=True)
# 将故障信号转换为灰度图
data_gray = []
for signal in data:
# 将一维信号转换为二维灰度图
# 这里可以尝试不同的转换方法,比如使用小波变换等
img = np.expand_dims(signal, axis=1)
img = np.tile(img, (1, 256))
data_gray.append(img)
# 标签映射表
label_map = {
'normal': 0,
'inner_race_fault': 1,
'outer_race_fault': 2,
'roller_fault': 3
}
# 将标签转换为数字编码
labels = [label_map[item['label']] for item in data]
# 将数据集划分为训练集和测试集
train_data = data_gray[:800]
train_labels = labels[:800]
test_data = data_gray[800:]
test_labels = labels[800:]
# 定义CNN模型
class CNNModel(nn.Module):
def __init__(self):
super(CNNModel, self).__init__()
self.conv1 = nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1)
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1)
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
self.fc1 = nn.Linear(128 * 32 * 32, 256)
self.fc2 = nn.Linear(256, 4)
self.dropout = nn.Dropout(0.5)
self.relu = nn.ReLU()
def forward(self, x):
x = self.conv1(x)
x = self.relu(x)
x = self.pool(x)
x = self.conv2(x)
x = self.relu(x)
x = self.pool(x)
x = self.conv3(x)
x = self.relu(x)
x = self.pool(x)
x = x.view(-1, 128 * 32 * 32)
x = self.fc1(x)
x = self.relu(x)
x = self.dropout(x)
x = self.fc2(x)
return x
# 定义训练函数
def train(model, train_data, train_labels, optimizer, criterion, device):
model.train()
train_loss = 0
train_acc = 0
for i in range(len(train_data)):
data = torch.tensor(train_data[i], dtype=torch.float32).unsqueeze(0).to(device)
label = torch.tensor(train_labels[i], dtype=torch.long).unsqueeze(0).to(device)
optimizer.zero_grad()
output = model(data)
loss = criterion(output, label)
loss.backward()
optimizer.step()
train_loss += loss.item()
train_acc += (output.argmax(dim=1) == label).sum().item()
train_loss /= len(train_data)
train_acc /= len(train_data)
return train_loss, train_acc
# 定义测试函数
def test(model, test_data, test_labels, criterion, device):
model.eval()
test_loss = 0
test_acc = 0
with torch.no_grad():
for i in range(len(test_data)):
data = torch.tensor(test_data[i], dtype=torch.float32).unsqueeze(0).to(device)
label = torch.tensor(test_labels[i], dtype=torch.long).unsqueeze(0).to(device)
output = model(data)
loss = criterion(output, label)
test_loss += loss.item()
test_acc += (output.argmax(dim=1) == label).sum().item()
test_loss /= len(test_data)
test_acc /= len(test_data)
return test_loss, test_acc
# 设置超参数
epochs = 50
batch_size = 16
lr = 0.001
device = 'cuda' if torch.cuda.is_available() else 'cpu'
# 初始化模型、优化器和损失函数
model = CNNModel().to(device)
optimizer = optim.Adam(model.parameters(), lr=lr)
criterion = nn.CrossEntropyLoss()
# 记录训练过程中的损失和准确率
train_losses = []
train_accs = []
test_losses = []
test_accs = []
# 训练模型
for epoch in range(epochs):
print('Epoch {}/{}'.format(epoch + 1, epochs))
train_loss, train_acc = train(model, train_data, train_labels, optimizer, criterion, device)
test_loss, test_acc = test(model, test_data, test_labels, criterion, device)
train_losses.append(train_loss)
train_accs.append(train_acc)
test_losses.append(test_loss)
test_accs.append(test_acc)
print('Train Loss: {:.4f}, Train Acc: {:.4f}'.format(train_loss, train_acc))
print('Test Loss: {:.4f}, Test Acc: {:.4f}'.format(test_loss, test_acc))
# 绘制训练过程中的损失和准确率曲线
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.plot(train_losses, label='train')
plt.plot(test_losses, label='test')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.subplot(1, 2, 2)
plt.plot(train_accs, label='train')
plt.plot(test_accs, label='test')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.show()
```
需要注意的是,这份代码只是示例,实际应用中需要根据数据集的特点和实际需求进行相应的调整和优化。例如,可以尝试不同的数据增强方法、模型结构、超参数等。
阅读全文