Pytorch demo(一)之分类测试识别
程序员文章站
2024-03-22 09:06:34
...
demo流程
- model.py定义卷积神经网络
- train.py加载数据集并训练,训练集计算loss,测试集计算accuracy,保存训练模型
- predict.py用自己图像进行分类测试,并显示出图像改变成32*32大小后的图像和预测出的类别
定义卷积神经网络
def __init__(self):
super(LeNet, self).__init__()
self.conv1 = nn.Conv2d(3,16,5) # 第一个卷积层
self.pool1 = nn.MaxPool2d(2,2) # 第一个subsampling下采样层
self.conv2 = nn.Conv2d(16,32,5) # 第二个卷积层
self.pool2 = nn.MaxPool2d(2,2) # 第二个subsampling下采样层
self.fc1 = nn.Linear(32*5*5,120) # 将矩阵展平之后得到的结点就是32*5*5,且输出120
self.fc2 = nn.Linear(120,84)
self.fc3 = nn.Linear(84,10) # 最终有10类,所以最后一个全连接层输出数量是10
def forward(self,x):
x = F.relu(self.conv1(x)) # input(3,32,32) output(16,28,28)
x = self.pool1(x) # output(16,14,14)
x = F.relu(self.conv2(x)) # output(32,10,10)
x = self.pool2(x) # output(32,5,5)
x = x.view(-1,32*5*5) # output(32*5*5=800)
x = F.relu(self.fc1(x)) # output(120)
x = F.relu(self.fc2(x)) # output(84)
x = self.fc3(x) # output(10)
return x
经卷积后的矩阵尺寸大小计算公式:
O
u
t
p
u
t
=
(
W
−
F
+
2
P
)
/
S
+
1
Output = (W - F +2P) / S +1
Output=(W−F+2P)/S+1
- 输入图片为 W ∗ W W * W W∗W
- Filter 大小 F ∗ F F * F F∗F
- 步长S
- padding的像素数P
pytorch 中 tensor(也就是输入输出层)的 通道排序为:
[batch, channel, height, width]
过程分析:
-
输入(3,32,32)
- 图片像素大小为32*32
-
经过第一层卷积层(卷积核为5*5)
- Out:(16,18,18)
- 18 = ( 32 − 5 + 2 ∗ 0 ) / 1 + 1 18 = (32-5 + 2 * 0 )/ 1+1 18=(32−5+2∗0)/1+1
- Out:(16,18,18)
当前最常用形式的池化层是每隔2个元素从图像划分出2*2的区块,然后在每个区块中的4个数取最大值。
-
经过第一个下采样层(池化层)
- Out:(16,14,14)
-
经过第二层卷积层(卷积核仍为5*5)
-
Out:(32,10,10)
-
经过第二个下采样层
-
Out:(32,5,5)
-
经过第二个池化层后,数据还是三维的Tensor(32,5,5),所以需要先展平再传到全连接层
-
x = x.view(-1,32*5*5)
-
Out:(32*5*5=800)
-
-
全连接层
-
Out:(120)
-
Out:(84)
-
Out:(10)
-
因为最后是下面**classes中的10个分类**,所以最终输出为10
-
classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
-
-
加载数据集并训练
此demo用的是CIFAR10数据集,一共包含10个类别的RGB彩色图片。
导入、加载训练集
trainset = torchvision.datasets.CIFAR10(root='./data',
train=True,
download=False,
transform=tranform)
# 加载训练集--->50000张训练图片,实际过程需要分批次(batch_size)进行训练
trainlodaer = torch.utils.data.DataLoader(trainset, # 导入的训练集
batch_size=50, # 分批次进行训练,每批次训练的个数
shuffle=True, # 是否打乱训练集
num_workers=0) # 使用线程数
当需要下载数据集时,将 download设为True即可。
导入、加载测试集
# 导入10000张测试图片
testset = torchvision.datasets.CIFAR10(root='./data',
train=False,
download=False,
transform=tranform)
# 加载测试集
testlodaer = torch.utils.data.DataLoader(testset,
batch_size=10000, # 每批次用于验证的样本数
shuffle=False,num_workers=0)
test_data_iter = iter(testlodaer)
# 获取到测试的数据(图像、图像对应标签值)
test_image, test_label = test_data_iter.next()
可视化部分训练数据
# 显示数据集中的图片
def imshow(img):
img = img / 2 + 0.5 # 对图像进行反标准化处理
npimg = img.numpy()
plt.imshow(np.transpose(npimg, (1, 2, 0)))
plt.savefig('./data/sample.png')
plt.show()
# 打印标签
print(' '.join('%5s' % classes[test_label[j]] for j in range(4)))
# 显示图片
imshow(torchvision.utils.make_grid(test_image))
训练
名词 | 定义 |
---|---|
epoch | 一次epoch是对训练集的全部数据进行一次完整的训练 |
batch | 将训练集分成多批次训练,每批次训练大小batch_size |
step | 对一个batch的数据训练过程称为一个step |
那么,现在有50000个训练数据,batch_size=50,即将训练集迭代5次,完整训练一次样本的话:setp=1000,epoch=1。
设置每训练500次打印一次loss和accuray。
学习率设为0.002,打印信息如下:
[1, 500] train_loss: 1.669test_accuracy: 0.481
[1, 1000] train_loss: 1.330test_accuracy: 0.561
[2, 500] train_loss: 1.173test_accuracy: 0.598
[2, 1000] train_loss: 1.115test_accuracy: 0.606
[3, 500] train_loss: 1.009test_accuracy: 0.636
[3, 1000] train_loss: 0.999test_accuracy: 0.629
[4, 500] train_loss: 0.911test_accuracy: 0.647
[4, 1000] train_loss: 0.914test_accuracy: 0.656
[5, 500] train_loss: 0.842test_accuracy: 0.655
[5, 1000] train_loss: 0.844test_accuracy: 0.669
Finished Training
学习率设为0.002时,准确率为66.9%
分类测试
部分测试结果
【1】plane
【2】bird
【3】ship
accuracy变化