文章目录

  • 1. Kaggle数据集介绍
  • 2. 下载数据和数据整理(kaggle官网即可)
  • 3. 图像增广
  • 4. 加载数据
  • 5.微调模型
  • 6.可视化validation数据
  • 7. 输出测试结果并提交kaggle

1. Kaggle数据集介绍

狗的类别识别:https://www.kaggle.com/c/dog-breed-identification

我们将识别 120 类不同品种的狗。 这个数据集实际上是著名的 ImageNet 的数据集子集。

数据分布:

2. 下载数据和数据整理(kaggle官网即可)

import collections
import math
import os
import shutil
import pandas as pd
import torch
import torchvision
from torch import nn
from d2l import torch as d2l
import matplotlib.pyplot as plt
import numpy as np
# 如果使用测试数据:
# d2l.DATA_HUB['dog_tiny'] = (d2l.DATA_URL + 'kaggle_dog_tiny.zip',
#                             '0cb91d09b814ecdc07b50f31f8dcad3e81d6a86d'
demo = False
if demo:data_dir = d2l.download_extract('dog_tiny')
else:data_dir = os.path.join('..', 'data', 'dog-breed-identification')
# 数据分为训练数据集、验证数据集、测试数据集,并分别复制到对应的文件夹之中
"""如果数据量不大(对于我个人的主机,几个G的数据还是可以这样做),但是数据太大就不建议了,这样数据会被复制两次"""
def reorg_dog_data(data_dir, valid_ratio):labels = d2l.read_csv_labels(os.path.join(data_dir, 'labels.csv'))d2l.reorg_train_valid(data_dir, labels, valid_ratio)d2l.reorg_test(data_dir)batch_size = 32 if demo else 128
valid_ratio = 0.1
reorg_dog_data(data_dir, valid_ratio)

3. 图像增广

ImageNet的图片大小是要大于CIFAR-10的,对图片进行裁减可以提高训练效率,同时减小误差

