数据集
CIFAR10 是由 Hinton 的学生 Alex Krizhevsky、Ilya Sutskever 收集的一个用于普适物体识别的计算机视觉数据集,它包含 60000 张 32 X 32 的 RGB 彩色图片,总共 10 个分类。
这些类别分别是飞机、汽车、鸟类、猫、鹿、狗、青蛙、马、船和卡车。其中,包括 50000 张用于训练集,10000 张用于测试集。
run
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
import torchvision.transforms as transforms
import torch.optim as optim
import time
import os# transform 的作用主要是用来对数据进行预处理。
transform = transforms.Compose([transforms.RandomHorizontalFlip(), # 随机翻转图片 , 数据增强transforms.RandomGrayscale(), # 随机调整图片的亮度transforms.ToTensor(), # 数据集加载时,默认的图片格式是numpy,所以通过transforms转换成 Tensor。然后再对输入图片进行标准化。transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) # 给定均值:(R,G,B) 方差:(R,G,B),将会把Tensor正则化
])transform1 = transforms.Compose([transforms.ToTensor(), # 测试的时候,并不需要对数据进行增强transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])trainset = torchvision.datasets.CIFAR10(root='./data',train=True,download=True, transform=transform)trainloader = torch.utils.data.DataLoader(trainset, batch_size=100,shuffle=True # shuffle = True 表明提取数据时,随机打乱顺序)
testset = torchvision.datasets.CIFAR10(root='./data', train=False,download=True, transform=transform1)
testloader = torch.utils.data.DataLoader(testset, batch_size=100,shuffle=False)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,64,3,padding=1)self.conv2 = nn.Conv2d(64,64,3,padding=1)self.pool1 = nn.MaxPool2d(2, 2)self.bn1 = nn.BatchNorm2d(64)self.relu1 = nn.ReLU()self.conv3 = nn.Conv2d(64,128,3,padding=1)self.conv4 = nn.Conv2d(128, 128, 3,padding=1)self.pool2 = nn.MaxPool2d(2, 2, padding=1)self.bn2 = nn.BatchNorm2d(128)self.relu2 = nn.ReLU()self.conv5 = nn.Conv2d(128,128, 3,padding=1)self.conv6 = nn.Conv2d(128, 128, 3,padding=1)self.conv7 = nn.Conv2d(128, 128, 1,padding=1)self.pool3 = nn.MaxPool2d(2, 2, padding=1)self.bn3 = nn.BatchNorm2d(128)self.relu3 = nn.ReLU()self.conv8 = nn.Conv2d(128, 256, 3,padding=1)self.conv9 = nn.Conv2d(256, 256, 3, padding=1)self.conv10 = nn.Conv2d(256, 256, 1, padding=1)self.pool4 = nn.MaxPool2d(2, 2, padding=1)self.bn4 = nn.BatchNorm2d(256)self.relu4 = nn.ReLU()self.conv11 = nn.Conv2d(256, 512, 3, padding=1)self.conv12 = nn.Conv2d(512, 512, 3, padding=1)self.conv13 = nn.Conv2d(512, 512, 1, padding=1)self.pool5 = nn.MaxPool2d(2, 2, padding=1)self.bn5 = nn.BatchNorm2d(512)self.relu5 = nn.ReLU()self.fc14 = nn.Linear(512*4*4,1024)self.drop1 = nn.Dropout2d()self.fc15 = nn.Linear(1024,1024)self.drop2 = nn.Dropout2d()self.fc16 = nn.Linear(1024,10)def forward(self,x):x = self.conv1(x)x = self.conv2(x)x = self.pool1(x)x = self.bn1(x)x = self.relu1(x)x = self.conv3(x)x = self.conv4(x)x = self.pool2(x)x = self.bn2(x)x = self.relu2(x)x = self.conv5(x)x = self.conv6(x)x = self.conv7(x)x = self.pool3(x)x = self.bn3(x)x = self.relu3(x)x = self.conv8(x)x = self.conv9(x)x = self.conv10(x)x = self.pool4(x)x = self.bn4(x)x = self.relu4(x)x = self.conv11(x)x = self.conv12(x)x = self.conv13(x)x = self.pool5(x)x = self.bn5(x)x = self.relu5(x)# print(" x shape ",x.size())x = x.view(-1,512*4*4)x = F.relu(self.fc14(x))x = self.drop1(x)x = F.relu(self.fc15(x))x = self.drop2(x)x = self.fc16(x)return xdef train_sgd(self,device):optimizer = optim.Adam(self.parameters(), lr=0.0001)path = 'weights.tar'initepoch = 0if os.path.exists(path) is not True:loss = nn.CrossEntropyLoss()# optimizer = optim.SGD(self.parameters(),lr=0.01)else:checkpoint = torch.load(path)self.load_state_dict(checkpoint['model_state_dict'])optimizer.load_state_dict(checkpoint['optimizer_state_dict'])initepoch = checkpoint['epoch']loss = checkpoint['loss']for epoch in range(initepoch,100): # loop over the dataset multiple timestimestart = time.time()running_loss = 0.0total = 0correct = 0for i, data in enumerate(trainloader, 0):# get the inputsinputs, labels = datainputs, labels = inputs.to(device),labels.to(device)# zero the parameter gradientsoptimizer.zero_grad()# forward + backward + optimizeoutputs = self(inputs)l = loss(outputs, labels)l.backward()optimizer.step()# print statisticsrunning_loss += l.item()# print("i ",i)if i % 500 == 499: # print every 500 mini-batchesprint('[%d, %5d] loss: %.4f' %(epoch, i, running_loss / 500))running_loss = 0.0_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item()print('Accuracy of the network on the %d tran images: %.3f %%' % (total,100.0 * correct / total))total = 0correct = 0torch.save({'epoch':epoch,'model_state_dict':net.state_dict(),'optimizer_state_dict':optimizer.state_dict(),'loss':loss},path)print('epoch %d cost %3f sec' %(epoch,time.time()-timestart))print('Finished Training')def test(self,device):correct = 0total = 0with torch.no_grad():for data in testloader:images, labels = dataimages, labels = images.to(device), labels.to(device)outputs = self(images)_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item()print('Accuracy of the network on the 10000 test images: %.3f %%' % (100.0 * correct / total))device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
net = Net()
net = net.to(device)
net.train_sgd(device)
net.test(device)
总结
- 下载的数据是numpy格式,shape:HWC, 会转换成tensor,shape:CHW
- torchvision 下载不是图像原始数据,是经过处理转换的numpy
- plt.imshow(),输出的是HWC 格式图像信息