标签平滑的PyTorch实现
解决过拟合的手段有很多,比如early stopping, dropout, weight regularization,然而,这些手段无法解决模型对于标签过度自信的问题:在标签有误时,容易导致模型学习到错误的内容。
在普通的交叉熵函数中,只有预测正确的类别才会对损失作出贡献。标签平滑的思想是对标签target的onehot形式进行改造,使其取值不再是非0即1,这样,预测错误的类别也会对损失作出较小的贡献,从而迫使模型进一步学习不同类别之间的区别,避免了模型的过度自信。
使用标签平滑,只需对标签target进行变换即可,其余部分和交叉熵的计算方式是一样的,平滑后的标签如下:
$$y_{ls}=(1-\alpha)*y_{onehot}+\frac{\alpha}K$$
其中,K是类别数,$\alpha$是平滑系数,$y_{onehot}$是原始标签的onehot结果。
标签平滑的PyTorch代码实现如下:
12345678910111213141516171819import torchimport torch.nn.functional as Fdef cross_entropy_ ...
鲸鱼和海豚识别竞赛解析:上分思路
数据backfin:只保留目标的背鳍特征(通过检测的方法得到的),有点类似人脸关键点的作用。
数据增强使用:
颜色增强:
random_hue
random_saturation
random_contrast
random_brightness
几何增强:
random_flip_left_right
离线增强:
使用显著性目标检测去掉背景,得到无背景(背景变为白色)图片。统计这些图片中白色背景占比,并将占比低于某个阈值的图片取出来,添加到训练集中。
模型
EfficientNet-B5/6/7
效果相比ConvNext和SwinTransformer要好一些,且b7>b6=b5
修改:将低层特征与高层特征分别做全局平均池化,将得到的特征向量拼接在一起,作为输入图片编码后的特征向量。
ConvNext-Large/Xlarge
效果其次
SwinTransformer
效果一般。图像尺寸最大限制为384,可能是这个原因
损失函数ArcFace(s=15,m=0.3)+SoftMax,s和m这俩参数对 ...
PyTorch中的collate_fn有什么作用?
在使用PyTorch创建自定义数据集时,通常是先使用数据和标签定义一个DataSet类,然后将其传入DataLoader,这样就定义好了一个数据加载器。
对于一些简单的任务,以上操作已经足够了。但有些时候,还需要自定义DataLoader类中的collate_fn方法。
DataSet类中定义了获取单个样本的方法(自定义__getitem__),DataLoader类中定义了获取一个batch个样本的方法(相当于多次执行__getitem__),将这一个batch的样本数据传入DataLOader类中的collate_fn方法,使用collate_fn中定义的逻辑对着一个batch的样本数据做进一步的处理。
下面以目标检测为例,进一步解释自定义collate_fn的必要性。
假设batch size=2,那么一个batch的数据格式可能是这样的:
12345images:[图片1,图片2]labels:[图片1的标签,图片2的标签]其中,图片x的shape为:[3,w,h],图片x的标签的shape为:[[cls,x1,y1,x2,y2],[cls,x1,y1,x2,y2],...]
...
鲸鱼和海豚识别竞赛解析:验证&预测代码
本文的目标是对整个验证和预测的过程进行梳理,至于其中出现的一些概念,比如GeM Pooling,ArcFace等,将在后续出一篇文章进行介绍。
导入所需库12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849import osimport gcimport cv2import mathimport copyimport timeimport random# For data manipulationimport numpy as npimport pandas as pd# Pytorch Importsimport torchimport torch.nn as nnimport torch.nn.functional as Ffrom torch.utils.data import Dataset, DataLoaderfrom torch.cuda import amp# Utilsimport joblibfrom tqdm import tqdmfr ...
鲸鱼和海豚识别竞赛解析:训练代码
在上一篇文章中,我们已经介绍了赛题背景,目标任务,数据集格式以及评估指标,现在,来看看如何使用所给数据训练一个模型,来识别每张图片所对应的individual_id。
本文的目标是对整个训练过程进行梳理,至于其中出现的一些概念,比如GeM Pooling,ArcFace等,将在后续出一篇文章进行介绍。
导入所需库1234567891011121314151617181920212223242526272829303132333435363738394041424344454647import osimport gcimport cv2import mathimport copyimport timeimport random# For data manipulatiimport numpy as npimport pandas as pd# Pytorch Importsimport torchimport torch.nn as nnimport torch.optim as optimimport torch.nn.functional as Ffrom torch.optim ...
鲸鱼和海豚识别竞赛解析:全流程概述
背景描述我们可以使用人类的指纹和面部特征来识别具体的人(指纹识别,人脸识别),类似地,我们也可以根据海洋生物的尾巴,背鳍,头部等特征识别并跟踪海洋生物。
然而,依赖于研究人员人眼观察的识别方法效率太低,而借助自动化鲸鱼和海豚识别模型,研究人员可以将图像识别时间减少99%以上。
查看数据集数据集格式如下:
其中,test_images和train_images文件夹中分别存储了测试图片和训练图片,就像这样:
train.csv总共有3列,如下:
第一列是图片文件名(image),第二列是该图片中的生物所属种类(species),第三列是该图片中的生物的专属id(indivadual_id)。
sample_submission.csv是所需提交文件的样例,包含每张图片对应的预测结果,由于题目需要预测的是该图片最有可能属于的前5个individual_id,因此这里的predictions中包含5个不同的indivisual_id:
任务描述使用train_images作为训练集,对test_images中的每张图片中的生物individual_id进行预测。
每一个生物个体对应一个不同的 ...
交叉验证时划分数据的方式
交叉验证是机器学习中常用的一种策略,其核心是对数据集进行划分,本文介绍sklearn中的3种交叉验证时划分数据集的方法:
123KFoldStratifiedKFoldGroupKFold
这里来举例说明各个方法的使用。
先来导入这些方法,并创建一个简单的数据集:
12345from sklearn.model_selection import KFold,StratifiedKFold,GroupKFoldx=[1,2,3,4,5,6,7,8,9,10]# 特征y=[0,0,0,0,0,1,1,1,1,1]# 标签group=['a','a','a','b','b','b','b','c','c','c']# 样本所在的组
KFoldKFold只需要特征x就能够完成数据划分
123kf = KFold(n_splits=3,shuffle=True)# n_splits不能超过总的样本 ...
目标检测:Two-stage
RPN寻找每一个anchor匹配到的GT box,所以是多对一(不一定每个anchor都能找到匹配的GT box,原因见第三行)
假设有m个GT box,n个anchor,则有一个mxn的矩阵M, M[i,j]代表第j个anchor与第i个GT box之间的IOU
anchor和GT box的IOU大于0.7,则该anchor为正样本,小于0.2则该anchor为负样本,其余不考虑直接忽略该anchor(除非启用set_low_quliaty,解释:注意还有一个特殊情况,可能有一个gt没有与之匹配的anchor,即该groud-truth和所有的bbox的iou都小于high_threshold,那么我们允许“与这个gt最大iou的bbox”被认为是正样本,确保每个gt都有配对的bbox)
之后再使用nms过滤得到包含正样本和负样本的anchor
最终的正负样本数量是不一致的,并且负样本数量远远大于正样本数量(emm,也不完全是)
选取一定数量的正负样本anchor用于loss计算(可以控制正负样本比例以及正负样本的总个数,比如总个数是256,正负样本比例是0.5,如果正样本不足128 ...
ToothSeg项目总结
项目目标是打造一款牙齿分割器,它可以将一张人脸露齿图分割成共3个类别:上牙,下牙以及其他。
采集露齿微笑的图片作为样本,每个人通过摆出不同嘴型来贡献多个样本。在剔除牙齿比较模糊的图片后,总共得到2000+样本,使用labelme进行标定。
将标定好的数据处理成PascalVOC格式。
按照8:2划分训练集和验证集,基于DeepLabV3+搭建baseline.
输入网络的图片是512*512的。
数据增强:
随机翻转
随机旋转
随机模糊
中心随机裁剪
mIoU=0.8638.
修改网络结构:参考fpn的思想,原先的网络只使用了backbone提取的特征图的高层信息和低层信息,我们把中间层的信息也提取出来,自上而下的进行特征融合(插值上采样,求和或拼接),代码实现在decoder模块中。
mIoU=0.874,有提升。
将交叉熵损失改为Focal Loss,mIoU不升反降,由于调参花费时间会较长,因此不用Focal Loss.
将交叉熵损失改为dice,mIoU=0.8812.
为了使得边缘更平滑,设计了如下方案:
1)制作边缘掩码。具体地,以mask中每个像素点在坐标轴上的位置 ...