transform_train = torchvision.transforms.Compose([# 随机裁剪图像,所得图像为原始面积的0.08到1之间,高宽比在3/4和4/3之间。# 然后,缩放图像以创建224 x 224的新图像torchvision.transforms.RandomResizedCrop(224, scale=(0.08, 1.0),ratio=(3.0 / 4.0, 4.0 / 3.0)),torchvision.transforms.RandomHorizontalFlip(),# 随机更改亮度,对比度和饱和度torchvision.transforms.ColorJitter(brightness=0.4, contrast=0.4,saturation=0.4),# 添加随机噪声torchvision.transforms.ToTensor(),# 标准化图像的每个通道torchvision.transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])])transform_test = torchvision.transforms.Compose([torchvision.transforms.Resize(256),# 从图像中心裁切224x224大小的图片torchvision.transforms.CenterCrop(224),torchvision.transforms.ToTensor(),torchvision.transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])])

4. 加载数据

# 注意四个datasets:train_valid_ds 是train_ds和valid_ds的集合(通常我们是根据这个数据集来划分train和valid的)
train_ds, train_valid_ds = [torchvision.datasets.ImageFolder(os.path.join(data_dir, 'train_valid_test', folder),transform=transform_train) for folder in ['train', 'train_valid']]valid_ds, test_ds = [torchvision.datasets.ImageFolder(os.path.join(data_dir, 'train_valid_test', folder),transform=transform_test) for folder in ['valid', 'test']]
train_iter, train_valid_iter = [torch.utils.data.DataLoader(dataset, batch_size, shuffle=True,drop_last=True)for dataset in (train_ds, train_valid_ds)]valid_iter = torch.utils.data.DataLoader(valid_ds, batch_size, shuffle=False,drop_last=True)test_iter = torch.utils.data.DataLoader(test_ds, batch_size, shuffle=False,drop_last=False)

查看一下增强之后的数据:查看一下增强之后的数据:

from mpl_toolkits.axes_grid1 import ImageGrid
def imshow(axis, inp):"""Denormalize and show"""inp = inp.numpy().transpose((1, 2, 0))mean = np.array([0.485, 0.456, 0.406])std = np.array([0.229, 0.224, 0.225])inp = std * inp + meanaxis.imshow(inp)img, label = next(iter(train_iter))
print(img.size(), label.size())
fig = plt.figure(1, figsize=(16, 4))
grid = ImageGrid(fig, 111, nrows_ncols=(3, 4), axes_pad=0.05)
for i in range(12):ax = grid[i]img_data = img[i]imshow(ax, img_data)
torch.Size([128, 3, 224, 224]) torch.Size([128]

5.微调模型

深度学习框架的高级API提供了在ImageNet数据集上预训练的各种模型。在这里我们选择ResNet-34模型,重构其输出层即可

def get_net(devices):finetune_net = nn.Sequential()finetune_net.features = torchvision.models.resnet50(pretrained=True)# 定义一个新的输出网络,共有120个输出类别finetune_net.output_new = nn.Sequential(nn.Linear(1000, 512), nn.ReLU(),nn.Linear(512, 120))# 将模型参数分配给用于计算的CPU或GPUfinetune_net = finetune_net.to(devices[0])# 冻结参数for param in finetune_net.features.parameters():param.requires_grad = Falsereturn finetune_net
"""计算损失之前,首先获取预训练模型的输出层之前的输出,然后使用这个输出作为我们自定义的输出层的输入,进行损失计算"""
loss = nn.CrossEntropyLoss(reduction='none')def evaluate_loss(data_iter, net, devices):l_sum, n = 0.0, 0for features, labels in data_iter:features, labels = features.to(devices[0]), labels.to(devices[0])outputs = net(features)l = loss(outputs, labels)l_sum += l.sum()n += labels.numel()return l_sum / n
def train(net, train_iter, valid_iter, num_epochs, lr, wd, devices, lr_period,lr_decay):# 只训练小型自定义输出网络net = nn.DataParallel(net, device_ids=devices).to(devices[0])# 注意这里进行训练的部分是都可以求解梯度的部分(即我们自定义的部分)trainer = torch.optim.SGD((param for param in net.parameters() if param.requires_grad), lr=lr,momentum=0.9, weight_decay=wd)scheduler = torch.optim.lr_scheduler.StepLR(trainer, lr_period, lr_decay)num_batches, timer = len(train_iter), d2l.Timer()legend = ['train loss']if valid_iter is not None:legend.append('valid loss')animator = d2l.Animator(xlabel='epoch', xlim=[1, num_epochs],legend=legend)for epoch in range(num_epochs):metric = d2l.Accumulator(2)for i, (features, labels) in enumerate(train_iter):timer.start()features, labels = features.to(devices[0]), labels.to(devices[0])trainer.zero_grad()output = net(features)l = loss(output, labels).sum()l.backward()trainer.step()metric.add(l, labels.shape[0])timer.stop()if (i + 1) % (num_batches // 5) == 0 or i == num_batches - 1:animator.add(epoch + (i + 1) / num_batches,(metric[0] / metric[1], None))measures = f'train loss {metric[0] / metric[1]:.3f}'if valid_iter is not None:valid_loss = evaluate_loss(valid_iter, net, devices)animator.add(epoch + 1, (None, valid_loss.detach()))scheduler.step()if valid_iter is not None:measures += f', valid loss {valid_loss:.3f}'print(measures + f'\n{metric[1] * num_epochs / timer.sum():.1f}'f' examples/sec on {str(devices)}')

Resnet35+Adam优化

# Adam的结果太丝滑了
devices, num_epochs, lr, wd = d2l.try_all_gpus(), 20, 1e-4, 1e-4
lr_period, lr_decay, net = 5, 0.5, get_net(devices)
train(net, train_iter, valid_iter, num_epochs, lr, wd, devices, lr_period,lr_decay)
train loss 1.130, valid loss 0.936
461.9 examples/sec on [device(type='cuda', index=0)]

resnet50 + SGD

devices, num_epochs, lr, wd = d2l.try_all_gpus(), 20, 1e-4, 1e-4
lr_period, lr_decay, net = 2, 0.75, get_net(devices)
train(net, train_iter, valid_iter, num_epochs, lr, wd, devices, lr_period,lr_decay)
train loss 0.751, valid loss 0.734
228.5 examples/sec on [device(type='cuda', index=0)]

6.可视化validation数据

def visualize_model(valid_iter, net, devices, num_images=16):cnt = 0fig = plt.figure(1, figsize=(16, 16))grid = ImageGrid(fig, 111, nrows_ncols=(4, 4), axes_pad=0.05)net = nn.DataParallel(net, device_ids=devices).to(devices[0])for i, (inputs, labels) in enumerate(valid_iter):outputs = net(inputs.to(devices[0]))_, preds = torch.max(outputs.data, 1)for j in range(inputs.size()[0]):ax = grid[cnt]imshow(ax, inputs.cpu().data[j])ax.text(10, 210, '{}/{}'.format(preds[j], labels.data[j]), color='k', backgroundcolor='w', alpha=0.8)cnt += 1if cnt == num_images:returnvisualize_model(valid_iter,net ,devices)

7. 输出测试结果并提交kaggle

preds = []
for data, label in test_iter:output = torch.nn.functional.softmax(net(data.to(devices[0])), dim=0)preds.extend(output.cpu().detach().numpy())
ids = sorted(os.listdir(os.path.join(data_dir, 'train_valid_test', 'test', 'unknown')))
with open('./kaggle_submission/dog/submission4.csv', 'w') as f:f.write('id,' + ','.join(train_valid_ds.classes) + '\n')for i, output in zip(ids, preds):f.write(i.split('.')[0] + ',' + ','.join([str(num)for num in output]) + '\n')

最后看看成绩(只使用ResNet-35模型,调参只是lr和LRStep在变化):

这个排名在四年前大概800名左右,仔细调参应该可以排到700名左右,score达到0.7?【炼丹吧大师!!!】

玩转Kaggle:Dog Breed Identification【识别狗的类别】相关推荐

  1. 动手学深度学习Kaggle:图像分类 (CIFAR-10和Dog Breed Identification), StratifiedShuffleSplit,数据集划分

    目录 CIFAR-10 获取并组织数据集 下载数据集 整理数据集 组织数据集更一般的方式 图像增广 读取数据集 torchvision.datasets.ImageFolder()的特点 定义模型 定 ...

  2. kaggle比赛--Dog Breed Identification狗狗品种识别大赛

    对截止至2020.8.1的top5方案进行总结归纳 比赛链接:dog-breed-identification 1.数据形式 2.top1总结 3.top2总结 4.top3总结 -- 1.数据形式 ...

  3. Kaggle: ImageNet Dog Breed Classification (Pytorch)

    本文为自学碰壁的完成任务的一个记录总结,无任何参考价值 写在前面:本文章是跟着<动手深度学习>(李沐)学习过程中的动手实操,前因是对一个树叶数据集分类,但是由于自己太小白(太菜了)折腾了两 ...

  4. 【Kaggle项目实战记录】狗的品种识别

    文章目录 1 查看原数据 2 数据预处理,建立Dataset 设定图像增广的方法 创建数据集Dataset类 预览训练集和验证集 3 定义和初始化模型 4 设置训练集和测试集 5 训练 6 模型存储 ...

  5. UVa Problem 10310 Dog and Gopher (狗拿地鼠)

    // Dog and Gopher (狗拿地鼠) // PC/UVa IDs: 111301/10310, Popularity: A, Success rate: average Level: 1 ...

  6. Python视觉深度学习系列教程 第三卷 第9章 Kaggle竞赛:情绪识别

            第三卷 第九章 Kaggle竞赛:情绪识别 在本章中,我们将解决Kaggle的面部表情识别挑战.为了完成这项任务,我们将在训练数据上从头开始训练一个类似VGG的网络,同时考虑到我们的网 ...

  7. 玩转Kaggle:Classify Leaves(叶子分类)——模型设计与训练

    文章目录 一.数据加载 二.模型构建与训练 1. resnet 1.1 ResNet-50模型微调+冻结 1.2 五折交叉验证 1.3 模型预测 1.4 利用K-Fold结果投票获取最终提交数据 1. ...

  8. python狗品种识别_使用python+keras来识别狗的品种

    在这篇文章中,将教大家实现一个网页应用程序,该程序可以接收狗的图片,然后输出其品种,其准确率超过80%! 我们将使用深度学习来训练一个识别狗品种的模型,数据集是狗图像与他们的品种信息,通过学习图像的特 ...

  9. 使用python+keras来识别狗的品种

    在这篇文章中,将教大家实现一个网页应用程序,该程序可以接收狗的图片,然后输出其品种,其准确率超过80%! 我们将使用深度学习来训练一个识别狗品种的模型,数据集是狗图像与他们的品种信息,通过学习图像的特 ...

最新文章

  1. Failed to register Grid Infrastructure type ora.mdns.type
  2. ASP.NET Core 上传多文件 超简单教程
  3. Apache软件基金会宣布Apache Unom成为顶级项目
  4. [转]Web测试中的界面测试用例设计
  5. HDU - 6598 Harmonious Army (最小割)
  6. MySQL找出锁等待
  7. Educational Codeforces Round 72 (Rated for Div. 2) D. Coloring Edges dfs树/拓扑找环
  8. 电力电子、电机控制系统的建模和仿真_清华团队研发,首款国产电力电子仿真软件来啦~已捐赠哈工大、海工大、清华使用!...
  9. 累积分布函数_C7: 概率函数和分布函数Distribution Function
  10. Servlet-Response直接返回一个文件并且在浏览器上显示
  11. hdu-3488-Tour(KM最佳完美匹配)
  12. 代码整洁之道-第5章-格式-读书笔记
  13. 莫烦 Tensorflow
  14. 机器学习(四)神经网络
  15. 东方木分享:如何快速的安装网吧系统
  16. 1H413000工业机电工程安装技术—— 1H413010机械设备安装技术
  17. wps生成正态分布的随机数_如何用excel批量生成正态分布的随机数?
  18. vue的keep-alive的正确用法
  19. 电脑解锁后黑屏有鼠标_电脑开机后,显示屏黑屏只有鼠标箭头,怎么回事
  20. 亲测绝对有用,,电脑不显示可连接WiFi列表,无法连接WiFi的解决办法。

热门文章

  1. Bash-Script 应用案例
  2. Practical Python and OpenCV 3rd Edition读书笔记_Chapter8_Smoothing and Blurring平滑与模糊_思维导图
  3. 日记记事本java实训,黑马学习日记  GUI实现简单记事本功能
  4. pythontrun什么意思_python 新手笔记一
  5. c++通讯录管理系统(函数,指针,结构体)
  6. ps如何把自己的图与样机结合_如何用PS制作样机,并且看起来毫无痕迹
  7. CH57X/CH58X系列BLE Mesh无线组网方案
  8. 自动驾驶测试中的场景构建
  9. 摄氏度符号英文计算机语言,英文摄氏度°C符号的正确输法
  10. linux添加键盘布局,Linux 定制键盘布局