PytorchLearning-testCifar10
标签: DeepLearning Pytorch
概述
CIFAR-10是多伦多大学提供的图片数据库,图片分辨率压缩至32x32,为三通道彩色图片,一共有10种图片分类,均进行了标注。每种标注6000张,一共60000个样本,适合监督式学习。
本文借鉴LeNet进行CIFAR-10的进行一个简单的训练。
理论准备
LeNet是一个很经典的CNN,在Ng的CNN课程中有过专门的介绍。LeNet一个效果良好的测试集就是手写数字识别。
LeNet的网络结构图如下:
LeNet-5一共有七层结构,输入为3232的图像。网络的第一层为C1为卷积层,有6个特征,每个特征为2828,共156个可以训练的参数;第二层S2为一个池化层,将每个特征由2828缩减为1414;第三层C3为卷积层,有16个特征,每个特征为1010;第四层S4为池化层,将特征由1010缩减为5*5,第5层为全连接层,有120个单元,第6层为全连接层,有84个单元,第7层为输出层,输出10个值,作为分类的依据。详细介绍参见《Gradient-Based Learning Applied to Document Recognition》。
代码实现
LeNet-5网络建立
本文利用pytorch框架重现LeNet-5网络,代码实现参考陈云的开源项目。
网络的构建如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class Net(nn.Module):
def __init__(self):
super(Net,self).__init__()
self.conv1 = nn.Conv2d(3,6,5)
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)
def forward(self,x):
x = F.max_pool2d(F.relu(self.conv1(x)),(2,2))
x = F.max_pool2d(F.relu(self.conv2(x)),2)
x = x.view(x.size()[0],-1)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
其中conv1为一个3通道输入,6特征输出,内核为55的卷基层;conv2为一个6通道输入,16特征输出,内核为55的卷基层;fc1为实现1655到1×120转换的全连接层;fc2为实现1120到184转换的全连接层;fc3为实现184到110转换的输出层。池化层的定义在forward()函数中,其中对于conv1层的池化采用最大池化方法;对于conv2的池化也采用最大池化。
网络输出如下:1
2
3
4
5
6
7Net (
(conv1): Conv2d(3, 6, kernel_size=(5, 5), stride=(1, 1))
(conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
(fc1): Linear (400 -> 120)
(fc2): Linear (120 -> 84)
(fc3): Linear (84 -> 10)
)
数据的导入
CIFAR-10数据的导入实现如下:1
2
3
4
5
6
7
8
9
10
11
12transform = transforms.Compose([transforms.ToTensor(),
transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5)), ])
trainset = tv.datasets.CIFAR10(root='/home/yanwang/下载/dataSet/CIFAR10/',train = True,
download=True,transform=transform)
trainloader = t.utils.data.DataLoader(trainset,batch_size=4,shuffle=True,num_workers=2)
testset = tv.datasets.CIFAR10(root='/home/yanwang/下载/dataSet/CIFAR10/',train = False,
download=True,transform=transform)
testloader = t.utils.data.DataLoader(testset,batch_size=4,shuffle=False,num_workers=2)
classes = ('plane','car','bird''cat','deer','dog','frog','horse','ship','truck')
选择4个样本输出标签和图像,实现如下:1
2
3
4
5dataiter = iter(trainloader)
images,labels = dataiter.next()
print(' '.join('%11s'%classes[labels[j]] for j in range(4)))
img = imshow(tv.utils.make_grid((images+1)/2)).resize((400,100))
img.show()
输出如下:1
2
3
4
5$ python testCifar10.py
Files already downloaded and verified
Files already downloaded and verified
truck
birdcat dog birdcat deer
定义损失函数和优化器
代码如下:1
2criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net1.parameters(),lr=0.001,momentum=0.9)
其中,损失函数选择的是交叉熵损失函数。
pytorch已经为我们实现。
优化器选择是常见的随机梯度下降算法(SGD)。
网络训练
1 | for epoch in range(2): |
此处训练轮数为2。
测试集测试
1 | correct = 0 |
输出为网络在测试集上的准确率。
测试结果
训练2个epoch的结果如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14[1, 2000] loss:2.213
[1, 4000] loss:1.878
[1, 6000] loss:1.706
[1, 8000] loss:1.592
[1,10000] loss:1.505
[1,12000] loss:1.441
[2, 2000] loss:1.386
[2, 4000] loss:1.348
[2, 6000] loss:1.311
[2, 8000] loss:1.298
[2,10000] loss:1.278
[2,12000] loss:1.261
Finished Training
accuracy rate of testSet: 57 %
训练3个epoch的结果如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20[1, 2000] loss:2.161
[1, 4000] loss:1.851
[1, 6000] loss:1.671
[1, 8000] loss:1.551
[1,10000] loss:1.504
[1,12000] loss:1.440
[2, 2000] loss:1.367
[2, 4000] loss:1.357
[2, 6000] loss:1.318
[2, 8000] loss:1.296
[2,10000] loss:1.275
[2,12000] loss:1.264
[3, 2000] loss:1.164
[3, 4000] loss:1.180
[3, 6000] loss:1.173
[3, 8000] loss:1.158
[3,10000] loss:1.142
[3,12000] loss:1.135
Finished Training
accuracy rate of testSet: 59 %
训练5个epoch的结果如下:1
2
3
4
5
6
7
8[5, 2000] loss:1.090
[5, 4000] loss:1.055
[5, 6000] loss:1.095
[5, 8000] loss:1.064
[5,10000] loss:1.076
[5,12000] loss:1.079
Finished Training
accuracy rate of testSet: 58 %
训练10个epoch的参数如下:1
2
3
4
5
6
7
8[10, 2000] loss:0.809
[10, 4000] loss:0.852
[10, 6000] loss:0.847
[10, 8000] loss:0.875
[10,10000] loss:0.891
[10,12000] loss:0.866
Finished Training
accuracy rate of testSet: 62 %
由测试结果可以发现,随着训练轮数的增加,熵损失率减小,准确率逐渐增加。
小结
LeNet是一个比较经典的网络,本次用来训练的电脑是CPU为i5-5200U的thinkpad—X1C.由于本身没有独显,所以使用的CPU进行计算,实际感受是,在没有GPU加速的情况下,即使样本规模不是很大,跑起来也比较吃力。训练3轮的平均用时为4:42,训练10轮的平均时间为12:45。