Kaggle座头鲸识别赛

9 篇文章 0 订阅
3 篇文章 0 订阅

本文节选自我的博客:Kaggle 座头鲸识别赛

  • 💖 作者简介:大家好,我是MilesChen,偏前端的全栈开发者。
  • 📝 CSDN主页:爱吃糖的猫🔥
  • 📣 我的博客:爱吃糖的猫
  • 📚 Github主页: MilesChen
  • 🎉 支持我:点赞👍+收藏⭐️+留言📝
  • 💬介绍:The mixture of WEB+DeepLearning+Iot+anything🍁

whale是kaggle比赛鲸鱼图像识别的简化版,本文是对Top3大神pudae算法复现。

来自19年的黑龙江省人工智能大赛。本文本文涉及的代码与素材均在这里获取,如果对您有帮助,麻烦帮我点个star

描述

为保护濒临灭绝的鲸类资源,1946 年由 15 国政府签署了国际捕鲸公约,我国也在 1980 年成为该公约的成员国。自国际捕鲸公约生效半个多世纪过去了,某些国家以各种理由进行的捕鲸活动仍在继续,鲸鱼种群仍然需要我们的保护。为了帮助保护鲸鱼,科学家们利用监控摄像机观察海面,在鲸鱼出水时拍摄下它们的尾巴。接下来,利用每条鲸鱼尾部不同的纹理图案,来识别鲸鱼的品种以总结鲸鱼族群的变化与移动规律。40 年来,这项工作几乎是用方式、由若干科学家单独完成的,因此遗留下来许多未标记、未利用的数据。

来自19年的黑龙江省人工智能大赛

result

最终验证数据集共有423张图共50类。Acc:0.9713,AUC:0.9985,耗时65s。

快速上手

  1. 环境安装

注意pytorch要单独先安装torch >= 1.7.0
pip install -r requirements.txt

  1. 训练
    在fcn目录下执行,训练语义分割模型
    python train.py
    在根目录下执行,训练语义分割模型
    python train.py

  2. 使用模型
    启动本地客户端ui
    python verify.py

技术路线

数据增强

编写Python脚本对数据预处理,并将图片进行分组,数据增强。将数据集进行分组,便于模型搭建和训练,由于数据集稀缺,合理使用数据增强可以提高模型的泛化能力。使用torchvision、Pillow、OpenCV模块对原始数据集数据增强。原图片如图,

数据增强:

  • 降噪 采用3*3高斯滤波最优 filter过大图片会模糊;
  • 去雾 由于海上拍摄受天气影响,故需要去雾;
  • 翻转 翻转后的鲸鱼可以认为是一个新的样本,随机水平翻转;
  • 旋转 左右随机旋转10度
  • 灰度化 由于很多黑白训练图片,将图片随机灰度化增加训练数据集
  • 亮度 由于拍摄角度和时间导致亮度问题,随机按一定阈值调节亮度
  • 对比度 对图片的对比度调节

模型结构

使用FCN语义分割,FCN的卷积网络部分我们采用VGG-19作为前置基础网络,在这些的预训练基础上进行迁移学习与调优,对反卷积的结果跟对应的正向feature map进行叠加输出(这样做的目的是得到更加准确的像素级别分割)。使用FCN语义分割后的mask图形与原来的3通道图片合并,作为四通道输入,传入ResNet18训练分类。模型结构如图

模型参数调优过程

这一节中我们将介绍我们是如何经过参数和超参数调优将原来的ResNet18 0.6的准确率,提升到0.89的准确率,训练过程中的加速技巧。

模型结构调优

们选定好基础模型后,先修改模型结构,将第一层模型结构 (-1,3,300,300) 修改为(-1,4,300,300)的shape作为输入层,因为新增加了一层FCNmask特征,原来的RGB三通道基础之上加一层,故一共有四个通道作为输入层。
重写全连接层,因为原有模型是分为1000类,不适合本赛题需求,故我们修改了全连接层,最后分为50类。
我们尝试修改中间的卷积层层数,卷积核的大小,模型都没有提升,准确率还下降了不少。经过我们的研究发现,我们使用的预训练权重值,对改动较大的网络不再适用。

