经典目标检测
RCNN首先,使用Selective Search算法,从图片中裁出来N个小区域图像
然后将者N个小区域图像分别使用CNN提取得到D维的特征向量。至此得到了NxD的矩阵,该矩阵包含每个小区域对应的D维特征向量
接着,将NxD的矩阵分别使用k个SVM分类器(Dxk)进行分类,得到Nxk的矩阵,即每个小区域图像的分类结果(k个类别,取概率最大的作为预测类别)。在得到每个小区域图像的预测类别后,可能存在同一个目标被多个小区域图片同时预测到的情况,因此还需要针对每个类别对应的小区域图像做一个NMS后处理。
最后,对于NMS后保留下来M(M<=N)个的小区域图像,先按照这些建议框(小区域图像)与GT之间的IoU做一个过滤,保留IoU大于阈值的建议框,然后将每个建议框对应的D维特征向量输入回归器,得到修正后的建议框位置。这里,和分类器个数一样,总共设置了k个回归器,各自负责不同类别(上一步预测得到的类别)的建议框位置修正。
RCNN存在的问题:
测试速度慢(SS算法提取候选框很慢)
训练速度慢(CNN,SVM分类器,回归器)
训练所需空间大(需要将目标框的小区域提取特征并写入磁盘)
Fa ...
chatGPT是怎样炼成的
chatGPT会写作业,写代码,写文案,写提示词喂给AI绘画模型来作画,各种各样的玩法,使得chatGPT成为了一个”得力助手”,微软也在自家的搜索引擎Bing中引入了chatGPT,大有要引领搜索引擎新未来的趋势,chatGPT(或者类似的模型)正逐步走向大众视野。
在体验过chatGPT后,可以明显感觉到,对方不再像是各大手机厂商的智能语音助手,而是一个可以结合对话上下文语境实现真正连续对话的”机器人”。
是什么使得chatGPT脱颖而出呢?
这还要从许多年前讲起。
chatGPT的前身是GPT模型,GPT的全称是Generative Pre-trained Transformer,这是一种生成模型,采用自回归的方式来不断的生成新的内容:
$$P_{\theta}(x_{t+1}|x_1,x_2,…,x_{t})$$
将上式中的$x$看作是模型生成的字,那么$x_i$就表示模型生成的第$i$个字,在生成第$t+1$个字时,模型需要将${x_i}^{t}_{i=1}$作为输入。
可以看到,在模型的一次预测中,后面文字的生成依赖于之前生成的内容,chatGPT也继承了这一特点,这也是为 ...
都2023了,你还在用tqdm做进度条吗
谈到Python的进度条,相信大家用的最多的就是tqdm库了,比如这样:
1234import timefrom tqdm import tqdmfor i in tqdm(range(20)): time.sleep(1)
运行上述代码,便可以看到如下的进度条:
今天要分享的是另外一款Python进度条,相较于老前辈tqdm,在视觉效果上更加炫酷,话不多说,开整!
这款进度条依赖于rich库中的progress模块进行实现,所以第一步就是安装rich库,直接pip install rich即可搞定。
在完成rich库的安装后,就可以实现一个简易的Python进度条啦:
12345import timefrom rich.progress import trackfor i in track(range(20), description="Processing..."): time.sleep(1)
效果如下:
也可以同时展示多个任务进度条:
12345678910111213141516import timefrom rich.progress i ...
为ONNX设置动态输入
在使用torch自带的方法将训练好的权重文件转换成onnx格式时,输入的张量可以是静态的,也可以通过一些设置修改成动态的。
静态:在导出onnx时传入输入尺寸,在之后的预测过程中也必须使用相同尺寸的输入。
这种方法对于像分割检测这种任务不太友好,我们希望模型能够自适应输入尺寸,所以需要设置成动态输入形式。
设置方法也很方便,只需在导出时传入dynamic_axes,指定要动态输入的维度即可。
123456789101112131415161718192021222324252627282930313233343536373839404142434445import argparseimport osimport numpy as npimport timeimport cv2from modeling.deeplab import *from dataloaders import custom_transforms as trfrom PIL import Imagefrom torchvision import transformsfrom dataloaders.utils imp ...
VIT如何处理不同尺寸的输入图片?
假设vit的输入图片尺寸是224,将图片分为固定大小的patch,patch大小为patch_size=16x16
则每张图像会生成224x224/16x16=14*14=196个patch, 每个patch的长度是16*16*3=768
这里还需要加上一个特殊字符cls,因此最终的维度是197x768
相当于NLP中一个句子有197个单词,每个单词的embedding dim是768
现在,保持patch size不变,将输入图片尺寸改成288*288
当输入图片尺寸发生变化时,由于每个 patch 的尺寸固定,图片切分出的 patch 数就会发生变化。表现在上述特征图中,就是特征图的尺寸发生了变化。这样一来,我们原本位置编码图的尺寸就和图像特征图的尺寸对不上了,无法进行后续的计算。
找到了问题所在,解决的方法也就顺理成章了。位置编码代表的是 patch 所在位置的附加信息,那么如果和图像特征图的尺寸不匹配,只需要使用双三次插值法(Bicubic)对位置编码图进行插值缩放,缩放到与图像特征图一致的尺寸,就同样可以表现每个 patch 在图片中的位置信息。
12345678910111 ...
Kaggle-GI-Tract竞赛-EDA
每个case都对应若干Day的若干个scan得到的slices,在train.csv中,每个case-Day-slice占3行,分别对应3个类别(大肠、小肠、胃)的标注信息
因此,在制作每一个case-Day-slice的mask时(制作1D数据),这三行分别作为mask的一个通道,因此mask是3个通道的:
1234567891011def id2mask(id_): idf = df[df['id']==id_] wh = idf[['height','width']].iloc[0] shape = (wh.height, wh.width, 3) mask = np.zeros(shape, dtype=np.uint8) for i, class_ in enumerate(['large_bowel', 'small_bowel', 'stomach']): cdf = idf[idf['class ...
权重衰减和L2正则化
权重衰减是在更新模型的参数时,对当前参数乘以一个系数,公式如下:
而L2正则化是在损失函数后面加一项约束,如下:
在使用SGD作为优化器,且满足$\lambda’=\frac{\lambda}{\alpha}$时,权重衰减和L2正则化等价,证明如下:
参考:
[1] https://blog.csdn.net/weixin_41803874/article/details/108730883
[2] https://zhuanlan.zhihu.com/p/498372080
[3] https://arxiv.org/pdf/1711.05101.pdf
标签平滑的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],...]
...