超简单!用pytorch训练自己的数据集

在pytorch官网上的tutoral中,教程给了一个例子,训练一个分类器,下载CIFAR10数据集,用一个简单的CNNC网络训练模型。在我们下载的CIFAR10数据集中,已标签的数据被打包并封装在data文件夹里。

我们可以在这个例子的基础上,把自己的数据放到其模型下,并实现一个简易的分类器。

首先是配置pytorch的各种环境,有很多教程的,他们讲的又详细又好,我就不多讲啦。

先导入各种模块

#encoding=utf-8
import torch
import torchvision
import torchvision.transforms as transforms
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
import torch.optim as optim  
import matplotlib.pyplot as plt
import numpy as np

如果报错就是各种库各种包没有配好。没有报错就进行下一步啦

首先定义我们的训练数据。我们采用的是ImageFolder函数。将我们要训练的数据放在一个路径为path的文件夹下,假如这个文件夹名为train。在我们的train文件夹下有N个子文件夹,每个子文件夹代表一个分类,一共有N类。

transforms.Compose()是把几个transform语句合并到一起

transforms.Resize()可以传入两类参数。一类是(h,w)这将把图片缩放到(h,w)大小(长宽比会改变)。另一类是传入单个参数,这将把图片经过缩放后(保持长宽比不变),将最短的边缩放到传入的参数。

transforms.ToTensor()是数据类型的转换。我们得到的trainset就和官网tutorals里的trainset有一样的格式啦。

需要注意的是我们自己的trainset的图像大小必须为32×32,因为全连接层是固定尺寸的输入输出,所以在卷基层之前的输入,也就是我们训练的图片尺寸大小要求是固定的。CIFAR10的大小是32×32,所以自己的数据也要被缩放到32×32。如果需要其他尺寸的,可以修改CNN的内部结构。

def loadtraindata():
    path = r"/home/********/folder/train"                                         # 路径
    trainset = torchvision.datasets.ImageFolder(path,
                                                transform=transforms.Compose([
                                                    transforms.Resize((32, 32)),  # 将图片缩放到指定大小(h,w)或者保持长宽比并缩放最短的边到int大小

                                                    transforms.CenterCrop(32),
                                                    transforms.ToTensor()])
                                                )

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

接着定义CNN网络。我这里用的结构完全照搬tutorals里的结构。注意我们这里同样是10个输出,也就是10种分类。如果你只有9种分类记得改变参数哦。

class Net(nn.Module):                 # 定义网络,继承torch.nn.Module
    def __init__(self):
        super(Net, self).__init__()   
        self.conv1 = nn.Conv2d(3, 6, 5)       # 卷积层
        self.pool = nn.MaxPool2d(2, 2)        # 池化层
        self.conv2 = nn.Conv2d(6, 16, 5)      # 卷积层
        self.fc1 = nn.Linear(16 * 5 * 5, 120) # 全连接层
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)      # 10个输出

  def forward(self, x):                   # 前向传播
                                           
        x = self.pool(F.relu(self.conv1(x)))  # F就torch.nn.functional
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)  # .view( )是一个tensor的方法,使得tensor改变size但是元素的总数是不变的。
                                                                        # 从卷基层到全连接层的维度转换

        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return 

我用的数据库是车牌里的数字,从0~9一共10类,所以定义的种类还是10种。

classes = ('0','1', '2', '3', '4',
           '5', '6', '7', '8', '9')

测试集也和训练集相似。我这里将batch_size改成了25,在预测时我一次预测25张图片并以5×5的排列显示。

def loadtestdata():
    path = r"/home/********/folder/test"
    testset = torchvision.datasets.ImageFolder(path,
                                                transform=transforms.Compose([
                                                    transforms.Resize((32, 32)),  # 将图片缩放到指定大小(h,w)或者保持长宽比并缩放最短的边到int大小
                                                    transforms.ToTensor()])
                                                )
    testloader = torch.utils.data.DataLoader(testset, batch_size=25,
                                             shuffle=True, num_workers=2)
    return testloader

