使用pytorch对一维数据实现简单多分类

使用pytorch对一维数据实现简单多分类

    Pytorch 是目前最好用的神经网络库之一,最近我写了一个pytorch的简单代码,在这里对其做一个全面的介绍。

    在pytorch 中一些常用的功能都已经被封装成了模块,所以我们只需要继承并重写部分函数即可。首先介绍一下本文最终希望实现的目标, 对本地的一维数据 (1xn)的ndarry 进行一个多分类,数据集为mn的数据,标签为m1的数组。下面是结合代码记录一下踩坑过程。

    1. 继承Dataset类,可以看到我这里重写了三个函数,init 函数用于载入numpy数据并将其转化为相应的tensor,__gititem__函数用于定义训练时会返回的单个数据与标签,__len__表示数据数量m。
    class MyDataSet(torch.utils.data.Dataset):
         def __init__(self, data, label):
             self.data = torch.from_numpy(data).float()
             self.label = torch.from_numpy(label)
             self.length = label.shape[0]
         def __getitem__(self, index):
             return self.data[index], self.label[index]
         def __len__(self):
             return self.length
    
    1. 通过继承nn.Module来自定义神经网络

      其中__init__函数来自定义定义我们需要的网络参数,这里我们block1 的in_channels为1,输出参数可根据需要自己设定,但而且当前层的输出channel应该和下一层的输入channel相同,
    注意:MaxPool1d的inchannel需要自己计算一下,当然如果你不想算,可以给个参数直接运行,看报错信息的提示
      __forward__ 函数定义了网络的连接方式,注意此处应返回x。

    class NeuralNetwork(nn.Module):
      def __init__(self):
          super(NeuralNetwork, self).__init__()
          self.block1 = nn.Sequential(
              nn.Conv1d(in_channels=filter_num[0], out_channels=filter_num[1], padding='same', stride=conv_stride_size,
                        kernel_size=conv_kernel_size, dtype=dtype),
              nn.BatchNorm1d(filter_num[1],dtype=dtype),
              nn.ReLU(),
              nn.Conv1d(filter_num[1], filter_num[1], kernel_size=conv_kernel_size, stride=conv_stride_size, padding='same',dtype=dtype),
              nn.BatchNorm1d(filter_num[1],dtype=dtype),
              nn.ReLU(),
              nn.MaxPool1d(kernel_size=pool_kernel_size, stride=pool_stride, padding=pool_padding),
              nn.Dropout(drop_float),
          )
          self.block2=nn.Sequential(
              nn.Conv1d(in_channels=filter_num[1],out_channels=filter_num[2], padding='same', stride=conv_stride_size,
                        kernel_size=conv_kernel_size, dtype=dtype),
              nn.BatchNorm1d(num_features=filter_num[2],dtype=dtype),
              nn.ReLU(),
              nn.Conv1d(filter_num[2],filter_num[2],kernel_size=conv_kernel_size,stride=conv_stride_size,
                        padding='same',dtype=dtype),
              nn.BatchNorm1d(filter_num[2],dtype=dtype),
              nn.ReLU(),
              nn.MaxPool1d(kernel_size=pool_kernel_size, stride=pool_stride,padding=pool_padding),
              nn.Dropout(drop_float),
          )
          self.block3=nn.Sequential(
              nn.Conv1d(in_channels=filter_num[2],out_channels=filter_num[3], padding='same', stride=conv_stride_size,
                        kernel_size=conv_kernel_size, dtype=dtype),
              nn.BatchNorm1d(num_features=filter_num[3],dtype=dtype),
              nn.ReLU(),
              nn.Conv1d(filter_num[3],filter_num[3],kernel_size=conv_kernel_size,stride=conv_stride_size,
                        padding='same',dtype=dtype),
              nn.BatchNorm1d(filter_num[3],dtype=dtype),
              nn.ReLU(),
              nn.MaxPool1d(kernel_size=pool_kernel_size, stride=pool_stride,padding=pool_padding),
              nn.Dropout(drop_float),
          )
          self.block4=nn.Sequential(
              nn.Conv1d(in_channels=filter_num[3],out_channels=filter_num[4], padding='same', stride=conv_stride_size,
                        kernel_size=conv_kernel_size, dtype=dtype),
              nn.BatchNorm1d(num_features=filter_num[4],dtype=dtype),
              nn.ReLU(),
              nn.Conv1d(filter_num[4],filter_num[4],kernel_size=conv_kernel_size,stride=conv_stride_size,
                        padding='same',dtype=dtype),
              nn.BatchNorm1d(filter_num[4],dtype=dtype),
              nn.ReLU(),
              nn.MaxPool1d(kernel_size=pool_kernel_size, stride=pool_stride,padding=pool_padding),
              nn.Dropout(drop_float),
          )
          self.connected = nn.Sequential(
              nn.Flatten(),
              nn.BatchNorm1d(num_features=1280 ,dtype=dtype),
              nn.ReLU(),
              nn.Dropout(0.7),
              nn.Flatten(),
              nn.BatchNorm1d(num_features=1280 ,dtype=dtype),
              nn.ReLU(),
              nn.Dropout(0.5),
              nn.Linear(1280, 180,dtype=dtype)
          )
      def forward(self, x):
          x = self.block1(x)
          x= self.block2(x)
          x= self.block3(x)
          x= self.block4(x)
          x = self.connected(x)
          return x
    
    1. 主程序。为了更好的说明,先放一下主程序。这里的程序是已经载入了数据的,data是mn 数组,label为m1数组。
      实例化DataLoader的第一个参数是Dataset的实例,通过DataLoader,其功能是为下文训练和测试过程提供数据。
        print("data loading ...")
        train_data_set = MyDataSet(trainingDataLoadProcess.data, trainingDataLoadProcess.label)
        test_data_set = MyDataSet(testDataLoadProcess.data, testDataLoadProcess.label)
        train_dataloader = DataLoader(train_data_set, batch_size=batch_size, shuffle=shuffle)
        test_dataloader = DataLoader(test_data_set, batch_size=batch_size, shuffle=shuffle)
        print("model constructing...")
        model_test = NeuralNetwork()
        loss_fn = nn.CrossEntropyLoss()
        optimizer = torch.optim.Adamax(model_test.parameters(), lr=learning_rate, betas=(beta_1, beta_2), weight_decay=0.0)
        print(model_test)
        for t in range(epochs):
            print(f'Epoch{t + 1}\n-------------') 
            train_loop(train_dataloader, model_test, loss_fn, optimizer)
            test_loop(test_dataloader, model_test, loss_fn)
        print("Done!")
    
    1. 定义训练阶段,从DataLoader中取出数据,这里X,y分别为batch_sizen,batch_size1的数据。
      首先要进行一个调整,将X调整为batch_size1n的float,设置float的转化过程放在Dataset的初始化函数里完成了
      注意:如果没有这一步会报错

    期望是long但得到了float的错误。(虽然我也不明白为啥错误不是期望float...)

    y为1*batch的数组并转化成long(这里y的形式可能与损失函数有关)

    def train_loop(dataloader, model, loss_fn, optimizer):
        size = len(dataloader.dataset)
        for batch, (X, y) in enumerate(dataloader):
            X = X.unsqueeze(1)
            y=y.squeeze(1).long()
            pred = model(X)
            loss = loss_fn(pred, y)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
    
    1. 定义测试过程(同上)
    def test_loop(dataloader, model, loss_fn):
        size = len(dataloader.dataset)
        num_batches = len(dataloader)
        test_loss, correct = 0, 0
        with torch.no_grad():
            for X, y in dataloader:
                X = X.unsqueeze(1)
                y=y.squeeze(1).long()
                pred = model(X)
                test_loss = loss_fn(pred, y).item()
                correct += (pred.argmax(1) == y).type(torch.float).sum().item()
        test_loss /= num_batches
        correct /= size
    

    大体流程就是这些,最后记得修改加入输出语句与保存模型等操作。

    posted @   非典型废物  阅读(4698)  评论(0编辑  收藏  举报
    编辑推荐:
    · AI与.NET技术实操系列(二):开始使用ML.NET
    · 记一次.NET内存居高不下排查解决与启示
    · 探究高空视频全景AR技术的实现原理
    · 理解Rust引用及其生命周期标识(上)
    · 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
    阅读排行:
    · DeepSeek 开源周回顾「GitHub 热点速览」
    · 物流快递公司核心技术能力-地址解析分单基础技术分享
    · .NET 10首个预览版发布:重大改进与新特性概览!
    · AI与.NET技术实操系列(二):开始使用ML.NET
    · 单线程的Redis速度为什么快?
    点击右上角即可分享
    微信分享提示