【项目实战】Pytorch的十二生肖分类挑战

火山方舟向量数据库大模型

picture.image

作者 | M. Rake Linggar A

来源 | Medium

编辑 | 代码医生团队

在贝塔斯曼AI Udacity奖学金中,学者们不仅必须完成AI Udacity课程,而且还相互挑战,以应用在课程中收集和实践的技能和知识。这些挑战之一是中国十二生肖分类挑战。马上就是中国农历新年之际。

中国的十二生肖分为十二个年度周期,每年由特定的动物识别。

对于那些想尝试这一挑战的人,可以在 此处 获取数据。

https://drive.google.com/file/d/1Bjope31ZX9p4jXyaYK6CazIOGcYhOjI6/view

搭建环境

首先是使用GPU会使任务变得更容易,因此尝试同时使用Google Colab和Kaggle Notebook来构建此模型。但是由于希望能够编辑(添加,更改,移动或删除)数据,因此更喜欢使用Google Colab,因为数据存储在Google云端硬盘中。

picture.image

加载并检查数据

有12类图像,希望对Pytorch模型进行分类。将数据分为三类是一个好主意,即用于训练模型的训练数据,用于确保模型不会过拟合的验证和测试数据。

首先检查这些数据的分布。


          
for dirname, _, filenames in os.walk('./signs/'):
          
    print("{0} \t-\t {1}".format(dirname, len(filenames)))
      

picture.image

十二生肖图像分布

对于每次训练,都有600幅训练图像(简称goat),54幅验证图像(代表一张goat,这很可能是因为一幅图像放错了位置)以及54-55张测试图像。

看一下这些图像的样本。

picture.image

样本图片

对来说也很好。还可以看到,也在合并绘图图像(因为龙不存在,也不全是)。

使用Pytorch创建模型

Pytorch(以及其他机器学习/深度学习框架)的优点之一是它提供了简化的样板代码。其中之一是加载训练测试数据。


          
data_dir = 'signs'
          
 
          
batch_size = 32
          
 
          
train_transforms = transforms.Compose([transforms.Resize([224,224]),
          
                                        transforms.RandomHorizontalFlip(0.5),
          
                                        transforms.ToTensor(),
          
                                        transforms.Normalize([0.5, 0.5, 0.5],
          
                                        [0.5, 0.5, 0.5])])
          
 
          
val_transforms = transforms.Compose([transforms.Resize([224,224]),
          
                                        transforms.ToTensor(),
          
                                        transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])])
          
 
          
test_transforms = transforms.Compose([transforms.Resize([224,224]),
          
                                        transforms.ToTensor(),
          
                                        transforms.Normalize([0.5, 0.5, 0.5],
          
                                        [0.5, 0.5, 0.5])])
          
 
          
train_data = datasets.ImageFolder(data_dir + '/train', transform=train_transforms)
          
valid_data = datasets.ImageFolder(data_dir + '/valid', transform=test_transforms)
          
test_data = datasets.ImageFolder(data_dir + '/test', transform=test_transforms)
          
 
          
 
          
trainloader = torch.utils.data.DataLoader(train_data, batch_size=batch_size, shuffle=True, num_workers=4)
          
validloader = torch.utils.data.DataLoader(valid_data, batch_size=batch_size, num_workers=4)
          
testloader = torch.utils.data.DataLoader(test_data, batch_size=batch_size, shuffle=True, num_workers=4)
      

现在建立模型。

将使用经过预训练的Resnet34模型来转移其学习内容,以建立此分类模型。还尝试了其他经过预训练的模型,例如带有BatchNorm的Resnet101和VGG 19,但是Resnet34提供了相当不错的性能,因此继续这样做。Resnet34要求输入图像的宽度和高度为224。

完整的模型架构如下。


          
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
          
model = models.resnet34(pretrained=True)
          
 
          
for param in model.parameters():
          
    param.requires_grad = False
          
    
          
model.fc = nn.Sequential(nn.Linear(512, 512),
          
                                 nn.ReLU(),
          
                                 nn.Dropout(0.2),
          
                                 nn.Linear(512, 12),
          
                                 nn.LogSoftmax(dim=1))
          
criterion = nn.NLLLoss()
          
