参考与前言

  1. 课程链接:跟李沐学AI的个人空间_哔哩哔哩_bilibili
  2. 课程主页:https://zh-v2.d2l.ai/chapter_introduction/index.html
  3. 相关代码参考:https://github.com/SHENZHENYI/Classify-Leaves-Kaggle-MuLi-d2l-course
  4. pytorch官方相关教程参考:https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html

本部分主要用于记录自己做第二次作业的一些感受,主要是也第一次Dataloader 也算是一次学习了

首先遇到的问题:

  1. Dataloader没有注意到一个是Dataset,然后还要建一个batch_size的Loader
  2. 输出的output无法和label进行比较,最后直接算max来的
  3. 现在算是知道了沐神讲的,数据预处理的重要性,特别是关于图片的分类中的处理看起来更为重要 -> 看原始数据不同 -> 水平垂直25%随机翻转
  4. loss抖动过大,原因loss的计算结果不应该作为看图的东西,而应该是准确率 -> label smoothing
  5. optimization选取 从SGD -> Adam-> AdamW

全部完整代码在这里:https://gitee.com/kin_zhang/d2l 点进去选择即可

1. 模型

Resnet18

其实看kaggle讨论和代码区 挺多人上了resnet50及更为复杂的模型,基本没有自己手写的cnn,所以我就用了小巧点的 毕竟想快点看到结果(基本就训练个半小时),也不冲前五了

import torch
import pandas as pd
from tqdm.notebook import tqdm
import numpy as np
import osimport torchvision
from torchvision import datasets, models, transforms
import torch.nn as nn
from torch.nn import functional as F
from torch.utils import data
import torch.optim as optimfrom torchvision.io import read_image
from PIL import Image
from torch.utils.data import Dataset,DataLoader
from torchvision.transforms import ToTensor, Lambda
import albumentations
from albumentations import pytorch as ATimport cv2
import matplotlib.pyplot as plt
import wandbnum_epochs, lr, bs, weight_decay = 50, 0.001, 64, 2e-4
NUM_SAVE = num_epochs//5class MODEL(nn.Module):def __init__(self, out_label):super().__init__()self.resnet = models.resnet18(pretrained=True)self.resnet.fc = nn.Linear(self.resnet.fc.in_features,out_label)def forward(self, X):return self.resnet(X)

Loss选取

没啥讲究,就选了CrossEntropyLoss 但是看到讨论区有人对这个做了顺滑功能,不然loss看着抖动特别大 emmm

criterion = nn.CrossEntropyLoss()

但其实在后面计算精度的时候,是直接取最大的那个然后对比label是否一致,类似于这样:

acc = (outputs.argmax(dim=-1) == labels).float().mean()

优化器

倒是这个优化器,一开始选了SGD,Adam 都不太熟内在 然后weight decay还是临时补了看了一下 然后一开始这个weight decay直接拉到了0.95 没有意识到事情的严重性(就是之前从上一个那里拉的;相关阅读:L2正则=Weight Decay?并不是这样 - 知乎 (zhihu.com)

后面看搜了搜就发现有AdamW,然后看其他人做的时候(参考链接处的那位同学) 还有对不同的layer有不同的学习率

net = MODEL(out_label = len(classes)).to(device)
params_1x = [param for name, param in net.resnet.named_parameters()if name not in ["fc.weight", "fc.bias"]]
optimizer = optim.AdamW([{'params': params_1x},{'params': net.resnet.fc.parameters(),'lr': lr * 10}],lr=lr, weight_decay=weight_decay)

2. 数据处理

这一块其实看训练和测试数据集 应该是要把光亮也多少加进去,就是随机加,但是我看了一下ColorJitter 并没有random的概率 emmm 所以就懒了,其实随便写一个random应该也可以

导入数据

和前一个其实差不多,主要是对着pytorch的教程写了一个dataloader然后看其他人 哦吼 原来图片操作这么多

首先是直接read_csv,然后大概按0.9和0.1随机分割训练和验证集,其实也可以用K-fold 我第一次没想好怎么个分割法,直接从train_dataloader那里不太好,从这里吧 每次又需要建新的loader也不太好,干脆 就不弄了,直接这样吧,这次有val主要是 意识到了 还是要看看的严重性 emmm

test_data = pd.read_csv('test.csv')
all_data = pd.read_csv('train.csv')
train_data = all_data.sample(n=int(len(all_data)*0.9),ignore_index=True)
val_data = all_data.sample(n=int(len(all_data)*0.1),ignore_index=True)
classes = all_data['label'].unique().tolist()
print("train_data:",all_data.shape,"test_data shape:",test_data.shape,"\nlabel size:", len(classes))

注意这里的sample函数是来源于pandas的,需要pandas New in version 1.3.0. 不然会报错没有ignore_index,如果不ignore index的话 emmm loader会报错,因为索引有问题,光这个bug 找了大概半小时,后知后觉 算是学习了

预处理

主要写在了dataset这一环,果然和杰哥说的一样 炼丹就是写dataloader hhhhh

class MyDataset(Dataset):def __init__(self, annotations, img_dir, mode=None, target_transform=None):super().__init__()self.img_labels = annotationsself.img_dir = img_dirif mode=='train':preprocess = transforms.Compose([transforms.Resize(256),transforms.CenterCrop(224),transforms.RandomHorizontalFlip(p=.25),transforms.RandomVerticalFlip(p=.5),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),])elif mode=='test':preprocess = transforms.Compose([transforms.Resize(256),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),])elif mode=='val':preprocess = transforms.Compose([transforms.Resize(256),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),])self.transform = preprocessself.target_transform = target_transformdef __len__(self):return len(self.img_labels)def __getitem__(self, idx):img_path = os.path.join(self.img_dir[idx])with Image.open(img_path) as im:image = imlabel = self.img_labels.iloc[idx]if self.transform:image = self.transform(image)if self.target_transform:label = self.target_transform(label)return image, label

