C I F A R − 10 CIFAR-10 CIFAR−10 数据集也是神经网络中一个非常经典的数据集,该数据集共有 60000 张彩色图像,这些图像是32*32,分为10个类 [ ′ a i r p l a n e ′ , ′ a u t o m o b i l e ′ , ′ b i r d ′ , ′ c a t ′ , ′ d e e r ′ , ′ d o g ′ , ′ f r o g ′ , ′ h o r s e ′ , ′ s h i p ′ , ′ t r u c k ′ ] ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'] [′airplane′,′automobile′,′bird′,′cat′,′deer′,′dog′,′frog′,′horse′,′ship′,′truck′],如下图所示:
过程依然和深度学习(五)-全连接神经网络实现 M N I S T MNIST MNIST 手写数字分类相同,但是在处理时,因为是彩色图片,由 [R, G, B] 组成,所以需要使用三维,其他依然相同:
transform = transforms.Compose([
transforms.ToTensor(), # 将数据转为 tensor
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) # 标准化
])
trainset = torchvision.datasets.CIFAR10(root="./data", train=True, download=False, transform=transform)
testset = torchvision.datasets.CIFAR10(root="./data", train=False, download=False, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True, num_workers=2)
testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False, num_workers=2)
然后看看图片信息:
classes = ("airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck")
(data, label) = trainset[100]
print(classes[label], "\t", data.shape)
show((data+1)/2).resize((100, 100))
模型中各个参数还是直接指定,也可以定义为变量,我这里偷懒,就直接自己填值了,大家可以自己设置,模型创建也都是大同小异:
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.player1 = nn.Sequential( # [3, 32, 32]
nn.Conv2d(3, 6, 5), # 卷积层 [6, 28, 28]
nn.ReLU(), # 激活函数
nn.MaxPool2d(2) # 池化 [6, 14, 14]
)
self.player2 = nn.Sequential( # [6, 14, 14]
nn.Conv2d(6, 16, 5), # [16, 10, 10]
nn.ReLU(),
nn.MaxPool2d(2) # [16, 5, 5]
)
self.player3 = nn.Sequential( # 全连接层
nn.Linear(16*5*5, 120),
nn.Linear(120, 84),
nn.Linear(84, 10)
)
def forward(self, x): # 传播过程
x = self.player1(x)
x = self.player2(x)
x = x.view(x.size()[0], -1) # 平面展开
output = self.player3(x)
return output
前面我们学习了怎么查看各层参数,这里我们也看看各层的权重与偏置信息:
for name, parameters in model.named_parameters():
print(name, ": ", parameters.size())
这里优化函数的学习率,暂时设置为 1 e − 5 1e-5 1e−5:
criterion = nn.CrossEntropyLoss() # 损失函数
optim = torch.optim.SGD(model.parameters(), 1e-3) # 优化器:调整参数,学习率
有了前面两个例子,模型训练相信大家也没啥问题了,我这里直接略过,这里训练 20 20 20 次,有条件的小伙伴可以多训练几次,效果会更好。直接看训练的准确率情况:
这里因为我对数据集的图片没有采取过多处理,而且训练次数太少,所以准确率只有 66 % 66\% 66%。我们也可以测试一下效果。
这里就不和前面一样直接跑测试集了,我们直接使用测试集中几组图片测试一下,想跑测试集的童鞋可以自己试试:
dataiter = iter(testloader) # 显示4张图片
images, labels = dataiter.next()
print("实际类别: ", " ".join("%11s"%classes[labels[j]] for j in range(4)))
show(torchvision.utils.make_grid((images+1)/2)).resize((400, 100)) # resize: 图片缩放 make_grid:将多个图片拼到一个网格
outputs = model(Variable(images))
_, predicted = torch.max(outputs.data, 1)
print("预测类别: ", " ".join("%11s"%classes[predicted[j]] for j in range(4)))
很尴尬,四组图片全部分类正确,但是实际正确率并不会达到这么多。