使用卷积神经网络进行图像分类

    日期: 2021.01

    摘要: 本示例教程将会演示如何使用飞桨的卷积神经网络来完成图像分类任务。这是一个较为简单的示例,将会使用一个由三个卷积层组成的网络完成数据集的图像分类任务。

    我们将会使用飞桨提供的API完成数据集的下载并为后续的训练任务准备好数据迭代器。cifar10数据集由60000张大小为32 * 32的彩色图片组成,其中有50000张图片组成了训练集,另外10000张图片组成了测试集。这些图片分为10个类别,我们的任务是训练一个模型能够把图片进行正确的分类。

    1. transform = ToTensor()
    2. cifar10_train = paddle.vision.datasets.Cifar10(mode='train',
    3. transform=transform)
    4. cifar10_test = paddle.vision.datasets.Cifar10(mode='test',
    5. transform=transform)

    接下来我们使用飞桨定义一个使用了三个二维卷积( Conv2D ) 且每次卷积之后使用 relu 激活函数,两个二维池化层( MaxPool2D ),和两个线性变换层组成的分类网络,来把一个(32, 32, 3)形状的图片通过卷积神经网络映射为10个输出,这对应着10个分类的类别。

    1. epoch_num = 10
    2. batch_size = 32
    3. learning_rate = 0.001
    1. val_acc_history = []
    2. val_loss_history = []
    3. def train(model):
    4. print('start training ... ')
    5. # turn into training mode
    6. model.train()
    7. opt = paddle.optimizer.Adam(learning_rate=learning_rate,
    8. parameters=model.parameters())
    9. train_loader = paddle.io.DataLoader(cifar10_train,
    10. shuffle=True,
    11. batch_size=batch_size)
    12. valid_loader = paddle.io.DataLoader(cifar10_test, batch_size=batch_size)
    13. for epoch in range(epoch_num):
    14. for batch_id, data in enumerate(train_loader()):
    15. x_data = data[0]
    16. y_data = paddle.to_tensor(data[1])
    17. y_data = paddle.unsqueeze(y_data, 1)
    18. logits = model(x_data)
    19. loss = F.cross_entropy(logits, y_data)
    20. if batch_id % 1000 == 0:
    21. print("epoch: {}, batch_id: {}, loss is: {}".format(epoch, batch_id, loss.numpy()))
    22. loss.backward()
    23. opt.step()
    24. opt.clear_grad()
    25. # evaluate model after one epoch
    26. model.eval()
    27. accuracies = []
    28. for batch_id, data in enumerate(valid_loader()):
    29. x_data = data[0]
    30. y_data = paddle.to_tensor(data[1])
    31. y_data = paddle.unsqueeze(y_data, 1)
    32. logits = model(x_data)
    33. loss = F.cross_entropy(logits, y_data)
    34. acc = paddle.metric.accuracy(logits, y_data)
    35. accuracies.append(acc.numpy())
    36. losses.append(loss.numpy())
    37. avg_acc, avg_loss = np.mean(accuracies), np.mean(losses)
    38. print("[validation] accuracy/loss: {}/{}".format(avg_acc, avg_loss))
    39. val_acc_history.append(avg_acc)
    40. val_loss_history.append(avg_loss)
    41. model.train()
    42. model = MyNet(num_classes=10)
    43. train(model)
    1. plt.plot(val_acc_history, label = 'validation accuracy')
    2. plt.xlabel('Epoch')
    3. plt.ylabel('Accuracy')
    4. plt.ylim([0.5, 0.8])
    1. <matplotlib.legend.Legend at 0x12c3686d0>

    从上面的示例可以看到,在cifar10数据集上,使用简单的卷积神经网络,用飞桨可以达到70%以上的准确率。你也可以通过调整网络结构和参数,达到更好的效果。