可以看到对于test和val都不做图像增广的操作,train也是按0.25 0.25的比例来做,其实加一个亮光应该更好一点,另外我发现这个增广是增广并没有增多数据,其实增多应该也没啥问题?可能担心过拟合?

target_transform = Lambda(lambda y: torch.tensor(classes.index(y)))training_data = MyDataset(train_data['label'], train_data['image'], 'train', target_transform)
train_dataloader = DataLoader(training_data, batch_size=bs, shuffle=True)val_data = MyDataset(val_data['label'], val_data['image'], 'val', target_transform)
val_dataloader = DataLoader(val_data, batch_size=bs, shuffle=False)testing_data = MyDataset(test_data['image'], test_data['image'], 'test', None)
test_dataloader = DataLoader(testing_data, batch_size=bs, shuffle=False)
print("train_data length:",len(training_data),"test_data length:",len(test_data))

3. 训练步骤

这一次没啥了 而且function都懒了 直接写在主体里了,其中有wandb的都是我… 习惯看数据的平台 对比与tensorboard emmm 可以让我多设备 在线看效果 hhh 想起来一开始,吃饭路上看了一眼自己的精度曲线95%好耶,然后一提交88% emmm

wandb.watch(net)
step = 0
for epoch in tqdm(range(num_epochs)):  # loop over the dataset multiple times# 训练集train_accs = []for i, data in enumerate(train_dataloader,0):# get the inputs; data is a list of [inputs, labels]inputs, labels = datainputs, labels = inputs.to(device), labels.to(device)# zero the parameter gradientsoptimizer.zero_grad()# forward + backward + optimizeoutputs = net(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()# recordstep+=1# 对比labels是否一致acc = (outputs.argmax(dim=-1) == labels).float().mean()train_accs.append(acc)wandb.log({'loss': loss,'step':step})del inputs, labels# 分类的精度百分比train_accuracy = sum(train_accs) / len(train_accs)wandb.log({'train accuracy': train_accuracy,'epoch': epoch})# 验证集val_accs = []for i, data in enumerate(val_dataloader,0):inputs, labels = datainputs, labels = inputs.to(device), labels.to(device)outputs = net(inputs)acc = (outputs.argmax(dim=-1) == labels).float().mean()val_accs.append(acc)del inputs, labelsval_accuracy = sum(val_accs) / len(val_accs)wandb.log({'accuracy': val_accuracy,'epoch': epoch})print("No. epoch:",epoch, "accuracy:"+"{:.2f}%".format(train_accuracy.item()*100))if epoch%NUM_SAVE==0 and epoch!=0:torch.save(net.state_dict(),'checkpoint_'+str(epoch))print("Model Saved")wandb.finish()
print('Finished Training, the last loss is:', loss.item())

唯一需要注意的是关于精度最好还是打一下 不然看着loss 抖动总是心有余悸,比如这样 是不是右边的顺眼多了

4. 结果

看kaggle上 有人0.99真的是 太太太太 吓人了,一开始光溜溜的写完loader,用的SGD基本默认参数,就大概直接train 上传后有92%结果,然后后面开始骚操作了一个比一个低,主要是我都不知道我改了些啥,emmm 做好记录的重要原因体现了,最新的结果emm 还是91%,所以又回到了最初的起点 hhhh 就是这篇博文上的代码提交的,给训练了50 epoch,大概贴一下val train loss的图和大致模型梯度(但是有太多个layer梯度了 所以 只截取了一点点)