接着我们需要训练这个CNN网络。用trainandsave函数来训练CNN的参数并用torch.save保存其参数。参数文件.pkl会放在py文件的同一个路径下。

def trainandsave():
    trainloader = loadtraindata()
    # 神经网络结构
    net = Net()
    optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)   # 学习率为0.001
    criterion = nn.CrossEntropyLoss()   # 损失函数也可以自己定义,我们这里用的交叉熵损失函数
    # 训练部分
    for epoch in range(5):    # 训练的数据量为5个epoch,每个epoch为一个循环
                            # 每个epoch要训练所有的图片,每训练完成200张便打印一下训练的效果(loss值)
        running_loss = 0.0  # 定义一个变量方便我们对loss进行输出
        for i, data in enumerate(trainloader, 0):  # 这里我们遇到了第一步中出现的trailoader,代码传入数据
            # enumeratepython的内置函数,既获得索引也获得数据
            # get the inputs
            inputs, labels = data  # data是从enumerate返回的data,包含数据和标签信息,分别赋值给inputslabels

            # wrap them in Variable
            inputs, labels = Variable(inputs), Variable(labels)  # 转换数据格式用Variable
           
            optimizer.zero_grad()        # 梯度置零,因为反向传播过程中梯度会累加上一次循环的梯度

            # forward + backward + optimize
            outputs = net(inputs)        # 把数据输进CNN网络net
            loss = criterion(outputs, labels)  # 计算损失值
            loss.backward()                    # loss反向传播
            optimizer.step()                   # 反向传播后参数更新 
            running_loss += loss.data[0]       # loss累加
            if i % 200 == 199:                 
                print('[%d, %5d] loss: %.3f' %
                    (epoch + 1, i + 1, running_loss / 200))  # 然后再除以200,就得到这两百次的平均损失值
                running_loss = 0.0  # 这一个200次结束后,就把running_loss归零,下一个200次继续使用

    print('Finished Training')
    # 保存神经网络
    torch.save(net, 'net.pkl')                      # 保存整个神经网络的结构和模型参数
    torch.save(net.state_dict(), 'net_params.pkl')  # 只保存神经网络的模型参数

如果我们只进行训练阶段,只需要执行

trainandsave()

就可以了。执行完毕后会保存两个参数文件。如果已经训练好了,就不需要执行训练用的这个函数了。接下来是预测。先定义两个函数:

def reload_net():
    trainednet = torch.load('net.pkl')
    return trainednet

def imshow(img):
    img = img / 2 + 0.5     # unnormalize
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))
    plt.show()

在imshow()中的transpose()的作用,也可简单理解为格式转换。不转换,数据无法正常读取。

def test():
    testloader = loadtestdata()
    net = reload_net()
    dataiter = iter(testloader)  
    images, labels = dataiter.next()                  # 
    imshow(torchvision.utils.make_grid(images,nrow=5))  # nrow是每行显示的图片数量,缺省值为8
    print('GroundTruth: '
          , " ".join('%5s' % classes[labels[j]] for j in range(25)))  # 打印前25个GT(test集里图片的标签)
    outputs = net(Variable(images))  
    _, predicted = torch.max(outputs.data, 1)
   

    print('Predicted: ', " ".join('%5s' % classes[predicted[j]] for j in range(25)))  
  # 打印前25个预测值

如果我们只进行训练阶段,首先需要一个根目录里已经训练好了的net.pkl文件,再执行

test()

最后显示

('GroundTruth: ', '    5     0     7     1     2     1     5     9     8     2     6     3     2     0     4     9     3     9     8     7     1     7     6     4     4')
('Predicted: ', '    5     0     7     1     2     1     5     9     8     2     6     3     2     0     4     9     3     9     8     7     1     7     6     4     4')

全预测对啦

有问题可以留言相互交流哦。


