何时才能继续wwW722gancom欣赏,里面的180WE那写节目com呀

&figure&&img src=&https://pic2.zhimg.com/v2-5d7bdf540c0f0c79f3c386_b.jpg& data-rawwidth=&946& data-rawheight=&618& class=&origin_image zh-lightbox-thumb& width=&946& data-original=&https://pic2.zhimg.com/v2-5d7bdf540c0f0c79f3c386_r.jpg&&&/figure&&h2&一、入门&/h2&&figure&&img src=&https://pic2.zhimg.com/v2-4dc4eec723eb3bda4e65ca_b.jpg& data-rawwidth=&946& data-rawheight=&335& data-caption=&& data-size=&normal& class=&origin_image zh-lightbox-thumb& width=&946& data-original=&https://pic2.zhimg.com/v2-4dc4eec723eb3bda4e65ca_r.jpg&&&/figure&&p&  图中的细实线箭头表示了四种一阶微分运算,包括梯度、散度、旋度和 Jacobian。每条箭头的起点表示了相应运算的自变量的类型,终点表示了相应运算的因变量的类型,例如梯度运算是作用在标量上的,结果是向量。图中的「向量」默认为列向量。&/p&&p&  这四种一阶微分运算可以统一用算符 &img src=&https://www.zhihu.com/equation?tex=%5Cnabla& alt=&\nabla& eeimg=&1&& (读作 nabla)表示。Nabla 算符是一个形式向量 &img src=&https://www.zhihu.com/equation?tex=%5Cnabla+%3D+%5Cleft%5B%5Cfrac%7B%5Cpartial%7D%7B%5Cpartial+x%7D+%5Cquad+%5Cfrac%7B%5Cpartial%7D%7B%5Cpartial+y%7D+%5Cquad+%5Cfrac%7B%5Cpartial%7D%7B%5Cpartial+z%7D+%5Cright%5D%5ET& alt=&\nabla = \left[\frac{\partial}{\partial x} \quad \frac{\partial}{\partial y} \quad \frac{\partial}{\partial z} \right]^T& eeimg=&1&& ,它可以如下地作用于标量 &img src=&https://www.zhihu.com/equation?tex=f& alt=&f& eeimg=&1&& 或向量 &img src=&https://www.zhihu.com/equation?tex=%5Cvec%7Bv%7D& alt=&\vec{v}& eeimg=&1&& 上:&/p&&ul&&li&直接与标量 &img src=&https://www.zhihu.com/equation?tex=f& alt=&f& eeimg=&1&& 相乘,得到 &img src=&https://www.zhihu.com/equation?tex=f& alt=&f& eeimg=&1&& 的梯度 &img src=&https://www.zhihu.com/equation?tex=%5Cnabla+f& alt=&\nabla f& eeimg=&1&& 。&/li&&li&与向量 &img src=&https://www.zhihu.com/equation?tex=%5Cvec%7Bv%7D& alt=&\vec{v}& eeimg=&1&& 点乘,得到 &img src=&https://www.zhihu.com/equation?tex=%5Cvec%7Bv%7D& alt=&\vec{v}& eeimg=&1&& 的散度 &img src=&https://www.zhihu.com/equation?tex=%5Cnabla+%5Ccdot+%5Cvec%7Bv%7D& alt=&\nabla \cdot \vec{v}& eeimg=&1&& 。本文把点乘用矩阵乘法的形式写作 &img src=&https://www.zhihu.com/equation?tex=%5Cnabla%5ET+%5Cvec%7Bv%7D& alt=&\nabla^T \vec{v}& eeimg=&1&& 。&/li&&li&与向量 &img src=&https://www.zhihu.com/equation?tex=%5Cvec%7Bv%7D& alt=&\vec{v}& eeimg=&1&& 叉乘,得到 &img src=&https://www.zhihu.com/equation?tex=%5Cvec%7Bv%7D& alt=&\vec{v}& eeimg=&1&& 的旋度 &img src=&https://www.zhihu.com/equation?tex=%5Cnabla+%5Ctimes+%5Cvec%7Bv%7D& alt=&\nabla \times \vec{v}& eeimg=&1&& 。&/li&&li&若允许偏导算符写在变量的右边,则 &img src=&https://www.zhihu.com/equation?tex=%5Cvec%7Bv%7D%5Cnabla%5ET& alt=&\vec{v}\nabla^T& eeimg=&1&& 就可以表示 &img src=&https://www.zhihu.com/equation?tex=%5Cvec%7Bv%7D& alt=&\vec{v}& eeimg=&1&& 的 Jacobian。&/li&&/ul&&p&  图中的粗实线箭头表示了两种二阶微分运算,它们可以由两个一阶微分运算组合而成,即:&/p&&ul&&li&梯度的散度就是 Laplacian;&/li&&li&梯度的 Jacobian 就是 Hessian。&/li&&/ul&&p&  图中的虚线箭头表示了一种不涉及微分的运算(迹)。在微分运算之后接上「迹」运算,可能得到另一种微分运算,如:&/p&&ul&&li&Jacobian 的迹就是散度;&/li&&li&Hessian 的迹就是 Laplacian。&/li&&/ul&&h2&二、入迷&/h2&&figure&&img src=&https://pic1.zhimg.com/v2-bbd4ee781adbcfaa8f26dc9_b.jpg& data-rawwidth=&946& data-rawheight=&547& data-caption=&& data-size=&normal& class=&origin_image zh-lightbox-thumb& width=&946& data-original=&https://pic1.zhimg.com/v2-bbd4ee781adbcfaa8f26dc9_r.jpg&&&/figure&&p&  图中的四种一阶微分运算两两搭配,一共可以得到 7 种二阶微分运算。第一节的图中画出了两种,本节的图中画出了另外五种(浅蓝色与灰色)。这五种二阶微分运算并没有特别的名字,但其中有两种是恒等于 0 的:&/p&&ul&&li&梯度的旋度恒为零向量;&/li&&li&旋度的散度恒为 0。&/li&&/ul&&p&其中,「梯度无旋」可以用下面的图形象说明(图片来自 &a class=&member_mention& href=&https://www.zhihu.com/people/093c08f1e265b2e37b97da22d5351933& data-hash=&093c08f1e265b2e37b97da22d5351933& data-hovercard=&p$b$093c08f1e265b2e37b97da22d5351933&&@得分的&/a& ):&/p&&figure&&img src=&https://pic3.zhimg.com/v2-9eac5c191ebc56b94b57f2c6f2fab1cc_b.jpg& data-rawwidth=&580& data-rawheight=&328& data-size=&normal& class=&origin_image zh-lightbox-thumb& width=&580& data-original=&https://pic3.zhimg.com/v2-9eac5c191ebc56b94b57f2c6f2fab1cc_r.jpg&&&figcaption&如果梯度有旋会怎么样?&/figcaption&&/figure&&h2&三、入魔&/h2&&figure&&img src=&https://pic2.zhimg.com/v2-997a5c9b085412cfca3d8be6abe9fb26_b.jpg& data-rawwidth=&946& data-rawheight=&547& data-caption=&& data-size=&normal& class=&origin_image zh-lightbox-thumb& width=&946& data-original=&https://pic2.zhimg.com/v2-997a5c9b085412cfca3d8be6abe9fb26_r.jpg&&&/figure&&p&  Laplacian 是一个作用于标量的二阶微分运算,其结果也是标量。但我们也可以把它作用于一个向量的每一个元素,得到一个向量;这种运算称为向量 Laplacian。&/p&&p&  Laplacian 运算作用于标量 &img src=&https://www.zhihu.com/equation?tex=f& alt=&f& eeimg=&1&& 上的结果可以用 nabla 算符写成 &img src=&https://www.zhihu.com/equation?tex=%5Cnabla%5ET+%5Cnabla+f& alt=&\nabla^T \nabla f& eeimg=&1&& 。这种写法无法直接推广到向量 Laplacian,因为 &img src=&https://www.zhihu.com/equation?tex=%5Cnabla%5ET+%5Cnabla+%5Cvec%7Bv%7D& alt=&\nabla^T \nabla \vec{v}& eeimg=&1&& 里 &img src=&https://www.zhihu.com/equation?tex=%5Cnabla& alt=&\nabla& eeimg=&1&& 无法直接跟 &img src=&https://www.zhihu.com/equation?tex=%5Cvec%7Bv%7D& alt=&\vec{v}& eeimg=&1&& 做矩阵乘法。但如果允许偏导算符写在变量右边,那就可以把向量 Laplacian 表示成 &img src=&https://www.zhihu.com/equation?tex=%5Cvec%7Bv%7D+%5Cnabla%5ET+%5Cnabla& alt=&\vec{v} \nabla^T \nabla& eeimg=&1&& 。这是 Jacobian 运算与「矩阵右乘 &img src=&https://www.zhihu.com/equation?tex=%5Cnabla& alt=&\nabla& eeimg=&1&& 」运算的复合;后者的效果是对矩阵的每一行求散度。图中恰好有一个为「逐行散度」运算准备的空位,我们把它补充到图中。&/p&&p&  向量 Laplacian 的结果,恰好等于「散度的梯度」与「旋度的旋度」之差。为了体现出这种关系,我把「从向量到向量」的三种二阶微分运算改用橙红色箭头表示。&/p&&h2&四、入土&/h2&&figure&&img src=&https://pic4.zhimg.com/v2-a3fadc57861cbd8ee35a0ea35bdc6caf_b.jpg& data-rawwidth=&946& data-rawheight=&618& data-caption=&& data-size=&normal& class=&origin_image zh-lightbox-thumb& width=&946& data-original=&https://pic4.zhimg.com/v2-a3fadc57861cbd8ee35a0ea35bdc6caf_r.jpg&&&/figure&&p&  既然引入了「逐行散度」这个一阶微分运算,那就索性把它能组合出来的二阶微分运算也全都放到图里去吧!这样就得到了一个完美对称的图,它包含了 11 种二阶微分运算,其中:&/p&&ul&&li&有两种比较常见:Laplacian 和 Hessian;&/li&&li&有两种恒等于零:「梯度的旋度」和「旋度的散度」;&/li&&li&有三种满足减法关系:向量 Laplacian = 梯度的散度 - 旋度的旋度;&/li&&li&剩下的四种没有专门的名字,也很罕见。&/li&&/ul&&p&  其中任何一种微分运算后面接上「迹」,都可以得到另一种同阶微分运算:&/p&&ul&&li&Jacobian 的迹就是散度;&/li&&li&Hessian 的迹就是 Laplacian;&/li&&li&旋度的 Jacobian 的迹就是旋度的散度,恒等于 0;&/li&&li&矩阵逐行散度的 Jacobian 的迹,就是它的逐行散度的散度。&/li&&/ul&&p&但需要注意只能在运算之后接上「迹」,在运算之前接「迹」是不行的,比如矩阵的迹的梯度不等于它的逐行散度。&/p&&p&  如果有读者知道图中几种没有名字的运算叫什么名字、有什么用途,或者在图中内容之外还有什么值得包括进来的微分运算,欢迎补充。&/p&
一、入门 图中的细实线箭头表示了四种一阶微分运算,包括梯度、散度、旋度和 Jacobian。每条箭头的起点表示了相应运算的自变量的类型,终点表示了相应运算的因变量的类型,例如梯度运算是作用在标量上的,结果是向量。图中的「向量」默认为列向量。 这四种…
&p&最近准备正儿八经的搞点事,琢磨着也发点paper,经常action,接地气的解决实际问题,别人还以为我是deeplearning的民间玩家。&/p&&p&&br&&/p&&p&正好腾讯AI lab刚发了波CVPR,找了找发现有一篇我觉得好玩的。结果一看,发现跟我之前看的文章类似,顺藤摸瓜,我发现3篇文章其实讲的都是一回事情。&/p&&p&&br&&/p&&p&1、cosFace:Large Margin cosine loss for deep face recognition (tencent AI lab) 1月29&/p&&p&2、ArcFace: additive angular margin loss for deep face recognition (deepInsight) 1月23&/p&&p&3、additive margin softmax for face verification (happynear) 1月18&/p&&p&&br&&/p&&p&不过腾讯发文章的时候特意说了,他们的文章17年就出来给同行看了。刷榜的结果也是17年提交的。&/p&&p&&br&&/p&&p&昨天跟第三篇的小哥凌晨扯了好久,这小哥是个等着毕业,期待博士期间发篇CVPR的博士。So,这个idea是不可能再中CVPR了。。。&/p&&p&&br&&/p&&p&论文原地址自己查一下吧。翻译的活我也不干了。&/p&&p&&br&&/p&&p&先说说为啥这3篇文章是一回事呢,本质上的工作就是loss函数的变化。&/p&&p&1、cos θ1 -m = cos θ2
&/p&&p&2、Cos(θ +m) &/p&&p&3、Cos θ - m&/p&&p&&br&&/p&&p&第二篇文章号称比第3篇文章刷榜的效果好,估计是因为他在网络结构上花了点花招吧。按损失函数来说,应该是一回事。你想,2是改变角度的大小,改变角度大小的本质不就是改变cos函数值的大小吗?跟在外面加个常量改变函数值的大小本质是一样的。&/p&&p&&br&&/p&&p&前面这些话算是个引子,总起了一下。接下来以第1篇为例,讲讲 他们所谓的 cos θ +m&/p&&p&是怎么回事。我发现腾讯AI lab写的文章是这个三篇里面最清晰的,条理分明,一点即透。个人看法,讲真我也是昨天才刚开始看这玩意。&/p&&p&&br&&/p&&p&先说清楚,我的文章不能代替你看原论文,我的文章相当于是论文讨论会,大家看过论文后,一起反刍讨论而已。也许看了我的文章会给你一些启发,可以让你一些思路连成片,当然,如果写错了就帮我纠正。&/p&&p&&br&&/p&&p&深度学习界从开始到现在,所有的论文基本就干了两件事情,一、发现一个牛逼的网络结构,提高了网络的表达能力;二、发现了一个好玩的损失函数,提升了模型的鲁棒性和精度。人脸识别的优化方向就两个,一是不断增大不同人之间的距离,二是不断降低一个人不同人脸照片之间的距离。 center loss 和 tripleloss都是干这个事情。但他们损失函数的根基还是softmax的交叉熵,现在,这三篇文章琢磨的是把这个根基变一变,从而扩大分类面之间的margin。这样就自然达到了上面两个方向的目的了。是不是?&/p&&figure&&img src=&https://pic4.zhimg.com/v2-a31160ece7d301f63f8f05be5d6198fe_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&558& data-rawheight=&585& class=&origin_image zh-lightbox-thumb& width=&558& data-original=&https://pic4.zhimg.com/v2-a31160ece7d301f63f8f05be5d6198fe_r.jpg&&&/figure&&p&&br&&/p&&p&直观的看图说话,就是论文里的这张图了。LMCL的全称是 large margin cosine loss。&/p&&p&&br&&/p&&p&那么他这个增大分类面之间的margin是怎么做到的呢?&/p&&p&&br&&/p&&p&首先,交叉熵的损失是长这样的:&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-ee19c8faf55755e1afc6_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&433& data-rawheight=&58& class=&origin_image zh-lightbox-thumb& width=&433& data-original=&https://pic3.zhimg.com/v2-ee19c8faf55755e1afc6_r.jpg&&&/figure&&p&其中,fj是卷积网络最后一层的feature map和 权值向量的点乘。&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-d92d28cf6a89c76c7aab064c75a84f44_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&353& data-rawheight=&47& class=&content_image& width=&353&&&/figure&&p&&br&&/p&&p&然后,他通过L2范数正则化,把 ||Wj||固定为1,把权值 ||x||固定为s。这下整个损失函数的唯一变量是这个角度 θ了。然后他就给他加个margin,(文章中试了试,这个超参数0.35比较理想,但跟分类个数相关,太大了不收敛,太小了没感觉)这样就让不同人的图片经过卷积后的特征分得更开了。&/p&&p&预测的时候,提得的特征,他也用余弦距离来做判断,提升精度。&/p&&p&&br&&/p&&p&整个算法的核心在这里:&/p&&p&&br&&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-adce746bfffa13f72ee8ccb8144cf19d_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&433& data-rawheight=&226& class=&origin_image zh-lightbox-thumb& width=&433& data-original=&https://pic4.zhimg.com/v2-adce746bfffa13f72ee8ccb8144cf19d_r.jpg&&&/figure&&p&&br&&/p&&p&&br&&/p&&p&第一个式子就是加了m(margin)后,交叉熵展开的式子,后面的就是前面讲的一些条件,用初中数学的语言说法就是 令 。最后一行应该是公式编辑器编辑的不对,就是 i和 j直接的θ,cos(θi,j),i和j是平行对等的。&/p&&p&&br&&/p&&p&这篇文章的东西就讲完了,文章后面讲的是超参数怎么选,跟其他loss的对比,以及一些实验结果图。&/p&&p&&br&&/p&&p&好长一段时间没写文章了,朋友都问我啥时候更新公众号,就写篇给大家玩玩吧。&/p&&p&&br&&/p&&p&学而不思则罔,思而不学则殆。&/p&&p&多看Paper,勤敲代码。只看paper不动手就会飘在表面,只写代码不看paper就会思路窄。&/p&&p&&br&&/p&&p&写这篇文章,算是给大家提供宽的思路,推荐一下我琢磨过的paper吧。&/p&&p&&/p&
最近准备正儿八经的搞点事,琢磨着也发点paper,经常action,接地气的解决实际问题,别人还以为我是deeplearning的民间玩家。 正好腾讯AI lab刚发了波CVPR,找了找发现有一篇我觉得好玩的。结果一看,发现跟我之前看的文章类似,顺藤摸瓜,我发现3篇文章其实…
谷歌的人工智能的病理读片正确率已经打败人类医生了&br&&br&&a href=&//link.zhihu.com/?target=https%3A//www.cn-healthcare.com/article//content-490389.html& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://www.&/span&&span class=&visible&&cn-healthcare.com/artic&/span&&span class=&invisible&&le//content-490389.html&/span&&span class=&ellipsis&&&/span&&/a&&br&&br&国内这方面也在持续关注中&br&&a href=&//link.zhihu.com/?target=http%3A//wap.91360.com//30269.html& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&wap.91360.com/&/span&&span class=&invisible&&/30269.html&/span&&span class=&ellipsis&&&/span&&/a&&br&&br&这些读图软件的训练过程是典型的机器学习过程。&br&&br&积极意义: 弥补国内基层单位病理科合格大夫的不足&br&消极意义:包括血液实验室和病理实验室【谢知友提醒 也不能放过影像科】在内的以图形识别为主要工作内容的科室可能在20年内失去90%的工作岗位&br&&br&PS 除了病理科在AI注视下瑟瑟发抖之外,大医院检验科的血液组早就开始应用自动阅片机帮助快速分辨正常标本。
谷歌的人工智能的病理读片正确率已经打败人类医生了
国内这方面也在持续关注中
这些读图软件的训练过程是典型的机器学习过程。 积极意义: 弥补国内基层单位病理科合格大夫的不足 消极意义:包括血液实验室和病理…
&figure&&img src=&https://pic2.zhimg.com/v2-67feb456ceff7e6bbc4d8deee60e0eb8_b.jpg& data-rawwidth=&559& data-rawheight=&207& class=&origin_image zh-lightbox-thumb& width=&559& data-original=&https://pic2.zhimg.com/v2-67feb456ceff7e6bbc4d8deee60e0eb8_r.jpg&&&/figure&&p&&b&[CVPR 17 oral] A-Fast-RCNN: Hard Positive Generation via Adversary for Object Detection&/b&&/p&&p&&a href=&http://link.zhihu.com/?target=http%3A//blog.csdn.net/u/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&笔记同步发表于CSDN博客&/a&&/p&&p&Xiaolong Wang, Abhinav Shrivastava and Abhinav Gupta&/p&&p&&i&from&/i& CMU&/p&&p&&a href=&http://link.zhihu.com/?target=https%3A//arxiv.org/abs/v1& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&paper link&/a&&/p&&h2&Motivation&/h2&&p&这篇文章提出了一种新的对手生成策略,通过训练提升检测网络对遮挡、形变物体的识别精度。&/p&&p&遮挡和形变是检测任务中影响模型性能的两个显著因素。增加网络对遮挡和形变的鲁棒性的一个方式是增加数据库的体量。但是由于遮挡的图片一般都处在图像分布的长尾部分,即便增加数据,遮挡和形变的图片仍是占比较少的部分。另一个思路就是使用生成网络产生遮挡和形变图片。然而遮挡和形变的情况太多,直接生成这些图片还是比较困难的事情。&/p&&p&在这篇文章中,作者的思路是训练一个对手网络,让这个网络动态产生困难的遮挡和形变样本。以遮挡为例,作者希望被训练的检测网络会认为哪里的遮挡更难以处理。之后去遮挡这些区域的特征,从而让检测网络努力学习这些困难的遮挡情况。对于形变的情况同理。&/p&&p&与其它提升检测网络性能的方法,如换用更强大的主干网络、使用自上而下的网络设计等相比,本文提出的方法则是考虑如何更加充分地利用训练数据。&/p&&h2&Method&/h2&&p&针对遮挡和形变两种情况,作者在Fast RCNN[1]的RoI pooling之后分别设计了ASDN (Adversarial Spatial Dropout Network)和ASTN (Adversarial Spatial Transformer Network)两个网络。其结构如下图所示:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-ccf600b63ce30cb29e2077_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&915& data-rawheight=&364& class=&origin_image zh-lightbox-thumb& width=&915& data-original=&https://pic4.zhimg.com/v2-ccf600b63ce30cb29e2077_r.jpg&&&/figure&&h2&ASDN&/h2&&p&ASDN的目标是根据物体建议框中的内容,动态生成一个遮挡掩模。将掩模对应的特征置0后,能给后续的分类器制造尽可能大的麻烦,从而让分类器学习更难的遮挡样本。&/p&&p&为了得到ASDN,作者分以下几步进行训练:&/p&&ol&&li&训练迭代Fast RCNN约10K次,首先得到一个基本上可以进行检测的模型;&/li&&li&之后单独训练ASDN用来预测具体遮挡的部位。首先proposal被分割为9个格子。为了产生ASDN的训练信息,依次对这9个格子进行遮挡。遮挡后使分类损失最大的格子便是最值得去遮挡的格子。ASDN的训练损失函数便是去分类判断这9个格子,每个格子是不是最值得遮挡的那个;&/li&&li&ASDN的输出是一个分类概率组成的图。在使用输出结果的时候作者取分类为“最值得遮挡”的概率最高的1/2像素,随机选取这些像素中的1/3进行遮挡,剩下的2/3不遮挡,增加一定的随机因素;&/li&&li&之后作者将ASDN和Fast RCNN组合在一起进行端到端训练。&/li&&/ol&&h2&ASTN&/h2&&p&ASTN使用和STN(Spatial Transformer Network[2])一样的网络结构。其优化目标和STN不同,即训练一种仿射变换,使得分类器无法正确分类。实际使用中,需要对输出的旋转角度大小加以约束,否则容易出现将物体上下颠倒的极端但是并不常见的情况。&/p&&p&在最终的使用时,ASDN和ASTN被级联组合在网络中。&/p&&h2&Experiments&/h2&&p&作者进行了一些列实验来证明提出方法的有效性。首先证明ASDN和ASTN对网络性能的提升作用,在VOC 2007上的结果如下图所示,其中FRCN指Fast RCNN:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-c53e720e4d0bfb6c6e0c7f_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&886& data-rawheight=&308& class=&origin_image zh-lightbox-thumb& width=&886& data-original=&https://pic4.zhimg.com/v2-c53e720e4d0bfb6c6e0c7f_r.jpg&&&/figure&&p&针对ASDN,作者与随机对特征进行遮挡、每次迭代动态寻找最难部位遮挡、使用没有联合端到端训练的ASDN等三种方法进行了对比,结果如下:&/p&&figure&&img src=&https://pic2.zhimg.com/v2-e_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&887& data-rawheight=&172& class=&origin_image zh-lightbox-thumb& width=&887& data-original=&https://pic2.zhimg.com/v2-e_r.jpg&&&/figure&&p&同作为加强数据利用的方法,作者同OHEM[3]进行了对比。在VOC 2007数据集上,本文方法(71.4%)好于OHEM(69.0%)。但在VOC 2012上,本文方法(69.0%)逊于OHEM(69.8%)。作者解释该现象为两种方法分别强调不同层面的数据利用,是可以互补而不冲突的两种手段。将两者结合一起训练时,其结果(71.7%)达到了最好。&/p&&h2&Reference&/h2&&p&[1] R. Girshick. Fast r-cnn. In ICCV, 2015. &br&[2] M. Jaderberg, K. Simonyan, A. Zisserman, and K. Kavukcuoglu. Spatial transformer networks. In NIPS, 2015. &br&[3] A. Shrivastava, A. Gupta, and R. Girshick. Training regionbased object detectors with online hard example mining. In CVPR, 2016.&/p&
[CVPR 17 oral] A-Fast-RCNN: Hard Positive Generation via Adversary for Object DetectionXiaolong Wang, Abhinav Shrivastava and Abhinav Guptafrom CMUMotivation这篇文章提出了一种新的对手生成策略,通过训练提升…
&p&机器学习界有一群炼丹师,他们每天的日常是:&/p&&p&&br&&/p&&p&拿来药材(数据),架起八卦炉(模型),点着六味真火(优化算法),就摇着蒲扇等着丹药出炉了。&/p&&p&&br&&/p&&p&不过,当过厨子的都知道,同样的食材,同样的菜谱,但火候不一样了,这出来的口味可是千差万别。火小了夹生,火大了易糊,火不匀则半生半糊。&/p&&p&&br&&/p&&p&机器学习也是一样,模型优化算法的选择直接关系到最终模型的性能。有时候效果不好,未必是特征的问题或者模型设计的问题,很可能就是优化算法的问题。&/p&&p&&br&&/p&&p&说到优化算法,入门级必从SGD学起,老司机则会告诉你更好的还有AdaGrad/AdaDelta,或者直接无脑用Adam。可是看看学术界的最新paper,却发现一众大神还在用着入门级的SGD,最多加个Moment或者Nesterov ,还经常会黑一下Adam。比如 UC Berkeley的一篇论文就在Conclusion中写道:&/p&&p&&br&&/p&&blockquote&Despite the fact that our experimental evidence demonstrates that adaptive
methods are not advantageous for machine learning, the Adam algorithm remains incredibly popular. We are not sure exactly as to why ……&/blockquote&&p&&br&&/p&&p&无奈与酸楚之情溢于言表。&/p&&p&&br&&/p&&p&这是为什么呢?难道平平淡淡才是真?&/p&&hr&&h2&一个框架回顾优化算法&/h2&&p&&br&&/p&&p&首先我们来回顾一下各类优化算法。&/p&&p&&br&&/p&&p&深度学习优化算法经历了 SGD -& SGDM -& NAG -&AdaGrad -& AdaDelta -& Adam -& Nadam 这样的发展历程。Google一下就可以看到很多的教程文章,详细告诉你这些算法是如何一步一步演变而来的。在这里,我们换一个思路,用一个框架来梳理所有的优化算法,做一个更加高屋建瓴的对比。&/p&&p&&br&&/p&&p&首先定义:待优化参数: &img src=&http://www.zhihu.com/equation?tex=w& alt=&w& eeimg=&1&& ,目标函数: &img src=&http://www.zhihu.com/equation?tex=f%28w%29& alt=&f(w)& eeimg=&1&& ,初始学习率 &img src=&http://www.zhihu.com/equation?tex=%5Calpha& alt=&\alpha& eeimg=&1&&。&/p&&p&而后,开始进行迭代优化。在每个epoch &img src=&http://www.zhihu.com/equation?tex=t& alt=&t& eeimg=&1&& :&/p&&ol&&li&计算目标函数关于当前参数的梯度: &img src=&http://www.zhihu.com/equation?tex=g_t%3D%5Cnabla+f%28w_t%29& alt=&g_t=\nabla f(w_t)& eeimg=&1&&&/li&&li&根据历史梯度计算一阶动量和二阶动量:&img src=&http://www.zhihu.com/equation?tex=m_t+%3D+%5Cphi%28g_1%2C+g_2%2C+%5Ccdots%2C+g_t%29%3B+V_t+%3D+%5Cpsi%28g_1%2C+g_2%2C+%5Ccdots%2C+g_t%29& alt=&m_t = \phi(g_1, g_2, \cdots, g_t); V_t = \psi(g_1, g_2, \cdots, g_t)& eeimg=&1&&,&/li&&li&计算当前时刻的下降梯度: &img src=&http://www.zhihu.com/equation?tex=%5Ceta_t+%3D+%5Calpha+%5Ccdot+m_t+%2F+%5Csqrt%7BV_t%7D& alt=&\eta_t = \alpha \cdot m_t / \sqrt{V_t}& eeimg=&1&&&/li&&li&根据下降梯度进行更新: &img src=&http://www.zhihu.com/equation?tex=w_%7Bt%2B1%7D+%3D+w_t+-+%5Ceta_t& alt=&w_{t+1} = w_t - \eta_t& eeimg=&1&&&/li&&/ol&&p&掌握了这个框架,你可以轻轻松松设计自己的优化算法。&/p&&p&&br&&/p&&p&我们拿着这个框架,来照一照各种玄乎其玄的优化算法的真身。步骤3、4对于各个算法都是一致的,主要的差别就体现在1和2上。&/p&&p&&br&&/p&&h2&SGD&/h2&&p&先来看SGD。SGD没有动量的概念,也就是说:&/p&&p&&img src=&http://www.zhihu.com/equation?tex=m_t+%3D+g_t%3B+V_t+%3D+I%5E2& alt=&m_t = g_t; V_t = I^2& eeimg=&1&&&/p&&p&代入步骤3,可以看到下降梯度就是最简单的&/p&&p&&img src=&http://www.zhihu.com/equation?tex=%5Ceta_t+%3D+%5Calpha+%5Ccdot+g_t+& alt=&\eta_t = \alpha \cdot g_t & eeimg=&1&&&/p&&p&SGD最大的缺点是下降速度慢,而且可能会在沟壑的两边持续震荡,停留在一个局部最优点。&/p&&p&&br&&/p&&h2&SGD with Momentum&/h2&&p&为了抑制SGD的震荡,SGDM认为梯度下降过程可以加入惯性。下坡的时候,如果发现是陡坡,那就利用惯性跑的快一些。SGDM全称是SGD with momentum,在SGD基础上引入了一阶动量:&/p&&p&&img src=&http://www.zhihu.com/equation?tex=m_t+%3D+%5Cbeta_1+%5Ccdot+m_%7Bt-1%7D+%2B+%281-%5Cbeta_1%29%5Ccdot+g_t& alt=&m_t = \beta_1 \cdot m_{t-1} + (1-\beta_1)\cdot g_t& eeimg=&1&&&/p&&p&一阶动量是各个时刻梯度方向的指数移动平均值,约等于最近 &img src=&http://www.zhihu.com/equation?tex=1%2F%281-%5Cbeta_1%29& alt=&1/(1-\beta_1)& eeimg=&1&& 个时刻的梯度向量和的平均值。&/p&&p&&br&&/p&&p&也就是说,t时刻的下降方向,不仅由当前点的梯度方向决定,而且由此前累积的下降方向决定。 &img src=&http://www.zhihu.com/equation?tex=%5Cbeta_1& alt=&\beta_1& eeimg=&1&& 的经验值为0.9,这就意味着下降方向主要是此前累积的下降方向,并略微偏向当前时刻的下降方向。想象高速公路上汽车转弯,在高速向前的同时略微偏向,急转弯可是要出事的。&/p&&p&&br&&/p&&h2&SGD with Nesterov
Acceleration &/h2&&p&SGD 还有一个问题是困在局部最优的沟壑里面震荡。想象一下你走到一个盆地,四周都是略高的小山,你觉得没有下坡的方向,那就只能待在这里了。可是如果你爬上高地,就会发现外面的世界还很广阔。因此,我们不能停留在当前位置去观察未来的方向,而要向前一步、多看一步、看远一些。&/p&&p&&br&&/p&&p&NAG全称Nesterov
Accelerated Gradient,是在SGD、SGD-M的基础上的进一步改进,改进点在于步骤1。我们知道在时刻t的主要下降方向是由累积动量决定的,自己的梯度方向说了也不算,那与其看当前梯度方向,不如先看看如果跟着累积动量走了一步,那个时候再怎么走。因此,NAG在步骤1,不计算当前位置的梯度方向,而是计算如果按照累积动量走了一步,那个时候的下降方向:&/p&&p&&img src=&http://www.zhihu.com/equation?tex=g_t%3D%5Cnabla+f%28w_t-%5Calpha+%5Ccdot+m_%7Bt-1%7D+%2F+%5Csqrt%7BV_%7Bt-1%7D%7D%29& alt=&g_t=\nabla f(w_t-\alpha \cdot m_{t-1} / \sqrt{V_{t-1}})& eeimg=&1&&&/p&&p&然后用下一个点的梯度方向,与历史累积动量相结合,计算步骤2中当前时刻的累积动量。&/p&&p&&br&&/p&&h2&AdaGrad&/h2&&p&此前我们都没有用到二阶动量。二阶动量的出现,才意味着“自适应学习率”优化算法时代的到来。SGD及其变种以同样的学习率更新每个参数,但深度神经网络往往包含大量的参数,这些参数并不是总会用得到(想想大规模的embedding)。对于经常更新的参数,我们已经积累了大量关于它的知识,不希望被单个样本影响太大,希望学习速率慢一些;对于偶尔更新的参数,我们了解的信息太少,希望能从每个偶然出现的样本身上多学一些,即学习速率大一些。&/p&&p&&br&&/p&&p&怎么样去度量历史更新频率呢?那就是二阶动量——该维度上,迄今为止所有梯度值的平方和:&/p&&p&&img src=&http://www.zhihu.com/equation?tex=V_t+%3D+%5Csum_%7B%5Ctau%3D1%7D%5E%7Bt%7D+g_%5Ctau%5E2& alt=&V_t = \sum_{\tau=1}^{t} g_\tau^2& eeimg=&1&&&/p&&p&我们再回顾一下步骤3中的下降梯度:&/p&&p&&img src=&http://www.zhihu.com/equation?tex=%5Ceta_t+%3D+%5Calpha+%5Ccdot+m_t+%2F+%5Csqrt%7BV_t%7D& alt=&\eta_t = \alpha \cdot m_t / \sqrt{V_t}& eeimg=&1&&&/p&&p&可以看出,此时实质上的学习率由 &img src=&http://www.zhihu.com/equation?tex=+%5Calpha& alt=& \alpha& eeimg=&1&& 变成了 &img src=&http://www.zhihu.com/equation?tex=+%5Calpha+%2F+%5Csqrt%7BV_t%7D& alt=& \alpha / \sqrt{V_t}& eeimg=&1&& 。 一般为了避免分母为0,会在分母上加一个小的平滑项。因此&img src=&http://www.zhihu.com/equation?tex=%5Csqrt%7BV_t%7D& alt=&\sqrt{V_t}& eeimg=&1&& 是恒大于0的,而且参数更新越频繁,二阶动量越大,学习率就越小。&/p&&p&&br&&/p&&p&这一方法在稀疏数据场景下表现非常好。但也存在一些问题:因为&img src=&http://www.zhihu.com/equation?tex=%5Csqrt%7BV_t%7D& alt=&\sqrt{V_t}& eeimg=&1&& 是单调递增的,会使得学习率单调递减至0,可能会使得训练过程提前结束,即便后续还有数据也无法学到必要的知识。&/p&&p&&br&&/p&&h2&AdaDelta / RMSProp&/h2&&p&&br&&/p&&p&由于AdaGrad单调递减的学习率变化过于激进,我们考虑一个改变二阶动量计算方法的策略:不累积全部历史梯度,而只关注过去一段时间窗口的下降梯度。这也就是AdaDelta名称中Delta的来历。&/p&&p&&br&&/p&&p&修改的思路很简单。前面我们讲到,指数移动平均值大约就是过去一段时间的平均值,因此我们用这一方法来计算二阶累积动量:&/p&&p&&img src=&http://www.zhihu.com/equation?tex=V_t+%3D+%5Cbeta_2+%2A+V_%7Bt-1%7D+%2B+%281-%5Cbeta_2%29+g_t%5E2& alt=&V_t = \beta_2 * V_{t-1} + (1-\beta_2) g_t^2& eeimg=&1&&&/p&&p&这就避免了二阶动量持续累积、导致训练过程提前结束的问题了。&/p&&p&&br&&/p&&h2&Adam&/h2&&p&&br&&/p&&p&谈到这里,Adam和Nadam的出现就很自然而然了——它们是前述方法的集大成者。我们看到,SGD-M在SGD基础上增加了一阶动量,AdaGrad和AdaDelta在SGD基础上增加了二阶动量。把一阶动量和二阶动量都用起来,就是Adam了——Adaptive + Momentum。&/p&&p&&br&&/p&&p&SGD的一阶动量:&/p&&p&&img src=&http://www.zhihu.com/equation?tex=m_t+%3D+%5Cbeta_1+%5Ccdot+m_%7Bt-1%7D+%2B+%281-%5Cbeta_1%29%5Ccdot+g_t& alt=&m_t = \beta_1 \cdot m_{t-1} + (1-\beta_1)\cdot g_t& eeimg=&1&&&/p&&p&加上AdaDelta的二阶动量:&/p&&p&&img src=&http://www.zhihu.com/equation?tex=V_t+%3D+%5Cbeta_2+%2A+V_%7Bt-1%7D+%2B+%281-%5Cbeta_2%29+g_t%5E2& alt=&V_t = \beta_2 * V_{t-1} + (1-\beta_2) g_t^2& eeimg=&1&&&/p&&p&&br&&/p&&p&优化算法里最常见的两个超参数 &img src=&http://www.zhihu.com/equation?tex=+%5Cbeta_1%2C+%5Cbeta_2& alt=& \beta_1, \beta_2& eeimg=&1&& 就都在这里了,前者控制一阶动量,后者控制二阶动量。&/p&&p&&br&&/p&&h2&Nadam&/h2&&p&&br&&/p&&p&最后是Nadam。我们说Adam是集大成者,但它居然遗漏了Nesterov,这还能忍?必须给它加上,按照NAG的步骤1:&/p&&p&&img src=&http://www.zhihu.com/equation?tex=g_t%3D%5Cnabla+f%28w_t-%5Calpha+%5Ccdot+m_%7Bt-1%7D+%2F+%5Csqrt%7BV_t%7D%29& alt=&g_t=\nabla f(w_t-\alpha \cdot m_{t-1} / \sqrt{V_t})& eeimg=&1&&&/p&&p&这就是Nesterov + Adam = Nadam了。&/p&&p&&br&&/p&&p&说到这里,大概可以理解为什么j经常有人说 Adam / Nadam 目前最主流、最好用的优化算法了。新手上路,先拿来一试,收敛速度嗖嗖滴,效果也是杠杠滴。&/p&&p&&br&&/p&&p&那为什么Adam还老招人黑,被学术界一顿鄙夷?难道只是为了发paper灌水吗?&/p&&p&&br&&/p&&p&请继续阅读:&/p&&p&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&Adam那么棒,为什么还对SGD念念不忘 (2)—— Adam的两宗罪&/a& &/p&&p&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&Adam那么棒,为什么还对SGD念念不忘 (3)—— 优化算法的选择与使用策略&/a&&/p&&p&&br&&/p&&p&————————————————————&/p&&h2&补充:指数移动平均值的偏差修正&/h2&&p&&br&&/p&&p&前面我们讲到,一阶动量和二阶动量都是按照指数移动平均值进行计算的:&/p&&p&&img src=&http://www.zhihu.com/equation?tex=m_t+%3D+%5Cbeta_1+%5Ccdot+m_%7Bt-1%7D+%2B+%281-%5Cbeta_1%29%5Ccdot+g_t& alt=&m_t = \beta_1 \cdot m_{t-1} + (1-\beta_1)\cdot g_t& eeimg=&1&&&/p&&p&&img src=&http://www.zhihu.com/equation?tex=V_t+%3D+%5Cbeta_2+%5Ccdot+V_%7Bt-1%7D+%2B+%281-%5Cbeta_2%29+%5Ccdot+g_t%5E2& alt=&V_t = \beta_2 \cdot V_{t-1} + (1-\beta_2) \cdot g_t^2& eeimg=&1&&&/p&&p&实际使用过程中,参数的经验值是&/p&&p&&img src=&http://www.zhihu.com/equation?tex=%5Cbeta_1%3D0.9%2C+%5Cbeta_2%3D0.999& alt=&\beta_1=0.9, \beta_2=0.999& eeimg=&1&&&/p&&p&初始化:&/p&&p&&img src=&http://www.zhihu.com/equation?tex=m_0%3D0%2C+V_0%3D0& alt=&m_0=0, V_0=0& eeimg=&1&&&/p&&p&这个时候我们看到,在初期, &img src=&http://www.zhihu.com/equation?tex=m_t%2C+V_t& alt=&m_t, V_t& eeimg=&1&& 都会接近于0,这个估计是有问题的。因此我们常常根据下式进行误差修正:&/p&&p&&img src=&http://www.zhihu.com/equation?tex=%5Ctilde%7Bm%7D_t+%3D+m_t+%2F+%281-%5Cbeta_1%5Et%29& alt=&\tilde{m}_t = m_t / (1-\beta_1^t)& eeimg=&1&&&/p&&p&&img src=&http://www.zhihu.com/equation?tex=%5Ctilde%7BV%7D_t+%3D+V_t+%2F+%281-%5Cbeta_2%5Et%29& alt=&\tilde{V}_t = V_t / (1-\beta_2^t)& eeimg=&1&&&/p&&p&&br&&/p&&p&————————————————————&/p&&p&行有所思,学有所得,陋鄙之言,请多指教。&/p&&p&欢迎关注我的微信公众号 Julius-AI&/p&&p&&/p&&p&&/p&&p&&/p&
机器学习界有一群炼丹师,他们每天的日常是: 拿来药材(数据),架起八卦炉(模型),点着六味真火(优化算法),就摇着蒲扇等着丹药出炉了。 不过,当过厨子的都知道,同样的食材,同样的菜谱,但火候不一样了,这出来的口味可是千差万别。火小了夹生,火…
&figure&&img src=&https://pic1.zhimg.com/v2-9fc12fd06ea300e4549ba_b.jpg& data-rawwidth=&2200& data-rawheight=&1212& class=&origin_image zh-lightbox-thumb& width=&2200& data-original=&https://pic1.zhimg.com/v2-9fc12fd06ea300e4549ba_r.jpg&&&/figure&&blockquote&转载请注明出处:&a href=&https://zhuanlan.zhihu.com/MCPRL& class=&internal&&CV喵的进阶&/a& &br&&a href=&http://link.zhihu.com/?target=https%3A//arxiv.org/abs/v1& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&原文链接&/a&&/blockquote&&h2&&b&一、问题介绍&/b&&/h2&&p&物体检测的主要方法是单阶段(eg:YOLO,SSD)和两阶段(eg:Faster RCNN)。通常情况下,单阶段方法速度更快,两阶段方法mAP更高。本文作者想将二种方法结合,使其能够速度和效果都有很好的表现。&/p&&h2&&b&二、相关工作&/b&&/h2&&ul&&li&&b&两阶段方法&/b&&/li&&/ul&&p&第一阶段:生成候选框。主要方法:Selective Search, EdgeBoxes, DeepMask, RPN&/p&&p&第二阶段:用卷积网络来分类--类别标签,回归--候选区域。&/p&&ul&&li&&b&单阶段方法&/b&&/li&&/ul&&p&单阶段检测方法依据一定规律和密度采样出不用的位置,尺寸,比例,从而省去了生成候选框的这一阶段的网络。主要是将不同尺寸的不同特征层的集中在一起,进行一次回归,得到预测框的位置信息和大小。类别不平衡则会严重影响该方法的精确度。&/p&&h2&&b&三、网络结构&/b&&/h2&&figure&&img src=&https://pic3.zhimg.com/v2-9fc12fd06ea300e4549ba_b.jpg& data-size=&normal& data-rawwidth=&2200& data-rawheight=&1212& class=&origin_image zh-lightbox-thumb& width=&2200& data-original=&https://pic3.zhimg.com/v2-9fc12fd06ea300e4549ba_r.jpg&&&figcaption&RefineDet的网络结构 灰绿色四边形是不同feature map之间相连接的refined anchors,里面小星星代表refined anchor boxes的中心&/figcaption&&/figure&&p&本文将结合两阶段和单阶段的优点。基于单阶段的网络框架,加入了互相连接的模块:
anchor refinement module(ARM), object detection module(ODM),和两者之间的连接块,
transfer connection block(TCB). &/p&&ul&&li&ARM:识别并去除不好的anchor,从而减少分类器的搜索区间,粗略调整anchor的位置和大小,为后面的回归提供更好的初始化。&/li&&li&ODM:输入时refined anchors,为了提高回归和类别预测。&/li&&/ul&&p&&b&流程:&/b&&/p&&ol&&li&在每个feature map上按照一定规律的分割出cell,每个cell会有n个anchor。与对应cell相关的anchor的初始位置会被修正。&/li&&li&对每个feature map cell的原始anchor,预测其坐标的四个offests,和前景存在的物体的两个scores( negative confidence score和 positive confidence score),这样每个feature map cell就得到了n个refined anchors(这一步即是与SSD最大不同的之处)。&/li&&li&refined anchor会进行一波筛选,negative confidence score超过预设的阈值的anchor会被丢掉。最后留下的是 negative hard refined anchor和positive refined anchor。以此减少样本失衡。&/li&&li&筛选后的refined anchor会被送到ODM,进一步精确位置坐标和大小,以及类别分数。&/li&&/ol&&p&&b&训练:&/b&&/p&&p&训练技巧使用了与SSD相同的数据扩充技巧,骨干网络是VGG16(用于Pascal VOC数据集)和ResNet-101(用于COCO数据集),骨干网络基础上做了小小的改动。&/p&&ul&&li&VGG16为例介绍改动:类似于 DeepLab-LargeFOV,通过二次抽样将VGG16的fc6和fc7转变成了fc_conv。使用了L2范数将con4_3和conv5_3放缩到10和8,反向传播的时候再学习scales。为了获得高层的信息产生多尺度的检测,在阶段的VGG16后面增添了两个层: conv6_1 和conv6_2&/li&&li&默认参数:4个默认scale: [8,16,32,64] ,3个默认ratio: [0.5,1,2],IoU的阈值为0.5&/li&&li&困难样本挖掘时,基于top loss选择,保证正负样本比例是1:3,而不是使用全部负样本或是随机选择负样本。&/li&&li&Loss函数详见论文,将ARM和ODM两部分的loss合并。&/li&&/ul&&figure&&img src=&https://pic1.zhimg.com/v2-b9b275a18a73ba56a580_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&904& data-rawheight=&166& class=&origin_image zh-lightbox-thumb& width=&904& data-original=&https://pic1.zhimg.com/v2-b9b275a18a73ba56a580_r.jpg&&&/figure&&ul&&li&优化:nms,soft_nms&/li&&/ul&&h2&&b&四、实验结果&/b&&/h2&&p&实验丰富,一部分实验用于验证整个框架的效果,一部分实验用于验证框架中三个每个模块的效果。取得了比较不错的效果&/p&&ul&&li&pacal_voc VGG16&/li&&/ul&&figure&&img src=&https://pic3.zhimg.com/v2-1a95dcbf0b307d08d2049e_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1972& data-rawheight=&1260& class=&origin_image zh-lightbox-thumb& width=&1972& data-original=&https://pic3.zhimg.com/v2-1a95dcbf0b307d08d2049e_r.jpg&&&/figure&&ul&&li&MSCOCO ResNet-101&/li&&/ul&&figure&&img src=&https://pic2.zhimg.com/v2-b2b17cdd7a1817fcecec5_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1972& data-rawheight=&474& class=&origin_image zh-lightbox-thumb& width=&1972& data-original=&https://pic2.zhimg.com/v2-b2b17cdd7a1817fcecec5_r.jpg&&&/figure&&h2&&b&五、总结&/b&&/h2&&p&框架结构简单又有效,代码公开。在同时期的SSD的衍生网络中速度与精度表现上脱颖而出。&/p&&hr&&p&第一次写文章,很多不足,欢迎指教~&/p&&p&总结的时候更是暴露出的自己还没有足够的积累。&/p&&p&总之,先迈出第一步。相信以后会越来越好。&/p&
转载请注明出处: 一、问题介绍物体检测的主要方法是单阶段(eg:YOLO,SSD)和两阶段(eg:Faster RCNN)。通常情况下,单阶段方法速度更快,两阶段方法mAP更高。本文作者想将二种方法结合,使其能够速度和效果都有很好的表现。二、相关工作…
&figure&&img src=&https://pic4.zhimg.com/v2-76b992c4a2c_b.jpg& data-rawwidth=&512& data-rawheight=&384& class=&origin_image zh-lightbox-thumb& width=&512& data-original=&https://pic4.zhimg.com/v2-76b992c4a2c_r.jpg&&&/figure&&h2&从Slerp说起&/h2&&p&ICLR'2017的投稿里,有一篇很有意思但被拒掉的投稿《&a href=&http://link.zhihu.com/?target=https%3A//openreview.net/forum%3Fid%3DSypU81Ole& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Sampling Generative Networks&/a&》 by &a href=&http://link.zhihu.com/?target=https%3A//www.victoria.ac.nz/design/about/staff/tom-white& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Tom White&/a&。文章比较松散地讲了一些在latent space挺有用的采样和可视化技巧,其中一个重要的点是指出在GAN的latent space中,比起常用的线性插值,沿着两个采样点之间的“弧”进行插值是更合理的办法。实现的方法就是图形学里的&a href=&http://link.zhihu.com/?target=http%3A//run.usc.edu/cs520-s12/assign2/p245-shoemake.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Slerp(spherical linear interpolation)&/a&在高维空间中的延伸:&/p&&p&&img src=&http://www.zhihu.com/equation?tex=%5Ctext+%7BSlerp%7D+%28p_0%2Cp_1%3Bt%29%3D%5Cfrac%7Bsin%28%281-t%29%5COmega%29%7D%7Bsin%28%5COmega%29%7D+p_0%2B%5Cfrac%7Bsin%28t%5COmega%29%7D%7Bsin%28%5COmega%29%7D+p_1& alt=&\text {Slerp} (p_0,p_1;t)=\frac{sin((1-t)\Omega)}{sin(\Omega)} p_0+\frac{sin(t\Omega)}{sin(\Omega)} p_1& eeimg=&1&&&/p&&p&形象理解并不难,以wiki上的图为例:&/p&&figure&&img src=&https://pic2.zhimg.com/v2-cebd397a48ed_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1024& data-rawheight=&650& class=&origin_image zh-lightbox-thumb& width=&1024& data-original=&https://pic2.zhimg.com/v2-cebd397a48ed_r.jpg&&&/figure&&p&要求的是图中P点,在Wiki图的基础上我加了A、B和O三个点,O就是原点。所以P其实就是&img src=&http://www.zhihu.com/equation?tex=%5Cvec+%7BOP%7D%3D%5Cvec+%7BOA%7D+%2B+%5Cvec+%7BOB%7D& alt=&\vec {OP}=\vec {OA} + \vec {OB}& eeimg=&1&& 。先考虑求 &img src=&http://www.zhihu.com/equation?tex=%5Cvec+%7BOA%7D& alt=&\vec {OA}& eeimg=&1&& ,第一步引入和 &img src=&http://www.zhihu.com/equation?tex=%5Cvec+%7BOP_0%7D& alt=&\vec {OP_0}& eeimg=&1&& 垂直的 &img src=&http://www.zhihu.com/equation?tex=%5Cvec+%7BO%5Cperp+P_0%7D& alt=&\vec {O\perp P_0}& eeimg=&1&& ,也就是图中蓝色的箭头。那么 &img src=&http://www.zhihu.com/equation?tex=%5Cleft%7C+OA+%5Cright%7C& alt=&\left| OA \right|& eeimg=&1&& 和 &img src=&http://www.zhihu.com/equation?tex=%5Cleft%7C+OP_1+%5Cright%7C& alt=&\left| OP_1 \right|& eeimg=&1&& 的比值就等于他们分别投影到蓝色向量上的部分的比值,也就是蓝色箭头两侧的橙色线段比红色线段。这个比值正是 &img src=&http://www.zhihu.com/equation?tex=%5Cfrac%7B%5Csin+%5Ctheta%7D%7B%5Csin+%5COmega%7D& alt=&\frac{\sin \theta}{\sin \Omega}& eeimg=&1&& ,于是 &img src=&http://www.zhihu.com/equation?tex=%5Cvec+%7BOA%7D& alt=&\vec {OA}& eeimg=&1&& 就是 &img src=&http://www.zhihu.com/equation?tex=%5Cfrac%7Bsin%28%5Ctheta%29%7D%7Bsin%28%5COmega%29%7D+p_1& alt=&\frac{sin(\theta)}{sin(\Omega)} p_1& eeimg=&1&& 。很显然,同样的方法也可以用来求 &img src=&http://www.zhihu.com/equation?tex=%5Cvec+%7BOB%7D%3D%5Cfrac%7Bsin%28%5COmega-%5Ctheta%29%7D%7Bsin%28%5COmega%29%7D+p_0& alt=&\vec {OB}=\frac{sin(\Omega-\theta)}{sin(\Omega)} p_0& eeimg=&1&& ,然后代入 &img src=&http://www.zhihu.com/equation?tex=%5Cvec+%7BOP%7D%3D%5Cvec+%7BOA%7D%2B%5Cvec+%7BOB%7D& alt=&\vec {OP}=\vec {OA}+\vec {OB}& eeimg=&1&& ,并令 &img src=&http://www.zhihu.com/equation?tex=%5Ctheta%3Dt%5COmega& alt=&\theta=t\Omega& eeimg=&1&& ,就得到了Slerp的公式。注意虽然推导的时候用的虽然是 &img src=&http://www.zhihu.com/equation?tex=P_0& alt=&P_0& eeimg=&1&& 和 &img src=&http://www.zhihu.com/equation?tex=P_1& alt=&P_1& eeimg=&1&& 在同一个(超)球面上,但是实际用的时候不同长度的 &img src=&http://www.zhihu.com/equation?tex=P_0& alt=&P_0& eeimg=&1&& 和 &img src=&http://www.zhihu.com/equation?tex=P_1& alt=&P_1& eeimg=&1&& 之间利用Slerp也是可以很自然的插值的,得到的向量长度介于二者之间且单调(非线性)增减。ICLR的Review中也讨论到了这个问题。&/p&&p&使用Slerp比起纯线性插值的好处在哪里呢?作者原文这样解释:&/p&&p&&&i&Frequently linear interpolation is used, which is easily understood and implemented. But this is often inappropriate as the latent spaces of most generative models are high dimensional (& 50 dimensions) with a Gaussian or uniform prior. In such a space, linear interpolation traverses locations that are extremely unlikely given the prior. As a concrete example, consider a 100 dimensional space with the Gaussian prior u=0, σ=1. Here all random vectors will generally a length very close to 10 (standard deviation & 1). However, linearly interpolating between any two will usually result in a &tent-pole& effect as the magnitude of the vector decreases from roughly 10 to 7 at the midpoint, which is over 4 standard deviations away from the expected length.&/i&&&/p&&p&就是说在高维(&50)的空间里做线性插值,会路过一些不太可能路过的位置,就好像数据都分布在帐篷布上,但是线性插值走的是帐篷杆。&/p&&p&要更具体理解这个现象,还要从GAN中常用的prior distribution说起。在GAN中,最常用的是uniform和Gaussian(感觉现在Gaussian居多)。不管是哪种prior,对于一个n维样本 &img src=&http://www.zhihu.com/equation?tex=%5Cleft%28+x_1%2Cx_2%2C%5Cdots%2Cx_n+%5Cright%29& alt=&\left( x_1,x_2,\dots,x_n \right)& eeimg=&1&& ,到中心的欧式距离为:&/p&&p&&img src=&http://www.zhihu.com/equation?tex=d%3D%5Csqrt%7Bx_1%5E2%2Bx_2%5E2%2B%5Cdots%2Bx_n%5E2%7D& alt=&d=\sqrt{x_1^2+x_2^2+\dots+x_n^2}& eeimg=&1&&&/p&&p&而通常GAN的采样空间维度还算高,这个时候我们把d的平方看作是一连串n个独立同分布的随机变量 &img src=&http://www.zhihu.com/equation?tex=x_1%5E2%2Cx_2%5E2%2C%5Cdots%2Cx_n%5E2& alt=&x_1^2,x_2^2,\dots,x_n^2& eeimg=&1&& 的和,则由&a href=&http://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Central_limit_theorem& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&中心极限定理&/a&可知d的平方近似服从正态分布(实际上是&a href=&http://link.zhihu.com/?target=https%3A//zh.wikipedia.org/wiki/%25E5%258D%25A1%25E6%%25E5%E4%25BD%2588& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Chi-square分布&/a&):&img src=&http://www.zhihu.com/equation?tex=N%5Cleft%28+n%5Cmu%2C+n%5Csigma%5E2+%5Cright%29& alt=&N\left( n\mu, n\sigma^2 \right)& eeimg=&1&&。考虑很常见的100维标准正态分布作为prior的情况,平方之后就是k=1的Chi-square分布,均值为1,方差为2。所以每个样本到原点的距离的平方近似服从N(100, 200),标准差~14.14,如果认为 &img src=&http://www.zhihu.com/equation?tex=%5Cdelta& alt=&\delta& eeimg=&1&& =14.14/100已经足够小,使 &img src=&http://www.zhihu.com/equation?tex=%5Csqrt%7B1%2B%5Cdelta%7D%5Capprox1%2B%5Cfrac+1+2%5Cdelta& alt=&\sqrt{1+\delta}\approx1+\frac 1 2\delta& eeimg=&1&& ,则d也可以近似看作是一个高斯分布(实际上是&a href=&http://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Chi_distribution& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Chi分布&/a&),均值为10,标准差为0.707,就是作者在原文中说的情况。&/p&&p&uniform prior的情况也类似,不过更加复杂,因为均匀分布并非各向同性。在高维空间中,一个超立方体形状如果脑补一下就是一个球周边长了很多尖刺,每个尖刺就是象限中的一个极端值。具体推导我不会,不过写个程序很容易模拟。采10万个样本得到的结果是100维,每个维度[-1, 1]的均匀分布的prior,样本到中心的距离平均值约为5.77,标准差约0.258。所以无论是哪种情况,高维空间里的样本都有一个特点:远离中心,且集中分布在均值附近。所以线性插值就会像在帐篷杆上插值一样,路过真实样本出现概率极低的区域。&/p&&p&原文还提到了在100维Gaussian prior的情况下,线性插值取到的点到中心的距离会从10到7,这怎么理解呢?我的数学水平脑补不了这件事,定性来看随机采两个样本,这两个样本趋于垂直的倾向会很高,因为要趋于同向或者反向需要每一维的距离都足够近或足够远,这个概率会很低。定量的话可以写个程序模拟:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&import numpy
from matplotlib import pyplot
def dist_o2l(p1, p2):
# distance from origin to the line defined by (p1, p2)
p12 = p2 - p1
u12 = p12 / numpy.linalg.norm(p12)
l_pp = numpy.dot(-p1, u12)
pp = l_pp*u12 + p1
return numpy.linalg.norm(pp)
N = 100000
dists2l = []
for i in range(N):
u = numpy.random.randn(dim)
v = numpy.random.randn(dim)
rvs.extend([u, v])
dists2l.append(dist_o2l(u, v))
dists = [numpy.linalg.norm(x) for x in rvs]
print('Distances to samples, mean: {}, std: {}'.format(numpy.mean(dists), numpy.std(dists)))
print('Distances to lines, mean: {}, std: {}'.format(numpy.mean(dists2l), numpy.std(dists2l)))
fig, (ax0, ax1) = pyplot.subplots(ncols=2, figsize=(11, 5))
ax0.hist(dists, 100, normed=1, color='g')
ax1.hist(dists2l, 100, normed=1, color='b')
pyplot.show()
&/code&&/pre&&/div&&p&结果如下:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-90a0df6ef7db_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&928& data-rawheight=&457& class=&origin_image zh-lightbox-thumb& width=&928& data-original=&https://pic4.zhimg.com/v2-90a0df6ef7db_r.jpg&&&/figure&&p&左边是在latent space里随机采样的样本到中心距离的分布,右边是原点在随机采样的两个样本所在直线上的投影点到中心距离的分布,也就是线性插值中到中心最近点的距离的分布。可以看到随机采样并进行线性插值的办法还真的是容易路过样本几乎不可能出现的区域(距原点距离5~7.5)。可是《&a href=&http://link.zhihu.com/?target=https%3A//openreview.net/forum%3Fid%3DSypU81Ole& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Sampling Generative Networks&/a&》被拒的comment里有一句:&neither the reviewers nor I were convinced that spherical interpolation makes more sense than linear interpolation&。就这一点来说,感觉Tom White有些冤枉,虽然确实不是什么眼前一亮的大改进,但是有理有据。那为什么reviewer们没觉得比线性插值好多少呢?原因可能就是:&/p&&h2&基于ReLU网络的线性&/h2&&p&CNN在12年的时候一鸣惊人,应该说ReLU一系的激活函数扮演了一个至关重要的角色:让深层网络可训练。后续的无论是LeakyReLU、ELU还是Swish等等,大于0的部分都是非常线性的。所以虽然非线性变换(激活函数)是神经网络作为&a href=&http://link.zhihu.com/?target=http%3A//citeseerx.ist.psu.edu/viewdoc/download%3Fdoi%3D10.1.1.441.7873%26rep%3Drep1%26type%3Dpdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&universal approximator&/a&的基础,但基于ReLU系的神经网络其实是线性程度很高的。对于常见判别式网络,Ian Goodfellow认为这种线性再加上Distributed Representation的超强表达能力是使得网络容易被对抗样本攻击的基础(详见&a href=&http://link.zhihu.com/?target=https%3A//arxiv.org/abs/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&这篇&/a&),并据此发明了Fast Gradient Sign方法快速生成对抗样本。&/p&&p&那么基于ReLU的CNN的线性有多强呢?先来看生成式网络,以DCGAN为例,示意图如下&/p&&figure&&img src=&https://pic3.zhimg.com/v2-ab7adb8e6c24ae126c7502_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&600& data-rawheight=&250& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&https://pic3.zhimg.com/v2-ab7adb8e6c24ae126c7502_r.jpg&&&/figure&&p&从结构上来看,DCGAN比常见的判别式网络更加线性,因为连max pooling都没了,不那么线性的部分就只有最后输出图片的Tanh。尤其是从latent space到第一组feature map这一步,常见的实现方法是把100维的噪声看成是100个channel,1x1的feature map,然后直接用没有bias的transposed convolution上采样,是一个纯线性变换!定性来看,如果整个后续的网络部分线性程度也足够高,则在latent space的任意样本,同时对所有维度进行缩放的话,得到的图像应该差不多就是同一幅图不同的对比度。&/p&&p&训练一个GAN的生成器就可以验证这个结论,感谢&a href=&https://www.zhihu.com/people/he-zhi-yuan-16& class=&internal&&何之源&/a&在文章&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&GAN学习指南:从原理入门到制作生成Demo&/a&中提供了一份对GAN而言高质量且好下载的动漫头像数据。基于这个数据和&a href=&http://link.zhihu.com/?target=https%3A//github.com/pytorch/examples/blob/master/dcgan/main.py& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&PyTorch的官方DCGAN例子&/a&就可以很轻松的训练出一个模型。基于训练出的模型随机采样并分别进行Slerp和线性插值,结果如下:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-94cedf990_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&768& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&https://pic1.zhimg.com/v2-94cedf990_r.jpg&&&/figure&&figure&&img src=&https://pic2.zhimg.com/v2-7e8a202c859cdc5b2a7059_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&768& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&https://pic2.zhimg.com/v2-7e8a202c859cdc5b2a7059_r.jpg&&&/figure&&figure&&img src=&https://pic2.zhimg.com/v2-94c4b61a7b65af49b8b191_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&768& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&https://pic2.zhimg.com/v2-94c4b61a7b65af49b8b191_r.jpg&&&/figure&&figure&&img src=&https://pic4.zhimg.com/v2-d880cb08e363d52ac943_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&768& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&https://pic4.zhimg.com/v2-d880cb08e363d52ac943_r.jpg&&&/figure&&figure&&img src=&https://pic4.zhimg.com/v2-76a31a6c0bc99a1be36ccb_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&768& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&https://pic4.zhimg.com/v2-76a31a6c0bc99a1be36ccb_r.jpg&&&/figure&&figure&&img src=&https://pic4.zhimg.com/v2-a1f6bd27dedebd774c6b_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&768& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&https://pic4.zhimg.com/v2-a1f6bd27dedebd774c6b_r.jpg&&&/figure&&p&1、3、5行是线性插值的结果,2、4、6是Slerp结果,仔细看的话会发现线性插值结果的中间部分和Slerp相比,颜色淡了那么一点点,除此以外差别微乎其微。也难怪Reviewer会觉得Tom White的结论不令人信服,如果没有对比,线性插值的结果看起来很好。并且由于高维空间中样本远离中心的特性,所以线性插值的均匀性和Slerp也差不多。不过有了上面的分析,再回过头来看DCGAN原文中的线性插值结果,好像中间部分看起来颜色还真是有点淡……&/p&&figure&&img src=&https://pic4.zhimg.com/v2-6af91cdec9dfa4484e4ccf_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&532& data-rawheight=&536& class=&origin_image zh-lightbox-thumb& width=&532& data-original=&https://pic4.zhimg.com/v2-6af91cdec9dfa4484e4ccf_r.jpg&&&/figure&&p&直接对比Slerp和线性插值并不是很有说服力,我们可以做一个更暴力的实验,让样本沿着一个随机方向从原点出发一直到距离原点20的位置,结果如下:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-943b494eb7cfef21ecbb6e_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&768& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&https://pic3.zhimg.com/v2-943b494eb7cfef21ecbb6e_r.jpg&&&/figure&&figure&&img src=&https://pic3.zhimg.com/v2-4bf2f93d13de2cc83801ece_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&768& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&https://pic3.zhimg.com/v2-4bf2f93d13de2cc83801ece_r.jpg&&&/figure&&figure&&img src=&https://pic4.zhimg.com/v2-4bdd375b349513cfd220d83ab09f702f_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&768& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&https://pic4.zhimg.com/v2-4bdd375b349513cfd220d83ab09f702f_r.jpg&&&/figure&&p&还是挺一目了然的,随着latent sample渐渐远离原点,图像的变化基本上是对比度越来越高,直至饱和。起码就人眼来说,这是很线性的。那么实际上呢?如果去掉Tanh层,随机取一些样本和输出图像随机位置的值,画出随着latent sample距中心距离变化的趋势,大概是下面这样:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-0b7dbadb938b_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1013& data-rawheight=&675& class=&origin_image zh-lightbox-thumb& width=&1013& data-original=&https://pic4.zhimg.com/v2-0b7dbadb938b_r.jpg&&&/figure&&p&可以看到,只有在距离中心很远的时候,线性才比较明显,这和Goodfellow论文中的图性质一致。在样本最集中的10附近,线性程度一般般,甚至有些输出都不是单调的。&/p&&p&那么更进一步,如果latent sample只产生在超球面上呢?或是到原点距离均匀分布呢?不妨试一试,结果如下:&/p&&p&1) 在到原点距离为10的超球面上产生latent sample&/p&&figure&&img src=&https://pic1.zhimg.com/v2-2382a3bace9c_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&768& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&https://pic1.zhimg.com/v2-2382a3bace9c_r.jpg&&&/figure&&figure&&img src=&https://pic2.zhimg.com/v2-a0afc6e1a72554ffb62c9_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&768& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&https://pic2.zhimg.com/v2-a0afc6e1a72554ffb62c9_r.jpg&&&/figure&&figure&&img src=&https://pic4.zhimg.com/v2-baeace5b5bb91a5567f3efb_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&768& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&https://pic4.zhimg.com/v2-baeace5b5bb91a5567f3efb_r.jpg&&&/figure&&figure&&img src=&https://pic2.zhimg.com/v2-02eac9ccfadd49_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&990& data-rawheight=&668& class=&origin_image zh-lightbox-thumb& width=&990& data-original=&https://pic2.zhimg.com/v2-02eac9ccfadd49_r.jpg&&&/figure&&p&肉眼看上去还是很线性,输出曲线的结果看上去和直接Gaussian采样差别也不大。&/p&&p&2) latent sample到原点距离从0到10均匀分布&/p&&figure&&img src=&https://pic1.zhimg.com/v2-d5a6abc84fb7017d57bfe2e56ddcc97c_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&768& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&https://pic1.zhimg.com/v2-d5a6abc84fb7017d57bfe2e56ddcc97c_r.jpg&&&/figure&&figure&&img src=&https://pic2.zhimg.com/v2-e4ffde1460dba100a0c61_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&768& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&https://pic2.zhimg.com/v2-e4ffde1460dba100a0c61_r.jpg&&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-c71f018c9bdea1b5f99bdc_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&768& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&768& data-original=&https://pic1.zhimg.com/v2-c71f018c9bdea1b5f99bdc_r.jpg&&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-aa0b22eba6c92cb5f3cce9c_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&984& data-rawheight=&667& class=&origin_image zh-lightbox-thumb& width=&984& data-original=&https://pic1.zhimg.com/v2-aa0b22eba6c92cb5f3cce9c_r.jpg&&&/figure&&p&从曲线来看和前两种情况明显不一样了,生成图像质量也下降了一些。但是从产生的图片来看线性仍然较强,至少到中心距离&10的部分,图片“身份”无区分度的结论还是基本成立。&/p&&p&这是个很有趣的现象,无论是Gaussian采样,还是1)和2)的情况,对人眼来说,这种很粗略程度的线性已经足够让沿着某个方向上的latent sample产生从“身份”角度看上去无差别的样本了。不管怎么样,基于这个现象,得到一个粗略的推论:&b&GAN的Latent Space只有沿着超球面的变化才是有区分力的&/b&。&/p&&h2&在Great Circle上行走&/h2&&p&经过一番分析,得到了一个好像也没什么用的结论。再回来看最初的问题,线性插值会路过低概率区域(虽然并没有什么影响),Slerp比线性插值也没什么视觉上的本质提高,那么有没有什么更优雅地行走在latent space的方法呢?我觉得是:&a href=&http://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Great_circle& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Great Circle&/a&。比起Slerp,Greate Circle通常要经过多3倍的距离,虽然这和Slerp其实也没什么本质区别,但是感觉上要更屌,而且沿着great circle走起点和终点是同一个点,这感觉更屌。&/p&&p&产生great circle路径比Slerp要简单得多:1)根据所使用分布产生一个超球面半径r(按前面讨论,Gaussian的话就是chi分布,或者Gaussian近似);2)产生一个随机向量u和一个与u垂直的随机向量v,然后把u和v所在平面作为great circle所在平面;3)u和v等效于一个坐标系的两轴,所以great circle上任一点就用在u和v上的投影表示就可以,最后在乘上r就得到了行走在great circle上的采样。代码如下:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&from __future__ import print_function
import argparse
import numpy
from scipy.stats import chi
import torch.utils.data
from torch.autograd import Variable
from networks import NetG
from PIL import Image
parser = argparse.ArgumentParser()
parser.add_argument('--nz', type=int, default=100, help='size of the latent z vector')
parser.add_argument('--niter', type=int, default=10, help='how many paths')
parser.add_argument('--n_steps', type=int, default=23, help='steps to walk')
parser.add_argument('--ngf', type=int, default=64)
parser.add_argument('--ngpu', type=int, default=1, help='number of GPUs to use')
parser.add_argument('--netG', default='netG_epoch_49.pth', help=&trained params for G&)
opt = parser.parse_args()
output_dir = 'gcircle-walk'
os.system('mkdir -p {}'.format(output_dir))
print(opt)
ngpu = int(opt.ngpu)
nz = int(opt.nz)
ngf = int(opt.ngf)
netG = NetG(ngf, nz, nc, ngpu)
netG.load_state_dict(torch.load(opt.netG, map_location=lambda storage, loc: storage))
netG.eval()
print(netG)
for j in range(opt.niter):
r = chi.rvs(df=100)
u = numpy.random.normal(0, 1, nz)
w = numpy.random.normal(0, 1, nz)
u /= numpy.linalg.norm(u)
w /= numpy.linalg.norm(w)
v = w - numpy.dot(u, w) * u
v /= numpy.linalg.norm(v)
ndimgs = []
for i in range(opt.n_steps):
t = float(i) / float(opt.n_steps)
z = numpy.cos(t * 2 * numpy.pi) * u + numpy.sin(t * 2 * numpy.pi) * v
noise_t = z.reshape((1, nz, 1, 1))
noise_t = torch.FloatTensor(noise_t)
noisev = Variable(noise_t)
fake = netG(noisev)
timg = fake[0]
timg = timg.data
timg.add_(1).div_(2)
ndimg = timg.mul(255).clamp(0, 255).byte().permute(1, 2, 0).numpy()
ndimgs.append(ndimg)
print('exporting {} ...'.format(j))
ndimg = numpy.hstack(ndimgs)
im = Image.fromarray(ndimg)
filename = os.sep.join([output_dir, 'gc-{:0&6d}.png'.format(j)])
im.save(filename)
&/code&&/pre&&/div&&p&结果如下:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-dc2bddef46e08c87fbedb33c_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1472& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&1472& data-original=&https://pic1.zhimg.com/v2-dc2bddef46e08c87fbedb33c_r.jpg&&&/figure&&figure&&img src=&https://pic2.zhimg.com/v2-644fee0131a85fba00eebd_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1472& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&1472& data-original=&https://pic2.zhimg.com/v2-644fee0131a85fba00eebd_r.jpg&&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-5adb40e9cef4_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1472& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&1472& data-original=&https://pic1.zhimg.com/v2-5adb40e9cef4_r.jpg&&&/figure&&figure&&img src=&https://pic4.zhimg.com/v2-3773dacf46e775b76c4eb_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1472& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&1472& data-original=&https://pic4.zhimg.com/v2-3773dacf46e775b76c4eb_r.jpg&&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-42459eff4e544c224d2f471de055bacc_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1472& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&1472& data-original=&https://pic1.zhimg.com/v2-42459eff4e544c224d2f471de055bacc_r.jpg&&&/figure&&figure&&img src=&https://pic1.zhimg.com/v2-7eab7e470_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1472& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&1472& data-original=&https://pic1.zhimg.com/v2-7eab7e470_r.jpg&&&/figure&&figure&&img src=&https://pic3.zhimg.com/v2-ac57ad8fdfc95e_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1472& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&1472& data-original=&https://pic3.zhimg.com/v2-ac57ad8fdfc95e_r.jpg&&&/figure&&figure&&img src=&https://pic3.zhimg.com/v2-18e47d4ca4dfd24e7e872da_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1472& data-rawheight=&64& class=&origin_image zh-lightbox-thumb& width=&1472& data-original=&https://pic3.zhimg.com/v2-18e47d4ca4dfd24e7e872da_r.jpg&&&/figure&&p&虽然感觉没什么用,不过万一有人想试试,代码在此:&a href=&http://link.zhihu.com/?target=https%3A//github.com/frombeijingwithlove/dlcv_for_beginners/tree/master/random_bonus/great-circle-interp& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&great-circle-interp&/a&&/p&&p&=========== 补充分割线 ===========&/p&&p&感谢 &a class=&member_mention& href=&http://www.zhihu.com/people/ebdb20dc00a4fb1e1d2358& data-hash=&ebdb20dc00a4fb1e1d2358& data-hovercard=&p$b$ebdb20dc00a4fb1e1d2358&&@李韶华&/a& 在评论里指出普通CNN如果改变输入强度会否有同样特性,用pyTorch自带的预训练resnet-18试了试,随便找了6张图,取输入强度从0到原图10倍,结果如下:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-d0efc52abc5f37c68ae717_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1006& data-rawheight=&677& class=&origin_image zh-lightbox-thumb& width=&1006& data-original=&https://pic4.zhimg.com/v2-d0efc52abc5f37c68ae717_r.jpg&&&/figure&&p&输入强度大了之后可以看到预期中的强线性。定性来看输入强度越大,任意神经元上的值偏离“零点”越来越远,这个过程中路过ReLU的零点的可能性就越来越低,所以线性会越来越强。从图上看,在合理范围内(0~2),resnet-18的非线性响应比GAN明显很多,个人猜测可能是因为分类网络对输入输出都没有假设,不像GAN的latent space是有简单prior,而且都是高度对称的分布,很可能起到了regularization的作用。定性来看这也许解释了为什么PPGN一类的网络产生diversity强的图片质量高很多,广义看C-GAN也可以这么理解。这也许并不是那么无聊的问题,我也想知道答案。&/p&
从Slerp说起ICLR'2017的投稿里,有一篇很有意思但被拒掉的投稿《》 by 。文章比较松散地讲了一些在latent space挺有用的采样和可视化技巧,其中一个重要的点是指出在GAN的latent space中,比起常用的线性插值,沿着两…
&h2&背景&/h2&&p&我的爸爸妈妈都是一个西南小城的大学老师。自从有记忆的时候开始,每次到他们期末考试的时候,他们就要花上好几天的时间改卷。最近几年,步入中年的他们开始老花了,改卷越来越费力,特别是我妈妈本身就高度近视,所以有时候得让学生帮忙。但是每张试卷四十到六十道选择题,我爸上的还是公共课,学生更多。&/p&&p&今年过年的时候,我刚毕业还没入职,赋闲在家,就请了两个研究生同学跑来家里玩,然后他们也“顺便”改了一下选择题。整个过程非常枯燥,得吃好几碗螺丝粉才能补回来。然后我忽然意识到,我们三个可能是家乡历史上出现过计算机水平最高的三颗大脑,还都是CMU毕业搞智能信息系统的,竟然还要做这种本应该交给计算机干的活儿,于是我自然而然想到了把它自动化。&/p&&hr&&h2&痛点&/h2&&p&答题卡读卡机是很早很早就有的东西了,但是主要有几点原因爸爸妈妈他们学校一直没有用上:&/p&&ul&&li&&b&设备太贵 &/b&&/li&&/ul&&p&淘宝答题卡读卡器5000元起。加上反腐之后,审计收紧,这种价格的设备需要统一通过政府采购,价格更加高昂,如果要购买这种设备手续非常复杂。&/p&&ul&&li&&b&需要专用答题卡 &/b&&/li&&/ul&&p&这进一步提升了使用成本,一般一张答题卡的采购价是一毛钱。&/p&&ul&&li&&b&使用复杂 &/b&&/li&&/ul&&p&爸爸妈妈虽然电脑已经用得很溜了,但是现在已有的软件的操作界面还是让老一辈教师望而却步——所以有的院校得专门雇人来操作答题卡读卡器。&/p&&hr&&h2&初期调研与设计&/h2&&p&刚好我本科接触过图像和视频处理技术,在CMU的时候某个课程项目是识别手写公式转换成Latex,个人有一定的技术积累。刚好签证例行被行政审查,暂时没法入职,过年期间就开始设计这么一个系统。针对上面三点,这个系统需要有以下几个特性,我一并做了调研:&/p&&ul&&li&&b&设备尽可能简单易用&/b&&/li&&/ul&&p&之前,在我印象中扫描还是手动模式,需要扫完一张,再放下一张……&/p&&p&直到我到CMU才第一次见识了自动送纸(Auto Document Feeder)扫描仪。&/p&&p&同时我在网上看了一下价格,自动进纸扫描仪最便宜的新品是国产的 清华紫光-F20S,只要1150元包邮,这个价格就算我自己掏腰包也可以承受,而且50张的纸匣已经基本足够一般教学的使用了。&/p&&ul&&li&&b&普通打印机就能打印的黑白答题卡&/b&&/li&&/ul&&p&常见的答题卡的框线一般都做成红、绿、蓝三种颜色:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-deeadcd59a218_b.jpg& data-size=&small& data-rawwidth=&724& data-rawheight=&608& class=&origin_image zh-lightbox-thumb& width=&724& data-original=&https://pic1.zhimg.com/v2-deeadcd59a218_r.jpg&&&figcaption&彩色硬纸答题卡&/figcaption&&/figure&&p&对应计算机中RGB的颜色表示方式,这样在做图像处理的时候,能够用阈值法轻松把框线等非答案的内容筛掉筛掉,只剩下学生填涂的结果。这样,再根据四周的定位块来确定学生的填涂内容。&/p&&p&如果变成黑白的,就需要把学生填涂的内容答案从背景中分离出来,这其实增加了一点难度,但是考虑到之前在CMU的课程设计里做过类似的事情,技术上是可以解决的。&/p&&ul&&li&&b&操作步骤尽可能简单&/b&&/li&&/ul&&p&所以我需要尽可能简化使用流程,让使用者少做选择,尽可能只需要三步:选择文件——处理——得到结果&/p&&p&&br&&/p&&p&除此之外,我还想整个东西看起来厉害一点。&/p&&p&前面说道我在CMU做过类似的事情,大概的项目效果是把手写公式转换成Latex公式:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-b2f1bcab9ce0a7c7dedf386_b.jpg& data-size=&normal& data-rawwidth=&728& data-rawheight=&667& class=&origin_image zh-lightbox-thumb& width=&728& data-original=&https://pic3.zhimg.com/v2-b2f1bcab9ce0a7c7dedf386_r.jpg&&&figcaption&手写公式识别&/figcaption&&/figure&&p&看上去很酷,但实际上做了如下两个假设之后一点也不难:&/p&&ol&&li&字符之间没有粘连&/li&&li&同级的字母基本上都保持在一个水平线上&/li&&/ol&&p&难点就在有的字符是被分成两部分的,需要合并,比如等号,阶乘号和i,j……可以“启发式”合并,或者实在太难可以假设他们不存在好了……(科学就是这么进步的嘛,基础性、积累性的工作靠大部分普通人解决,挑战性的工作由少部分天才解决)&/p&&p&识别这一块,机器学习的库现在封装得太好用了,基本上搜集到数据丢进去无脑训练就行,更何况这个只是机器学习入门必读教程——识别手写数字的升级版。只需要多采集一些手写数据就好了。&/p&&p&当时我搞了这么一个表格,让爸爸妈妈在上课的时候找学生去填:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-6a93ff20e169cbf7f98e96dc_b.jpg& data-size=&normal& data-rawwidth=&503& data-rawheight=&737& class=&origin_image zh-lightbox-thumb& width=&503& data-original=&https://pic1.zhimg.com/v2-6a93ff20e169cbf7f98e96dc_r.jpg&&&figcaption&手写字符采集卡&/figcaption&&/figure&&p&然后用了一些框线检测的算法和字符提取的算法搞出了个数据集,训练模型的测试效果也还行。&/p&&p&所以我刚开始做的时候野心比较大,想把填涂式改为手写式的答题卡,因为选项最多只有ABCDEFG和勾叉。&/p&&hr&&h2&实现&/h2&&p&有了之前的想法,我就开始动手实现。&/p&&p&&b&答题卡&/b&&/p&&p&第一步肯定是核心功能,识别。第一版的答题卡设计我已经找不到了,但是大致思想跟第二版差不多,学号部分也是手写的:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-dd1c21ea23e0e9c21f2b102b_b.jpg& data-size=&normal& data-rawwidth=&441& data-rawheight=&417& class=&origin_image zh-lightbox-thumb& width=&441& data-original=&https://pic4.zhimg.com/v2-dd1c21ea23e0e9c21f2b102b_r.jpg&&&figcaption&手写版答题卡&/figcaption&&/figure&&p&不定向选择题之所以设计成这样,是因为实际使用中让学生写多个选项的时候不连笔这个假设很难成立:一方面自然是学生书写习惯的问题;另一方面,即便学生书写没有问题,也可能会因为纸张、扫描仪的问题意外出现一些笔迹的断裂和符号的粘连。&/p&&p&一旦出现笔迹断裂、字母粘连的情况,就需要加入切割算法——这恰恰是验证码中一个比较难解决的问题——更何况,验证码识别器只需要30%的准确率就能凑合用,达到60%的准确率就基本满足需求了,而评卷时的准确率是以人的识别准确率(95%以上)作为标准的。&/p&&p&同时,就算能够成功切割,往往也会引入一些变形,对识别准确率造成负面影响。&/p&&p&所以,这个表格定下来后,大致处理方法是这样:提取出三块最大的矩形,然后利用框线检测方法去掉框线,提取出表格中的字母,标准化(居中、放大、填补边缘)之后利用上次收集的手写字符数据训练分类器并识别。&/p&&p&然而,这时候我才发现,训练出来的模型能够平均达到97%的准确率,但是具体测试总会出现一些匪夷所思的识别错误,有点类似&a href=&//link.zhihu.com/?target=https%3A//arxiv.org/pdf/.pdf& class=& wrap external& target=&_blank& rel=&nof}

我要回帖

更多关于 好吊日视频72an com 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信