optimizer = optim.Adam(model.fc.parameters(), lr=0.003)
          
model.to(device)
      

在这里不会使用任何非常复杂的东西。仅有两个额外的FC层,每个层具有512个神经元,而一个输出层则具有12个神经元(当然,每个生肖类都有一个)。

训练模型

现在是第一个令人兴奋的部分,训练模型。

只需要在(a)对模型进行正向和反向传递,以及(b)测量模型的当前/运行性能的同时遍历

训练

数据加载器。选择每100小批处理一次(b)。

选择在7-15个时期内训练模型。将在下面的图表中看到原因。

picture.image

训练和验证的损失和准确性(Resnet50试用1)

在每100次小批量通过中,该模型肯定会随着时间的推移在训练数据集上得到改善。但是查看验证数据集上的性能时,它似乎并没有改善太多(尽管精度似乎随时间而提高了一点,但认为这还不够)。

但是当查看具有不同体系结构的其他模型时,会发生相同的事情。

picture.image

训练和验证的损失和准确性(Resnet50试用2)

picture.image

训练和验证损失与准确性(具有批处理规范的VGG 19)

第二个模型使用Resnet50,与第一个模型几乎相同,除了将学习率从0.001更改为0.003。第三是将VGG 19与Batch Norm一起使用,学习率为0.001。

三种不同的模型和参数说明了同样的情况-经过多次训练后,验证的准确性性能并没有显着提高(尤其是对于后两种模型)。

对模型的损失并不太担心,因为它只是衡量模型表现的“可信度”的一种量度,将更多的精力放在准确性上。

测试模型

看看模型是否真的好,或者满足测试数据集而破裂。


          
test_acc = 0.0
          
test_datas = 0.0
          
running_test_loss = 0.0
          
 
          
model.eval()
          
 
          
for i_v, data_v in enumerate(testloader):
          
  i_, l_ = data_v
          
  inputs = i_.to(device)
          
  labels = l_.to(device)
          
  outputs = model(inputs)
          
  loss = criterion(outputs, labels)
          
  running_test_loss += loss.item()
          
 
          
  _, prediction = torch.max(outputs.data, 1)
          
  test_acc += torch.sum(prediction == labels.data).item()
          
  test_datas += prediction.shape[0]
          
 
          
print('Test model\ttest loss: %.3f\t---test acc: %.3f' %
          
      ( running_test_loss / len(testloader),  test_acc / test_datas ))
      
  • ResNet(lr 0.001)-损失:0.355 acc:90.5%

  • ResNet(lr 0.003)—损失:0.385 acc:90.6%

  • 具有批处理标准的VGG 19-损失:0.586 acc:90.8%

从准确性上看,它们几乎相同。对于损失,最高为0.001 lr的ResNet占统治地位。这些数字与训练和验证几乎相同,因此可以说模型并不过分(或者至少在小时期之前就停止了),并且可以很好地对生肖进行分类。

很好奇,关于哪个图像问题最多。

picture.image

混淆矩阵

可以看到,该模型很少会误认为山羊 ,但是如果出现这种情况,它总是带有 ox (角)。

picture.image

山羊图像被模型误认为是牛

还可以看到,该模型dragon与其他生肖相比较有一些困难。最值得注意的是oxes (角)和snake(身体)。

写在最后

在贝塔斯曼AI Udacity奖学金期间,中国生肖标志分类挑战的工作真是令人耳目一新。它推动并激励着去做爱做的事-在AI /机器学习/深度学习领域进行实验和构建。

可以在Github页面上查看笔记本。

https://github.com/mrakelinggar/zodiac\_animal\_classification

AI人工智能初学者 】希望可以帮助大家争取更多的内容推送和福利分享以及好文章的转载,我也会持续为大家提供更多更有质量的电子书籍非常期待您的加入。

转载文章请后台联系

侵权必究

希望技术与灵魂可以一路同行

长按识别二维码关注一下

更多精彩内容可回复关键词

每篇文章的主题即可

picture.image

picture.image

picture.image

picture.image

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
从 ClickHouse 到 ByteHouse
《从ClickHouse到ByteHouse》白皮书客观分析了当前 ClickHouse 作为一款优秀的开源 OLAP 数据库所展示出来的技术性能特点与其典型的应用场景。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论