PyTorch在CIFAR-10数据集上的训练及测试过程 package Version
python 3.6.5
pytorch 0.4.1
其他相关:
CIFAR-10数据集
PyTorch读取Cifar数据集并显示图片
卷积神经网络中的参数计算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import matplotlib.pyplot as plt import matplotlib.image as mpimg import numpy as npfrom scipy import miscimport torch import torch.nn as nnimport torchvisionimport torchvision.transforms as transforms
1 2 3 torch.cuda.set_device(1 ) device = torch.device('cuda' if torch.cuda.is_available() else 'cpu' )
1 2 3 4 5 num_epochs = 5 num_classes = 10 batch_size = 32 learning_rate = 0.001
加载CIFAR-10数据集
1 2 3 classes = ('plane' , 'car' , 'bird' , 'cat' , 'deer' , 'dog' , 'frog' , 'horse' , 'ship' , 'truck' )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 transform = transforms.Compose([ transforms.Pad(4 ), transforms.RandomHorizontalFlip(), transforms.RandomCrop(32 ), transforms.ToTensor(), ])
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 cifar10Path = './cifar' train_dataset = torchvision.datasets.CIFAR10(root=cifar10Path, train=True , transform=transform, download=True ) test_dataset = torchvision.datasets.CIFAR10(root=cifar10Path, train=False , transform=transform) train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True ) test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False )
Files already downloaded and verified
1 2 3 4 data_iter = iter (test_loader) images, labels = next (data_iter)
1 2 3 4 5 6 idx = 15 image = images[idx].numpy() image = np.transpose(image, (1 ,2 ,0 )) plt.imshow(image) classes[labels[idx].numpy()]
'ship'
网络模型设计和训练:自定义卷积神经网络 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class ConvNet (nn.Module): def __init__ (self, num_classes=10 ): super (ConvNet, self).__init__() self.conv1 = nn.Sequential( nn.Conv2d(3 , 16 , kernel_size=5 , stride=1 , padding=2 ), nn.BatchNorm2d(16 ), nn.ReLU(), nn.MaxPool2d(kernel_size=2 , stride=2 )) self.conv2 = nn.Sequential( nn.Conv2d(16 , 32 , kernel_size=5 , stride=1 , padding=2 ), nn.BatchNorm2d(32 ), nn.ReLU(), nn.MaxPool2d(kernel_size=2 , stride=2 )) self.fc = nn.Linear(8 *8 *32 , num_classes) def forward (self, x ): out = self.conv1(x) out = self.conv2(out) out = out.reshape(out.size(0 ), -1 ) out = self.fc(out) return out
1 2 model = ConvNet(num_classes).to(device)
1 2 3 criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 total_step = len (train_loader) for epoch in range (num_epochs): for i, (images, labels) in enumerate (train_loader): images = images.to(device) labels = labels.to(device) outputs = model(images) loss = criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() if (i+1 ) % 100 == 0 : print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}' .format (epoch+1 , num_epochs, i+1 , total_step, loss.item()))
Epoch [1/5], Step [100/1563], Loss: 1.9562
Epoch [1/5], Step [200/1563], Loss: 1.6313
Epoch [1/5], Step [300/1563], Loss: 1.6405
Epoch [1/5], Step [400/1563], Loss: 1.7303
Epoch [1/5], Step [500/1563], Loss: 1.4697
Epoch [1/5], Step [600/1563], Loss: 1.5183
Epoch [1/5], Step [700/1563], Loss: 1.3547
...
Epoch [5/5], Step [600/1563], Loss: 1.1019
Epoch [5/5], Step [700/1563], Loss: 0.8237
Epoch [5/5], Step [800/1563], Loss: 0.8497
Epoch [5/5], Step [900/1563], Loss: 0.7738
Epoch [5/5], Step [1000/1563], Loss: 0.7937
Epoch [5/5], Step [1100/1563], Loss: 1.1982
Epoch [5/5], Step [1200/1563], Loss: 1.1113
Epoch [5/5], Step [1300/1563], Loss: 0.9233
Epoch [5/5], Step [1400/1563], Loss: 1.3893
Epoch [5/5], Step [1500/1563], Loss: 0.9238
模型测试和保存
ConvNet(
(conv1): Sequential(
(0): Conv2d(3, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU()
(3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(conv2): Sequential(
(0): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU()
(3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(fc): Linear(in_features=2048, out_features=10, bias=True)
)
1 2 3 4 5 6 7 8 9 10 11 12 13 with torch.no_grad(): correct = 0 total = 0 for images, labels in test_loader: images = images.to(device) labels = labels.to(device) outputs = model(images) _, predicted = torch.max (outputs.data, 1 ) total += labels.size(0 ) correct += (predicted == labels).sum ().item() print ('Test Accuracy of the model on the test images: {} %' .format (100 * correct / total))
Test Accuracy of the model on the test images: 59.35 %
准确率是低了点,因为模型太简单了。
1 2 torch.save(model.state_dict(), 'model.ckpt' )
可视化测试(数据集图像和其他图像测试) 取测试集图像测试 1 2 3 data_iter = iter (test_loader) images, labels = next (data_iter)
1 2 3 4 5 6 idx = 10 image = images[idx].numpy() image = np.transpose(image, (1 ,2 ,0 )) plt.imshow(image) classes[labels[idx].numpy()]
'plane'
放入模型进行测试 1 2 3 4 5 imagebatch = image.reshape(-1 ,3 ,32 ,32 ) image_tensor = torch.from_numpy(imagebatch)
1 2 3 4 5 6 7 model.eval () output = model(image_tensor.to(device)) _, predicted = torch.max (output.data, 1 ) pre = predicted.cpu().numpy() print (pre) print (classes[pre[0 ]])
[0]
plane
注意,准确率还很低,预测出错没事情。后面改善网络结构就好了。
读入一张自己图像进行测试 1 2 3 4 5 6 7 8 9 10 srcPath = 'horse.jpg' src = mpimg.imread(srcPath) print (src.shape) plt.imshow(src) plt.axis('off' ) plt.show()
(193, 260, 3)
1 2 3 4 5 newImg = misc.imresize(src,(32 ,32 )) plt.imshow(newImg) plt.axis('off' ) plt.show()
/home/ubuntu/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py:2: DeprecationWarning: `imresize` is deprecated!
`imresize` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.
Use ``skimage.transform.resize`` instead.
1 2 3 4 5 imagebatch = newImg.reshape(-1 ,3 ,32 ,32 ) image_tensor = torch.from_numpy(imagebatch).float ()
1 2 3 4 5 6 7 model.eval () output = model(image_tensor.to(device)) _, predicted = torch.max (output.data, 1 ) pre = predicted.cpu().numpy() print (pre) print (classes[pre[0 ]])
[1]
car
还是预测出错,但是过程就是这么个过程。后续可以通过改善模型来提高准确率。