### 回答1: 在使用PyTorch进行训练之前,需要准备好自己的数据集。一般来说,数据集应该分为训练集、验证集和测试集。其中训练集用于训练模型,验证集用于调整模型参数,测试集用于测试模型的泛化能力。 在准备好数据集后,可以开始使用PyTorch构建模型。首先,需要定义一个包含各种层和激活函数的神经网络模型。然后,使用PyTorch提供的损失函数计算模型预测结果与真实结果之间的差异。接下来,定义一个优化器来优化模型的参数。这里通常使用随机梯度下降等梯度优化方法。 当模型构建好后,可以将自己的数据集加载到PyTorch中。这可以通过自定义一个Dataset类和DataLoader类来实现。其中,Dataset类用于加载数据集,DataLoader类用于将数据集划分为小批量进行训练。 最后,使用训练集和验证集进行模型训练。每轮训练后,可以用验证集检查模型的性能,并保存最好的模型参数。 总的来说,PyTorch训练自己的数据集需要经历数据集准备、模型构建、数据集加载、模型训练等一系列步骤。需要仔细设计和调整每个环节的参数,才能得到一个准确的模型。 ### 回答2: Pytorch 是一种开源机器学习框架,因其简单易用、灵活性高和强大的能力而受到广泛关注。训练自己的数据集也是 Pytorch 中的常见操作之一。下面是 Pytorch 训练自己的数据集的基本步骤: 1. 加载数据集: 使用 Pytorch 可以方便地从本地或远程服务器上加载数据集。可以编写自定义的数据读取器或使用 Pytorch 中提供的数据加载函数,如 DataLoader、ImageFolder 等。 2. 数据预处理: 在训练模型之前,需要对数据进行预处理,如缩放、裁剪、旋转、标准化等操作,可以使用 Pytorch 中提供的 torchvision 库实现。 3. 构建模型: 根据任务需求和数据集的特点,选择合适的深度学习模型,并在 Pytorch 中实现。可以使用 Pytorch 提供的模型库,如 torch.nn、torchvision.models 等。 4. 定义损失函数和优化器: 损失函数用于衡量模型预测结果与真实值之间的差异,常见的损失函数包括交叉熵、均方误差、对比损失等。优化器用于更新模型参数,常见的优化器包括随机梯度下降(SGD)、Adam、Adagrad 等。 5. 训练模型: 将数据分为训练集、验证集和测试集,分批次进行训练,每个批次包含多个样本。使用损失函数计算模型在训练集中的误差,并使用优化器更新模型权重,重复循环这个过程直至达到最优结果。 6. 评估模型: 使用测试集评估模型性能,计算模型在测试集中的准确率、精度、召回率等指标,以及混淆矩阵等结果。 最后,可以对模型进行调整、改进和优化,以得到更好的结果。 ### 回答3: PyTorch 是一款流行的深度学习框架,可以用于许多不同的机器学习任务。要训练自己的数据集,您需要执行以下步骤: 1. 准备数据集:将数据整理为适合 PyTorch 的形式,包括分割训练集、验证集和测试集,并将图像和标签标准化。 2. 定义模型:选择适合任务的模型,例如 CNN,RNN 或 Transformer,然后定义其结构和参数。 3. 定义损失函数:选择适合任务的损失函数,例如交叉熵或均方误差,并定义训练期间要最小化的目标函数。 4. 定义优化器:选择适合任务的优化器,例如随机梯度下降(SGD)或 Adam,并定义它的学习率和动量。 5. 训练模型:使用训练训练模型,使用验证集评估模型性能,而不参与梯度计算,使用测试集测试模型性能。 6. 调整参数:通过调整模型架构、损失函数和参数(如学习率)来优化模型性能。 7. 保存模型:训练完成后,可以保存模型的权重,以便以后使用。 总而言之,训练 PyTorch 模型需要准备数据集、定义模型、损失函数和优化器,然后训练模型和调整参数,最后保存模型。
评论 113
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值