点击上方“小白学视觉”,选择加"星标"或“置顶”
重磅干货,第一时间送达
作者: 马东什么 @知乎(已授权CV技术指南转载)
来源:https://zhuanlan.zhihu.com/p/604384546
仅用于学术分享,若侵权请联系删除
论文:
https://www.kaggle.com/code/markpeng/deepinsight-transforming-non-image-data-to-images/notebook
代码:
https:github.com/alok-ai-lab/pyDeepInsight/blob/master/pyDeepInsight/utils.p
下面根据官方提供的example来梳理一下整个流程
这里用的data是简单的iris数据集,150个样本,每个样本4个特征
第一步 归一化
因此第一步首先需要对每个特征进行minmaxscaler标准化,即将每个特征的取值区间压缩到0~1之间,源代码的实现为:
主要逻辑就是每个特征减去它的最小值(避免特征里有负数的情况,减去最小值之后原始特征就非负了),然后除以它的最大值,中间额外插入了一个log变换以平滑特征的分布没什么问题。
第二步 将特征映射到2维空间
这个地方比较脑洞大开,具体是这么做的:
首先,这里的self._fe 是一个降维的sklearn 式的model,源代码中提供了pca,kernelpca和tsne,但是实际上作者也提到umap之类的降维方法也是可以的;
这里输入的x是一个m行n列的矩阵,表示m个样本和n个特征,然后先做了转置 变成了n行m列的矩阵,表示有n个特征,每个特征对应m个样本点,然后使用reduction model降维到2维,变成了一个n行2列的新矩阵。
这里有4个特征,每个特征对应两个"样本维度",自然可视化之后是4个point了..
可以看到,这玩意儿一开始是在样本维度做的压缩。。然后就是用凸包算法ConvexHull(scipy里的一个工具组件),找到能够恰好囊括这4个"样本降维"之后的特征点的矩形
这里特征只有4个,所以看起来比较清晰,原文中用到了很多特征,就长这个样子的:
到这一步,我们可以看到,每个特征都被映射为一个2维的坐标嵌入到一张灰度图里作为一个pixel存在,最终我们会得到了每个特征pixel在上述的image中对应的坐标coord.
实际上早期就已经有类似的工作了,类似于supertml的思路(当然supertml要复杂点),更加简单,直接把特征reshape到一个image里,例如我的输入特征是2500维,直接reshape成一个50X50的灰度图,当然这种方法肯定不靠谱了.
因为image中,像素点是在同一个语义空间里的,即每个像素点的取值范围是固定的,并且意义也是固定的,他们属于同源的数据,但是tabular data中,每个特征之间的语义是存在差异的,往往是不同语义空间的下的概念,例如 年龄和收入这两个特征,即使做了0~1标准化强制转化到同一个量纲,直接reshape到一张image里也是意义不大,不make sense的.
而这里的大体思路就是把特征当作样本features2samples,把样本当作特征samples2features,然后可以看作是将features2samples做2维的embedding,在这个2维的embedding空间中,不同的features2sample的embedding vectors之间的距离应该满足某种规律,至于是什么规律..完全取决于上游使用的降维的方法.
原文中是没有做什么明确定义,就是用了几种常见的降维方法来实现embedding的功能;
第三步 根据第二步获取的特征的坐标,将原始样本进行转换
具体的首先是:
这里第0列和第1列是feature pixel的坐标,其它列对应的是不同的样本,原始的x_norm有150个样本,因此这里加上2维的坐标一共是152列,然后做了一个groupby的操作, 即如果有n个特征的feature pixel对应的坐标恰好相同,则直接聚合成一个column,这个过程中,实际上类似于做feature selection,n个特征的feature pixel重合则认为这些feature之间基本没有差异,对应的聚合的单个的新pixel对应的取值则为n个特征的均值
剩下的就没啥了,把每个样本按照4个feature对应的坐标依次填入image中即可,完整代码如下
一些个人的见解
一个很有意思的地方在于,视觉分类模型,将一张image转化为一个向量,而deep insight做的事情则是相反的,将一个向量转化为一张image(虽然按照原文的逻辑,目前暂时只是单通道的灰度图);
image to vector的过程是自适应的,例如猫的image产生的vectors可能是非常相似的,而vector 到image的过程,deepinsight中的实现则是固定的,整个过程就是将一个样本的每个特征转化为一个二维的坐标(x1,x2),这个2维的坐标代表了一张灰度图上的一个pixel的取值(所以前面会先去做0,1标准化,因为只需要乘以255再round一下就可以转化为具有实际意义的像素值了),m个特征对应m个pixels,因此一个样本最终是转化为m个pixels了;
需要注意的是,m个特征对应的pixel 坐标是固定的,因此最终所有样本转化为的image,在轮廓上是完全相同的,只不过不同pixel的像素值存在差异,这里比较关键的地方在于 feature 到pixel的坐标的这个转换过程,deepinsight的核心,就是去求解这个转换的function要怎么保证信息的损失少。比如说你原来100个特征,转化为具体的坐标之后,有50个特征对应的pixel的坐标是完全重合的,那信息的损失就比较大了(这里假设50个特征之间是正交的,都具有不同角度的信息)
原文是直接用了一些常见的降维的方法去简单实现了2维坐标转换的这么一个过程,没有太多深度探讨为什么这么转有效的理论解释,只是贴了图,描述了具体的结果.其实,之前的1dcnn的做法,类似,1dcnn是直接把原始的特征转化为一个超大的向量,然后reshape成图片,因此整个转换的过程是纯粹自适应的,但是这也导致了超大的参数量。按照常用的 224,224,3通道的结构,这里假设输入特征只有100维,则对应的参数量都有15,052,800 个了...
下载1:OpenCV-Contrib扩展模块中文版教程
在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。
下载2:Python视觉实战项目52讲
在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。
下载3:OpenCV实战项目20讲
在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。
交流群
欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~