【沐神课程 - 动手学深度学习】实战二详解之 Kaggle比赛:分类树叶相关推荐

  1. 【沐神课程 - 动手学深度学习】实战一详解之 Kaggle比赛:预测房价

    参考与前言 课程链接:跟李沐学AI的个人空间_哔哩哔哩_bilibili 课程主页:https://zh-v2.d2l.ai/chapter_multilayer-perceptrons/kaggle ...

  2. 沐神《动手学深度学习》使用笔记

    1.引言 沐神提到自己看的三本书: <算法导论> <模式识别和机器学习>即PRML <统计学习基础> 一个教训:计算机科学是动手的学科,没有足够的动手能力难以取得很 ...

  3. Colab运行沐神《动手学深度学习》:ImportError: cannot import name ‘_check_savefig_extra_args‘ from ‘matplotlib.back

    原语句: num_epochs = 10 train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, updater) 报错: I ...

  4. 沐神《动手学深度实战Kaggle比赛:狗的品种识别(ImageNet Dogs)

    沐神<动手学深度学习>飞桨版课程公开啦! hello各位飞桨的开发者,大家好!李沐老师的<动手学深度学习>飞桨版课程已经公开啦.本课程由PPSIG和飞桨工程师共同建设,将原书中 ...

  5. 李沐中《动手学深度学习》6月最新

    阿斯顿·张.李沐联合编写的,面向中文读者的能运行.可讨论的深度学习教科书<动手学深度学习>又更新了.     本书6月最新.免费中文版.英文版教材:随书配套代码.视频: https://m ...

  6. 李沐d2l《动手学深度学习》第二版——风格迁移源码详解

    本文是对李沐Dive to DL<动手学深度学习>第二版13.12节风格迁移的源码详解,整体由Jupyter+VSCode完成,几乎所有重要代码均给出了注释,一看就懂.需要的同学可以在文末 ...

  7. 动手学深度学习(二十二)——GoogLeNet:CNN经典模型(五)

    文章目录 1. 含并行连结的网络(GoogLeNet) 1.1 Inception块 1.2 GoogLeNet模型 2. 动手实现简化的GoogLeNet模型 2.1 实现Inception块 2. ...

  8. 动手学深度学习(二)——windows10系统中pytorch安装(从显卡驱动开始)

    文章目录 pytorch安装 一.配置及准备: 二.安装步骤: 1.下载与安装CUDA 2.下载与安装CuDNN 3. 验证CUDA和CuDNN的安装 4. 安装pytorch 5.测试pytorch ...

  9. 动手学深度学习(二十六)——图像增广(一生二,二生三,三生万物?)

    文章目录 一.图像增广 二.常用的图像增广方法 1. 翻转和裁减 2. 颜色改变 3. 叠加使用多种数据增广方法 三.使用图像增广进行训练 四.总结(干活分享) 一.图像增广 定义&解释: 通 ...

最新文章

  1. 新视野计算机等级考试官网,计算机二级C语言
  2. <<温泉屋的小老板娘>>观后感
  3. Connection to node 0 (/192.168.204.131:9092) could not be established
  4. JAVA执行过程sql,SQL 执行过程
  5. ASP.NET3.5 企业级项目开发 -- 第二章 数据访问层(DAL)的开发
  6. Kubernetes教程
  7. centos7安装ssh服务
  8. C++ Primer Plus学习(七)——函数简介
  9. Command “python setup.py egg_info“ failed with error code 1 in C:\Users\始末\AppData\Local\Temp\pip-b
  10. PDMS Pipeline Tool 教程(四):目录树顺序检查
  11. 2017年12月19-20日 阿里云 飞天/智能 云栖大会-北京峰会 会议笔记
  12. 三角形面积的计算公式,外接圆半径
  13. SRM 719 div2 Hard (01Trie,最大异或和)
  14. 互联网公司数据安全保护新探索
  15. win10与virtualBox共享文件夹
  16. CGAffineTransform 视频旋转(转)
  17. char *const 和 const char *(char const*)
  18. CentOS 7 腾讯云服务器 Linux无图形化界面静默安装oracle数据库.
  19. 计算机作业我家乡的变化,家乡的变化
  20. android高级工程师应该会的知识

热门文章

  1. 简单介绍android中什么叫i18n 和L10n
  2. 自媒体头条号平台的消重机制,你了解了吗?
  3. 博诺杯工业机器人比赛2019_2018年度机械行业职业教育技能大赛“博诺杯”工业机器人维修调试与技术应用竞赛顺利闭幕...
  4. 网页设计期末作业 使用HTML制作静态宠物网站——蓝色版爱宠之家(HTML CSS)
  5. 软件设计体系-简单工厂模式实例二---权限管理
  6. Opencv特征点检测及目标提取
  7. Verilog数据选择器参数化设计
  8. 3. RDMA基本元素
  9. 疫情下思乡的心理学调查问卷
  10. 【内网安全】——CS操作指南(二)