当前位置:   article > 正文

故障检测代码(109cnn文件)_pytorch一维cnn故障诊断代码

pytorch一维cnn故障诊断代码

.109cnn

import os
import torch
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import numpy as np
import sys
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from PIL import Image
from torch.utils.data import Dataset
import scipy.io as io
import random
from datetime import datetime
print(torch.cuda.is_available())  确认版本是否匹配
os.environ["CUDA_VISIBLE_DEVICES"] = "0"  
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")  用cpu
# print(torch.cuda.is_available())
class Net(nn.Module):  定义类(该类要继承nn.Module),在类中实现两个方法:1.初始化函数:实现在搭建网络过程中所需要实现的网络层结构。2.在forward函数中定义正向传播的过程。
    def __init__(self):
        super(Net, self).__init__()  super函数是继承父类的某个函数(理解为先执行父类的某个函数,再执行下面的语句)
        self.conv1 = nn.Conv2d(1, 32, 5, padding=2)  定义卷积层的函数为nn.Conv2d,参数顺序为:深度、卷积核的个数、卷积核的大小,通常情况下步距默认为1,此处运用了补0填充,保证前后图像尺寸相同,卷积处理的都是4维数据,批次处理,输入(4,1,64,64),意思是一次处理4组数据,通道为1,像素为64×64,第一次卷积就是(4,32,64,64),池化为(4,32,32,32),以此类推,4次卷积池化就是(4,256,4,4),卷积层的输出就是全连接层的输入。
        self.conv2 = nn.Conv2d(32, 64, 3, padding=1)
        self.conv3 = nn.Conv2d(64, 128, 3, padding=1)
        self.conv4 = nn.Conv2d(128, 256, 3, padding=1)  一共定义四个卷积层
        self.pool = nn.MaxPool2d(2)  定义下采样层的函数为nn.MaxPool2d,参数顺序为:卷积核大小,步距,padding
        self.fc1 = nn.Linear(4 * 4 * 256, 2560)  定义全连接层的函数为nn.Linear,全连接层的输入是一个一维的向量,因此需要将得到的特征矩阵给展平成一维向量
        self.fc2 = nn.Linear(2560, 2)
        # self.fc2 = nn.Linear(2560, 4)  最后一个全连接层的输出是需要根据自己的分类类别进行更改的,这个2560是自己设置出来的
def forward(self, x):  x代表输入的数据,就是一个tensor

    # print(x.size())
    x = self.pool(F.relu(self.conv1(x)))  将输入经过第一个卷积层,再经过一个relu激活函数,再经过池化,每次的输入输出就是一次卷积池化得到的那个四维数组。
    # print(x.size())
    x = self.pool(F.relu(self.conv2(x)))
    # print(x.size())
    x = self.pool(F.relu(self.conv3(x)))
    # print(x.size())
    x = self.pool(F.relu(self.conv4(x)))
    # print(x.size())
    x = x.view(-1, 4 * 4 * 256)  output(4*4*256) view函数起到的作用是reshape,view的参数的是改变后的shape,-1代表第一个维度(batch)是自动推理的,第二个参数就是展平
    # print(x.size())
    x = F.relu(self.fc1(x)) output(2560)
    # print(x.size())
    x = self.fc2(x)  output(4) 没有接softmax的原因:理论上确实需要,但实际训练网络计算交叉熵时在其内部已经实现了一个更加高效的sofymax方法,所以不需要添加了(内置了)
    # print(x.size())
    return x

这就是一个最简单的模型LeNet网络的model.py文件代码,就包括两个部分,定义网络结构和前向传播。

下面是训练分类网络

PATH = "cnn_net.pth"  
net = Net()
# net.load_state_dict(torch.load(PATH, map_location="cpu"))
net = Net().to(device)  将所有最开始读取数据时的tensor变量copy一份到device所指定的CPU上去,之后的运算都在CPU上进行。
net.load_state_dict(torch.load(PATH))   
print("load success")
criterion = nn.CrossEntropyLoss()  定义损失函数,其内部已经内置了softmax,多分类问题,用交叉熵损失函数
optimizer = optim.SGD(net.parameters(), lr=0.01, momentum=0.9)  定义优化器,参数一:所需要训练的参数(这里把网络中所有可训练的参数都进行训练);参数二:学习率