使用预训练模型

不使用预训练模型如图左,使用预训练模型如图右。

使用预训练模型能极大节省训练时间。如果不使用迁移学习的思想,训练几天也训练不出如此高准确率的网络,训练过程中需要设置运行前向传播参数更新,如果一昧使用原始参数,只训练全连接参数,模型的准确率只能达到0.7左右,最终还是选择重新训练一个新模型。

图片输入的Size

送入模型的Size大小也决定着模型的准确率,我们尝试过512512的作为图片输入的大小,训练时间也大幅度增加了,模型的准确率却只有0.52。使用256256的模型准确率为0.73,由于许多鲸鱼尾巴图片都长大于宽度,我们选用512256作为图片输入大小模型准确率提升到0.77,我们又尝试400400的准确率为0.76,300*300的准确率提升到了0.80,即我们最终使用的输入Size大小。

模型的BatchSize

BatchSize的大小决定模型梯度下降的方向,BatchSize越大模型梯度下降的方向越准确,所以我们希望将BatchSize调大,但由于GPU内存不够,我们最大调到了BatchSize=20。

学习率

学习率决定着梯度下降的速度,我们尝试将学习率调小,就需要更多的训练模型的时间,使用更大的学习率,测试准确率就得不到提高,经过权衡之下我们选择0.001作为本次模型的初始学习率。

梯度下降方式

开始我们使用SGD(随机梯度下降优化器)梯度下降的速度较快,但出现了损失值为nan 的情况,之后又改为Adma优化算法,能自动调整学习率大小。

数据增强方式

开始我们在数据预处理脚本中增加了数据增强 ,使用这种方式,会生成大量图片,严重浪费磁盘空间和读取时间。因此我们将数据增强与模型训练代码合成到一起。每次加载同样的数据,在进行数据增强变化,再送入到模型中去训练。这样可以进一步增强模型的鲁棒性、和适应性。

训练内存优化

开始我们边测试边加载数据集,优化后是开始训练时,一次性将所有测试数据集加载到内存中并转换为tensor,这样能减少重复加载数据,一定程度上减少训练模型的时间。由于测试数据集需要数据增强,所以没有一次性加载到内存中。

遇到的问题

在数据预处理过程中出现PIL、CV2、tensor相互转换问题

经过不断的调试我们发现,PIL与CV2和图片的shape完全一样,后我们将他们转换为numpy观察原始数据发现,两种数据格式的3通道排序恰好相反,我们将通道按照合理格式排序后便可以正常转换。

训练数据过程中模型不拟合问题

在搭建初级模型中,我们出现了数据拟合,测试数据集的准确率始终为0,开始我们一直怀疑是模型的问题,我们有简单搭建了其他模型,发现都会出现同样的问题,我们有开始怀疑是数据集的问题,我们不断观察数据集,发现每一个分类的数据确实有相同的数据特征。接着开始怀疑自己的标签问题,通过观察csv文件的标签,确实是csv标签的问题,检查代码发现,生成label标签的变量写错了,修改后即解决。

数据类型的转换问题

Tensor、numpy的数据类型转换,要注意他们的类型、维度,必要时将他们转换成列表数据逐个观察。

GPU上tensor取不出问题

output.cpu().detach() 使用detach截断反向传播的梯度流、不使用这个GPU的tensor取不出来。

模型过大问题

理论上使用ResNet模型层数越高,模型越复杂,模型分类的效果越好。由于我们受限于工作站硬件配置,优化过许多更为高级的模型,但效果仍然不够理想

优化方向

鲸鱼尾巴的位置和大小都不固定,这可能是影响准确率的原因之一,所以有下面几个优化方向

  • 加入attention机制 让模型自己去寻找尾巴的位置,提高识别准确率;
  • 训练自动定位box的模型,如YOLO3, Faster RCNN等;
  • 训练组合模型,将VGG,RESNET,inceptionv3经过我们的数据集预训练后,再组成一张大网络训练。

如果你觉得本文对你有所帮助,别忘记给我点个start,有任何疑问和想法,欢迎在评论区与我交流。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值