PyTorch_分类器详解_构建并训练CNN

运行错误:

RuntimeError: 
        An attempt has been made to start a new process before the
        current process has finished its bootstrapping phase.

        This probably means that you are not using fork to start your
        child processes and you have forgotten to use the proper idiom
        in the main module:

            if __name__ == '__main__':
                freeze_support()
                ...

        The "freeze_support()" line can be omitted if the program
        is not going to be frozen to produce an executable.

原因:从报错信息可以看到,当前进程在运行可执行代码时,产生了一个新进程。这可能意味着您没有使用fork来启动子进程或者是未在主模块中正确使用。后来经过查阅发现了原因,因为windows系统下默认用spawn方法部署多线程,如果代码没有受到__main__模块的保护,新进程都认为是要再次运行的代码,将尝试再次执行与父进程相同的代码,生成另一个进程,依此类推,直到程序崩溃。
解决方法很简单,把调用多进程的代码放到__main__模块下即可。

完整代码:

import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
import torch
import torchvision
import torchvision.transforms as transforms
import torch.optim as optim


if __name__ == '__main__':
    # torchvision数据集的输出是范围为[0,1]的pilimage图像。
    # 我们将它们转换为规范化范围的张量[-1,1]
    transform = transforms.Compose([transforms.ToTensor(),
                                    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
                                    ])

    # 训练集,将相对目录./data下的cifar-10-batches-py文件夹中的全部数据(50000张图片作为训练数据)加载到内存中,若download为True时,会自动从网上下载数据并解压
    trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=False, transform=transform)

    # 将训练集的50000张图片划分成12500份,每份4张图,用于mini-batch输入。shffule=True在表示不同批次的数据遍历时,打乱顺序。num_workers=2表示使用两个子进程来加载数据
    trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
                                              shuffle=True, num_workers=2)

    # 测试集,将相对目录./data下的cifar-10-batches-py文件夹中的全部数据(10000张图片作为测试数据)加载到内存中,若download为True时,会自动从网上下载数据并解压
    testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=False, transform=transform)

    # 将测试集的10000张图片划分成2500份,每份4张图,用于mini-batch输入。
    testloader = torch.utils.data.DataLoader(testset, batch_size=4,
                                             shuffle=False, num_workers=2)
    classes = ('plane', 'car', 'bird', 'cat',
               'deer', 'dog', 'frog', 'horse', 'ship', 'truck')


    class Net(nn.Module):
        def __init__(self):
            super(Net, self).__init__()
            self.conv1 = nn.Conv2d(3, 6, 5)  # 定义conv1函数的是图像卷积函数:输入为图像(3个频道,即彩色图),输出为6张特征图, 卷积核为5x5正方形
            self.pool = nn.MaxPool2d(2, 2)
            self.conv2 = nn.Conv2d(6, 16, 5)
            self.fc1 = nn.Linear(16 * 5 * 5, 120)   # 16 * 5 * 5??????
            self.fc2 = nn.Linear(120, 84)
            self.fc3 = nn.Linear(84, 10)

        def forward(self, x):
            x = self.pool(F.relu(self.conv1(x)))
            x = self.pool(F.relu(self.conv2(x)))
            x = x.view(-1, 16 * 5 * 5)
            x = F.relu(self.fc1(x))
            x = F.relu(self.fc2(x))
            x = self.fc3(x)
            return x


    net = Net()

    print(len(trainset))
    print(len(trainloader))

    criterion = nn.CrossEntropyLoss()  # 交叉熵损失函数
    optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)  # 使用SGD(随机梯度下降)优化,学习率为0.001,动量为0.9

    for epoch in range(2):  # 遍历数据集两次

        running_loss = 0.0      # 用来统计loss的平均值的
        # enumerate(sequence, [start=0]),i序号,data是数据
        # 将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在for循环当中。
        for i, data in enumerate(trainloader, 0):
            # 获取输入
            inputs, labels = data  # data的结构是:[4x3x32x32的张量,长度4的张量]

            # 用变量包装它们
            inputs, labels = Variable(inputs), Variable(labels)  # 把input数据从tensor转为variable

            # 将参数梯度归零
            optimizer.zero_grad()  # 将参数的grad值初始化为0

            # 前进+后退+优化
            outputs = net(inputs)
            loss = criterion(outputs, labels)  # 将output和labels使用叉熵计算损失
            loss.backward()  # 反向传播
            optimizer.step()  # 用SGD更新参数

            # 每2000批数据打印一次平均loss值
            # running_loss += loss.data[0]  # loss本身为Variable类型,所以要使用data获取其Tensor,因为其为标量,所以取0
            running_loss += loss.data        # PyTorch版本问题,该句与上句意思一样
            if i % 2000 == 1999:  # 每2000批打印一次
                print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 2000))
                running_loss = 0.0

    print('Finished Training')


    # 正确率
    correct = 0
    total = 0
    for data in testloader:
        images, labels = data
        outputs = net(Variable(images))

        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum()      # 两个一维张量逐个对比,相同的记为1,不同的记为0

        print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total))

输出:

50000
12500
[1,  2000] loss: 2.195
[1,  4000] loss: 1.893
[1,  6000] loss: 1.705
[1,  8000] loss: 1.585
[1, 10000] loss: 1.527
[1, 12000] loss: 1.463
[2,  2000] loss: 1.406
[2,  4000] loss: 1.357
[2,  6000] loss: 1.366
[2,  8000] loss: 1.337
[2, 10000] loss: 1.315
[2, 12000] loss: 1.283
Finished Training
Accuracy of the network on the 10000 test images: 75 %
Accuracy of the network on the 10000 test images: 87 %
Accuracy of the network on the 10000 test images: 91 %
Accuracy of the network on the 10000 test images: 81 %
Accuracy of the network on the 10000 test images: 75 %
Accuracy of the network on the 10000 test images: 75 %
Accuracy of the network on the 10000 test images: 64 %
Accuracy of the network on the 10000 test images: 68 %
Accuracy of the network on the 10000 test images: 66 %
Accuracy of the network on the 10000 test images: 70 %
Accuracy of the network on the 10000 test images: 68 %
Accuracy of the network on the 10000 test images: 68 %
Accuracy of the network on the 10000 test images: 71 %
Accuracy of the network on the 10000 test images: 69 %
Accuracy of the network on the 10000 test images: 66 %
Accuracy of the network on the 10000 test images: 67 %
Accuracy of the network on the 10000 test images: 66 %
Accuracy of the network on the 10000 test images: 66 %
Accuracy of the network on the 10000 test images: 65 %
…………
…………
Accuracy of the network on the 10000 test images: 55 %
Accuracy of the network on the 10000 test images: 55 %
Accuracy of the network on the 10000 test images: 55 %
Accuracy of the network on the 10000 test images: 55 %
Accuracy of the network on the 10000 test images: 55 %
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值