train_pics_dict = np.load("train_pics.npz")  加载上一个文件中已经保存的数据
train_labels_dict = np.load("train_labels.npz")
test_pics_dict = np.load("test_pics.npz")
test_labels_dict = np.load("test_labels.npz")
print(test_labels_dict["arr_" + str(3000)])   
train_pics = []   这里的空列表就是为了把前面储存再文件中的数据集拿出来,把数放进去
train_labels = []
test_pics = []
test_labels = []
for i in train_pics_dict.files:  增强数据,把数据变多
    train_pics.append(train_pics_dict[i])
    train_labels.append(int(train_labels_dict[i]))
for i in test_pics_dict.files:
    test_pics.append(test_pics_dict[i])
    test_labels.append(int(test_labels_dict[i]))
print(test_labels)  结果全为0
class MyData(Dataset):  定义自己的数据集
    def __init__(self, pics, labels):  初始化数据集
        self.pics = pics
        self.labels = labels
def __getitem__(self, index):  返回编号index的数据
    # print(index)
    # print(len(self.pics))
    assert index < len(self.pics)
    return torch.Tensor([self.pics[index]]), self.labels[index]
def __len__(self):
    return len(self.pics)  返回数据集总长度
def get_tensors(self):  Tensors对模型以及模型参数的输入和输出进行编码
    return torch.Tensor([self.pics]), torch.Tensor(self.labels)   
def main(argv=None):
classes = ["normal", "error"]
# 加载训练数据库

trainset = MyData(train_pics, train_labels)
trainloader = torch.utils.data.DataLoader(
    trainset, batch_size=4, shuffle=True, num_workers=2
)  

testset = MyData(test_pics, test_labels)
testloader = torch.utils.data.DataLoader(
    testset, batch_size=4, shuffle=True, num_workers=2
)  

batch_size:(数据类型 int)

每次输入数据的行数,默认为1。PyTorch训练模型时调用数据不是一行一行进行的(这样太没效率),而是一捆一捆来的。这里就是定义每次喂给神经网络多少行数据,如果设置成1,那就是一行一行进行(个人偏好,PyTorch默认设置是1)。

shuffle:(数据类型 bool)

洗牌。默认设置为False。在每次迭代训练时是否将数据洗牌,默认设置是False。将输入数据的顺序打乱,是为了使数据更有独立性,但如果数据是有序列特征的,就不要设置成True了。

num_workers:(数据类型 Int)

工作者数量,默认是0。使用多少个子进程来导入数据。设置为0,就是使用主进程来导入数据。注意:这个数字必须是大于等于0的,负数估计会出错。

for epoch in range(10):
    running_loss = 0  用来累加在训练过程中的损失
    for i, data in enumerate(trainloader):  遍历训练集样本 enumerate() 函数返回数据和数据下标
        inputs, labels = data  将数据分离成输入的图像和其所对应的标签
        inputs = inputs.cuda()  
        labels = labels.cuda()
        outputs = net(inputs)  正向传播得到输出
        loss = criterion(outputs, labels)  用定义的函数计算损失,参数为:网络预测的值,输入图片对应的真实标签
        optimizer.zero_grad()  梯度初始化为零,把loss关于weight的导数变成0
        loss.backward()  将loss进行反向传播
        optimizer.step()  进行参数的更新

#输出训练过程

 running_loss += loss  每计算一个loss就将其追加到变量中
    if i % 2000 == 1999:  每隔2000步打印一次数据
        print(
            "epoch:",  输出第{}个epoch
            epoch,
            "[",
            i - 1999,
            ":",
            i,
            "] loss:",
            running_loss.item() / 2000,  输出目前的训练损失loss
        )
        running_loss = 0
PATH = "cnn_net.pth"
torch.save(net.state_dict(), PATH)
print("save success")

训练分类网络代码结束,这就叫训练模型

下面是测试模型过程

correct = 0
total = 0
with torch.no_grad():  在该模块下,所有计算得出的tensor的requires_grad都自动设置为False,当requires_grad设置为False时,反向传播时就不会自动求导了,因此大大节约了显存或者说内存
    for inputs, labels in testloader:
        inputs = inputs.cuda()
        labels = labels.cuda()
        outputs = net(inputs)
        _, predicts = torch.max(outputs, 1)
        total += 4
        correct += (predicts == labels).sum().item()
print(correct / total * 100)

参考:

(1条消息) 深度学习之pytorch常用函数个人笔记_@会飞的毛毛虫的博客-CSDN博客​​​​​​(2条消息) 【PyTorch】从头搭建并训练一个神经网络模型(图像分类、CNN)_sin(豪)的博客-CSDN博客_搭建神经网络模型

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/776220
推荐阅读
相关标签
  

闽ICP备14008679号