建议使用以下浏览器,以获得最佳体验。 IE 9.0+以上版本 Chrome 31+ 谷歌浏览器 Firefox 30+ 火狐浏览器
请选择 进入手机版 | 继续访问电脑版-->
设置昵称

在此一键设置昵称,即可参与社区互动!

确定
我再想想
标签
您还可以添加5个标签
  • 没有搜索到和“关键字”相关的标签
  • 云产品
  • 解决方案
  • 技术领域
  • 通用技术
  • 平台功能
取消

拉小熊

角色:成员

话题:0

发消息
发表于2020年05月09日 10:53:07 7641
直达本楼层的链接
楼主
显示全部楼层
[参赛经验分享] 爱(AI)美食美食图片分类大赛——第三名方案分享

### 比赛简介 共10类食物,数据集共5000个图片,尺寸大小不一,类别分别均衡。需要自己划分训练集和验证集,用于判分的测试集不可见。 比赛难度不大,主要难点在于如何减小过拟合,提高模型的泛化能力。代码已在我的github上开源,欢迎star。 [源码的github地址](https://github.com/yananren2137/huawei-ai-food-challenge) **涨点核心思想:** - cbam注意力 - auto_augment - cutmix - snapshot - LabelSmooth ### 数据探索 由于数据集比较小,也比较简单,因此主要是统计了一下所有图像的尺寸分布,发现大多数图像的宽高在400~500,因此可以选择将图像输入尺寸调整到这个区间。 大尺寸的另一个好处是可以显著提高分类准确率。 ### 训练策略 ##### 数据集划分 采用9:1的比例将数据集划分为训练集和验证集,时间和资源允许的情况下,可以进行10折交叉验证。 ##### 数据增强 数据集比较小,因此数据增强是提分的重点方向。除了torch自带的随机裁切和随机擦除以外,涨分的一大技巧是采用auto_augment。数据增强的代码如下: ```python train_transform = transforms.Compose([ transforms.Resize((size+32, size+32)), transforms.RandomChoice([transforms.RandomCrop(size, padding=1, pad_if_needed=True, padding_mode='edge'), transforms.RandomResizedCrop(size, scale=(resize_scale, 1.0), ratio=(0.8, 1.2))]), transforms.RandomHorizontalFlip(), auto_augment.AutoAugment(dataset='CIFAR'), transforms.ToTensor(), transforms.RandomErasing(p=erasing_prob), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) ``` ##### 模型选择 采用efficientnet-b5,同时增加了cbam注意力模块,代码如下: ```python class ChannelAttention(nn.Module): def __init__(self, in_planes, ratio=16): super(ChannelAttention, self).__init__() self.avg_pool = nn.AdaptiveAvgPool2d(1) self.max_pool = nn.AdaptiveMaxPool2d(1) self.fc1 = nn.Conv2d(in_planes, in_planes // 16, 1, bias=False) self.relu1 = nn.ReLU() self.fc2 = nn.Conv2d(in_planes // 16, in_planes, 1, bias=False) self.sigmoid = nn.Sigmoid() def forward(self, x): avg_out = self.fc2(self.relu1(self.fc1(self.avg_pool(x)))) max_out = self.fc2(self.relu1(self.fc1(self.max_pool(x)))) out = avg_out + max_out return self.sigmoid(out) class SpatialAttention(nn.Module): def __init__(self, kernel_size=7): super(SpatialAttention, self).__init__() assert kernel_size in (3, 7), 'kernel size must be 3 or 7' padding = 3 if kernel_size == 7 else 1 self.conv1 = nn.Conv2d(2, 1, kernel_size, padding=padding, bias=False) self.sigmoid = nn.Sigmoid() def forward(self, x): avg_out = torch.mean(x, dim=1, keepdim=True) max_out, _ = torch.max(x, dim=1, keepdim=True) x = torch.cat([avg_out, max_out], dim=1) x = self.conv1(x) return self.sigmoid(x) ``` ##### 优化器和学习率衰减 优化器采用RAdam,学习率衰减策略采用torch1.4自带的学习率自动重启的余弦衰减。 ```python optimizer = newoptim.RAdam(model.parameters(), lr=lr, weight_decay=weight_decay) scheduler = optim.lr_scheduler.CosineAnnealingWarmRestarts(optimizer, T_0=epochs//snap_num) ``` ##### 训练方法 采用三阶段训练法,每一阶段基于快照集成思想获得5个模型快照,选择acc最高的模型作为当前阶段的训练结果。具体流程如下: - Stage 1:图像输入尺寸为400,使用LabelSmooth和cutmix,采用带学习率自动重启的CosineAnnealingWarmRestarts方法,获得5个模型快照,选择val_acc最高的模型,作为Stage 1的训练结果。 - Stage 2:图像输入尺寸为500,适当调整随机裁切和随机擦除的参数,增加weight_decay,在Stage 1模型的基础上训练获得5个模型快照,选择val_acc最高的模型,作为Stage 2的训练结果。 - Stage 3:图像输入尺寸为500,关闭cutmix,损失函数采用CrossEntropyLoss,在Stage 2模型的基础上训练获得5个模型快照,选择val_acc最高的模型,作为最终的训练结果。 ### 模型性能 单模型,验证集上acc为99.4%,提交到modelarts上,测试集的acc为99.2%。由于图像分辨率较大,推理时间比较长,500张图片需要40多分钟。
举报
分享

分享文章到朋友圈

分享文章到微博

l番薯加奶

角色:成员

话题:0

发消息
发表于2020年06月11日 17:07:38
直达本楼层的链接
沙发
显示全部楼层

干货帖!学习了!

点赞 评论 引用 举报

游客

富文本
Markdown
您需要登录后才可以回帖 登录 | 立即注册