当前位置:首页 » 操作系统 » 包入图算法

包入图算法

发布时间: 2023-03-22 16:37:54

1. Neo4j中使用Louvain算法和标签传播算法(LPA)对漫威英雄进行社群分析

在本系列第一篇 在Neo4j中构建漫威世界的社交网络 中我们从英雄到漫画的二分图推导出英雄到英雄的一分图。接着在第二篇 在Neo4j中对漫威社交网络进行初步分析 中得到一些基本的网络信息以帮助我们了解正在处理的网络情况。

在本篇中我将会在漫威英雄的网络上使用Louvain算法和标签传播算法(LPA),发现一些有趣的社群。

本文中的可视化是使用Gephi来进行呈现,关于Gephi的更多信息可以看我之前的文章《Neo4j to Gephi》(https://tbgraph.wordpress.com/2017/04/01/neo4j-to-gephi/)。关于社群可视化还可以使用neovis.js(https://github.com/johnymontana/neovis.js)。

Neo4j图算法一般是在图的子集上进行,而这个子集通常是一个虚拟图,Neo4j图算法加载这种图有两种办法。第一种简单的办法是通过指定结点的标签和关系的类型将其加载到图算法中。

但是,如果我们要运行的逻辑是在一个特定的子图上,而仅使用结点标签和关系类型无法描述出这个子图,同时也不想去修改实体图,这时要怎么办呢?

不用担心,我们还可以使用Cypher语句来指定要加载的子图。使用查询结点的Cypher语句代替结点标签参数,使用查询关系的Cypher语句来代替关系类型参数。

但是注意,在参数中一定要指明  graph:'cypher' 。

如下示例:

CALL algo.unionFind(
//第一个Cypher语句指定了要加载的结点。
    'MATCH (p:User)
WHERE p.property = 'import'
RETURN id(p) as id',
//第二个Cpyher语句指定要加载的关系
    'MATCH (p1:User)-[f:FRIEND]->(p2:User) 
RETURN id(p1) as source, id(p2) as target,f.weight as weight',
{graph:'cypher',write:true})

通过Cypher语句映射和加载子图,可以非常好的描述要运行算法的子图。不仅如此,我们还可以剔除一些关系,间接的映射一个虚拟图用于运行算法,而那些剔除的关系又并不会从实际图中删除。

Cpyher映射使用场景:

 * 过滤结点和关系

 * 加载间接关系

* 映射双向图

* 相似性阈值(后面详情介绍)

在对各种网络的研究过程中,如计算机网络、社交网络以及生物网络,我们发现了许多不同的特征,包括小世界特性,重尾分布以及聚类等等。另外,网络都有一个共同的特征即社群结构,也就是连通和分组。而现实网络世界的连通并不是随机或同质的,而是存在着某种自然的联系。

社群识别算法在一个全连通的图上运行,效果并不会很好。因为大多数据结点都是紧密连接的,他们是属于一个社群的。在这些的图上运行算法,最终结果就是:得到一个覆盖图大部分区域的大社群和一些边边角角小社群。

这时我们可以使用相似性阈值来进行调控,将大于某个值的关系保留,而小于此值的关系将会剔除。而这个虚拟图就可以通过Cypher语句轻松的映射出来了。

在本文中,我会将漫威社交网络中KNOWS的weight作为阈值,将其设置到100,大于100的关系将会保留,小于100的关于将会剔除,这样,得到的社群将会非常紧密。

连通分量或并查集算法都是找到相互连接的结点集,或者称之为岛,而在这个集合中的所有点都是可以相互连通的。

在图论中,无向图的连通分量(或者仅分量)是一个子图,其中此子图任何两个顶点通过路径相互连接。

当我遇到一个新的网络时,我第一时间想知道是:这个网络有多少个连通分量,以及他们每个都包含多少结点。在漫威英雄的网络中,当前我们已经把KNOWS的weight阈值设置到100了,而前一篇文章的阈值是10,因此,本文得到的连接肯定要比前一篇文章()中的连接要少。

在下面的示例中,我们直接使用结点标签和关系类型,所有标签为Hero的结点和所有类型为KNOWS的关系都将被加载到算法中。由于我们将阈值设置到100,所以,当前算法只考虑weight大于100的关系。

CALL algo.unionFind.stream('Hero', 'KNOWS',
{weightProperty:'weight', defaultValue:0.0, threshold:100.0,concurrency:1}) 
YIELD nodeId,setId
RETURN setId as component,count(*) as componentSize
ORDER BY componentSize DESC LIMIT 10;

正如我所料,漫威英雄网络是一个稀疏图,有1个大社群和6小社群组成,大社群有101个英雄,而小社群基本也就2~4个英雄。这表示,在6439个英雄中,有116个英雄至少一个KNOWS关系的weight值是大于100的。

如果想在浏览器中仔细浏览那个包含101英雄的大社群,会很容易发现隐藏在这里面的一些直观的东西以及社群之间的桥梁结点。接下来我们将尝试使用Louvain算法和标签传播算法来看看这个116个英雄的子图的社群结构。

社群就是网络中结点集合,它们彼此之间的连接比其他节点更紧密。Molarity是一种度量刻度,被用于衡量社群发现算法结果的质量,它能够刻画社区的紧密程度。在一个随机的网络中,将一个结点归类到某一个社群,Molarity值就是会生变化,进而给出这种分配后社区的质量。Molarity即量化了此结点与社群中其他结点的连接紧密程度。社群识别的Louvain方法,是一种基于启发式Molarity最大化的网络社群检测算法。

如前所述,我们将通过Cypher查询来仅映射weight大于110的关系到算法中。

CALL algo.louvain.stream(
// load nodes
    'MATCH (u:Hero) RETURN id(u) as id', 
// load relationships
    'MATCH (u1:Hero)-[rel:KNOWS]-(u2:Hero) 
// similarity threshold
WHERE rel.weight > 100
RETURN id(u1) as source,id(u2) as target',
{graph:"cypher"}) 
YIELD nodeId,community
MATCH (n:Hero) WHERE id(n)=nodeId
RETURN community,
count(*) as communitySize,
collect(n.name) as members
order by communitySize desc limit 5

我使用Gephi进行社群结果可视化,因为Gephi的表现力比表格更好,更有洞察力。

我并不是漫威漫画的专家,所以我只能根据数据来做一个简单的解释。我们总共划分出8个社群。最大的社群是紫色的社群,它由以美国队长为首的神盾局和复仇者联盟组成。在左边我们能看到神奇先生和神奇四侠也在紫色社群里。亮兰色是蜘蛛侠团队,蜘蛛侠帕克是他们与外界联系的唯一桥梁,其他人都是内部交流,与外界并无联系。深兰色是阿斯加德人,他们也是比较封闭,他们仅仅和雷神托尔有联系。哦?难以置信,绿巨人也是自己的社群(粉红色),而绿巨人是这个社群唯一与外界有联系的英雄。我们还看到野兽亨利是紫色社群与绿色社群的桥梁,位置特殊,而绿色是X-Men社群。

标签传播算法是由Raghavan等人于2007年首次提出,(译者言:网络显示此算法于2002年由Zhu等人提出)此算法是由每个结点使用其唯一标识作为标签,然后根据大多数邻居结点的标签为基础进行标签传播,每个结点再从他的邻居结点身上取出现次数最多的标签加到自己身上。LPA算法的具体步骤是这样:结点X有一些邻居结点,且每个邻居结点都有一个标签,标明他们所属的社群。然后网络中的每个结点都选择加入其大多数邻居所属的那个社群,同时再随机的断开一些连接。在开始时,每个节点都用唯一标签进行初始化,然后这些标签开始在网络中进行传播,传播的每一步,每个结点都会根据邻居标签的情况更新自己的标签,随着标签的传播,最终连接紧密的结点集合将会达成一个共识,而他们身上的标签也将不再发生变化。

与Louvaint算法类似,我们也采用Cypher语句进行图映射,在映射时仅加载weight值大于KNOWS关系。同时会将对结点进行回写,导出结果到Gephi中进行可视化展示。

CALL algo.labelPropagation(
// supports node-weights and defining
// initial communities using parameter value
    'MATCH (u:Hero) RETURN id(u) as id, 1 as weight,id(u) as value',
// load relationships
    'MATCH (u1:Hero)-[rel:KNOWS]-(u2:Hero) 
// Similarity threshold
WHERE rel.weight > 100
RETURN id(u1) as source,id(u2) as target, rel.weight as weight',
'OUT',{graph:"cypher",partitionProperty:"lpa" }) 
YIELD computeMillis

最终我们得到21个社群,包括单点社群。复仇者联盟(紫色)和神奇四侠(亮兰色)被分为两个社群了。蜘蛛侠(绿色),绿巨人(青绿色)和阿斯加德人(红色)三个社群的结果与Louvain算法一致。我们还发现X-Man被划分成两个社群,加农炮小组比Louvain的结果要稍微大点,同时也显的不那么孤立。

你发现没有?Neo4j图算法库真的很神奇,用起来也简单。通过与Cypher查询语句结合进行虚拟图映射,可以简单有效的对图进行分析和理解。

本来,我打算在本文中介绍中心性算法的使用,但那样本文将会非常长,不便于阅读,所以, 我后续将会再写文章来介绍使用Cypher映射进行中心性算法的示例。敬请期待吧。

2. 基本算法——深度优先搜索(DFS)和广度优先搜索(BFS)

        深度优先搜索和广度优先搜索,都是图形搜索算法,它两相似,又却不同,在应用上也被用到不同的地方。这里拿一起讨论,方便比较。

一、深度优先搜索

        深度优先搜索属于图算法的一种,是一个针对图和树的遍历算法,英文缩写为DFS即Depth First Search。深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图论问题,如最大路径问题等等。一般用堆数据结构来辅助实现DFS算法。其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。

基本步奏

(1)对于下面的树而言,DFS方法首先从根节点1开始,其搜索节点顺序是1,2,3,4,5,6,7,8(假定左分枝和右分枝中优先选择左分枝)。

(2)从stack中访问栈顶的点;

(3)找出与此点邻接的且尚未遍历的点,进行标记,然后放入stack中,依次进行;

(4)如果此点没有尚未遍历的邻接点,则将此点从stack中弹出,再按照(3)依次进行;

(5)直到遍历完整个树,stack里的元素都将弹出,最后栈为空,DFS遍历完成。

二、广度优先搜索

        广度优先搜索(也称宽度优先搜索,缩写BFS,以下采用广度来描述)是连通图的一种遍历算法这一算法也是很多重要的图的算法的原型。Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想。其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。基本过程,BFS是从根节点开始,沿着树(图)的宽度遍历树(图)的节点。如果所有节点均被访问,则算法中止。一般用队列数据结构来辅助实现BFS算法。

基本步奏

(1)给出一连通图,如图,初始化全是白色(未访问);

(2)搜索起点V1(灰色);

(3)已搜索V1(黑色),即将搜索V2,V3,V4(标灰);

(4)对V2,V3,V4重复以上操作;

(5)直到终点V7被染灰,终止;

(6)最短路径为V1,V4,V7.

3. 图算法(一): 图的概念基本表示

图并不是现实世界中的一幅画, 例如

在计算机中, 图是一种数据结构. 图是计算机科学的一个概念, 在数学中也有对应的数学分之: 图论.

计算机中的图如果表示出来大概长成这样

可以把上图想象成一个社交网络, 网络中的每个圆表示一个User, User存在某种关系.

或者看作是一个城市群, 每个圆表示一个城市, 城市之间通过道路联通.

直观的从图片上看 有3个组成部分:

更一般的叫法是:

有了这些概念, 在理解的基础上就可以对图做一个稍微正式点的定义了

上图中的图叫做简单图, 那什么样的图不叫简单图呢? 如下所示

在顶点0, 存在一个边, 这种边称之为 自环边(self-loop)
在顶点0和1之间, 除了之前那张图片上的一条边之外, 又多了一条边, 多出来的这条边称之为 平行边(parallel)

因此, 拥有自环边或平行边的图不是简单图.

上面给出的图的示例属于最简单的 无向无权图 .

因为图的边可以附加一些信息(权), 以及边是可以有方向的, 因此图有两个大类:

进一步的组合可以分为:

不同种类的图有不同的作用, 在开始学习图算法的时候, 应先从最简单的无权无向图开始.

通过图片可以很清楚的知道图的形状, 那么如何转换到计算机中表示呢?
对于这个问题, 有两种方式:

这两种方式各有优缺点, 具体选择哪一种需要看场景

4. 数据结构的图的算法

伪代码
void DFS (int u)
{
reach[u] = 1
for (u的邻接节点v) if (reach[v]==0) DFS (v)
}

5. 图遍历算法之DFS/BFS

在计算机科学, 图遍历(Tree Traversal,也称图搜索)是一系列图搜索的算法, 是单次访问树结构类型数据(tree data structure)中每个节点以便检查或更新的一系列机制。图遍历算法可以按照节点访问顺序进行分类,根据访问目的或使用场景的不同,算法大致可分为28种:

图遍历即以特定方式访问图中所有节点,给定节点下有多种可能的搜索路径。假定以顺序方式进行(非并行),还未访问的节点就需通过堆栈(LIFO)或队列(FIFO)规则来确定访问先后。由于树结构是一种递归的数据结构,在清晰的定义下,未访问节点可存储在调用堆栈中。本文介绍了图遍历领域最流行的广度优先搜索算法BFS和深度优先搜索算法DFS,对其原理、应用及实现进行了阐述。通常意义上而言,深度优先搜索(DFS)通过递归调用堆栈比较容易实现,广义优先搜索通过队列实现。

深度优先搜索(DFS)是用于遍历或搜索图数据结构的算法,该算法从根节点开始(图搜索时可选择任意节点作为根节点)沿着每个分支进行搜索,分支搜索结束后在进行回溯。在进入下一节点之前,树的搜索尽可能的加深。
DFS的搜索算法如下(以二叉树为例):假定根节点(图的任意节点可作为根节点)标记为 ,
(L) : 递归遍历左子树,并在节点 结束。
(R): 递归遍历右子树,并在节点 结束。
(N): 访问节点 。
这些步骤可以以任意次序排列。如果(L)在(R)之前,则该过程称为从左到右的遍历;反之,则称为从右到左的遍历。根据访问次序的不同,深度优先搜索可分为 pre-order、in-order、out-order以及post-order遍历方式。

(a)检查当前节点是否为空;
(b)展示根节点或当前节点数据;
(c)递归调用pre-order函数遍历左子树;
(d)递归调用pre-order函数遍历右子树。
pre-order遍历属于拓扑排序后的遍历,父节点总是在任何子节点之前被访问。该遍历方式的图示如下:

遍历次序依次为:F -B -A-D- C-E-G- I-H.

(a)检查当前节点是否为空;
(b)递归调用in-order函数遍历左子树;
(c)展示根节点或当前节点数据;
(d)递归调用in-order函数遍历右子树。
在二叉树搜索中,in-order遍历以排序顺序访问节点数据。该遍历方式的图示如下:

遍历次序依次为:A -B - C - D - E - F - G -H-I

(a)检查当前节点是否为空;
(b)递归调用out-order函数遍历右子树;
(c)展示根节点或当前节点数据;
(d)递归调用out-order函数遍历左子树。
该遍历方式与LNR类似,但先遍历右子树后遍历左子树。仍然以图2为例,遍历次序依次为:H- I-G- F- B- E- D- C- A.

(a)检查当前节点是否为空;
(b)递归调用post-order函数遍历左子树;
(c)递归调用post-order函数遍历右子树;
(d)展示根节点或当前节点数据。
post-order遍历图示如下:

遍历次序依次为:A-C-E-D-B-H-I-G-F.

pre-order遍历方式使用场景:用于创建树或图的副本;
in-order遍历使用场景:二叉树遍历;
post-order遍历使用场景:删除树

遍历追踪也称树的序列化,是所访问根节点列表。无论是pre-order,in-order或是post-order都无法完整的描述树特性。给定含有不同元素的树结构,pre-order或post-order与in-order遍历方式结合起来使用才可以描述树的独特性。

树或图形的访问也可以按照节点所处的级别进行遍历。在每次访问下一层级节点之前,遍历所在高层级的所有节点。BFS从根节点(图的任意节点可作为根节点)出发,在移动到下一节点之前访问所有相同深度水平的相邻节点。

BFS的遍历方法图示如下:

遍历次序依次为: F-B-G-A-D-I-C-E-H.

图算法相关的R包为igraph,主要包括图的生成、图计算等一系列算法的实现。

使用方法:

参数说明:

示例:

结果展示:

DFS R输出节点排序:

使用方法:

参数含义同dfs
示例:

结果展示:

BFS R输出节点排序:

以寻找两点之间的路径为例,分别展示BFS及DFS的实现。图示例如下:

示例:

输出结果:

示例:

输出结果:

[1] 维基网络: https://en.wikipedia.org/wiki/Tree_traversal
[2] GeeksforGeeks: https://www.geeksforgeeks.org/tree-traversals-inorder-preorder-and-postorder/
[3] http://webdocs.cs.ualberta.ca/~holte/T26/tree-traversal.html
[4]Martin Broadhurst, Graph Algorithm: http://www.martinbroadhurst.com/Graph-algorithms.html#section_1_1
[5]igraph: https://igraph.org/r/doc/dfs.html
[6]igraph: https://igraph.org/r/doc/bfs.html
[7] Depth-First Search and Breadth-First Search in python: https://eddmann.com/posts/depth-first-search-and-breadth-first-search-in-python/

6. 数据结构中图算法都能解答生活中什么样的问题

如两地最短距离,判断一个工程能否顺利完成,以完成某个工程需要的最短时间等

7. 【目标检测算法解读】yolo系列算法二

https://blog.csdn.net/Gentleman_Qin/article/details/84349144

|声明:遵循CC 4.0 BY-SA版权协议

    建立在YOLOv1的基础上,经过Joseph Redmon等的改进,YOLOv2和YOLO9000算法在2017年CVPR上被提出,并获得最佳论文提名,重点解决YOLOv1召回率和定位精度方面的误差。在提出时,YOLOv2在多种监测数据集中都要快过其他检测系统,并可以在速度与精确度上进行权衡。

    YOLOv2采用Darknet-19作为特征提取网络,增加了批量标准化(Batch Normalization)的预处理,并使用224×224和448×448两阶段训练ImageNet,得到预训练模型后fine-tuning。

    相比于YOLOv1是利用FC层直接预测Bounding Box的坐标,YOLOv2借鉴了FSR-CNN的思想,引入Anchor机制,利用K-Means聚类的方式在训练集中聚类计算出更好的Anchor模板,在卷积层使用Anchor Boxes操作,增加Region Proposal的预测,同时采用较强约束的定位方法,大大提高算法召回率。同时结合图像细粒度特征,将浅层特征与深层特征相连,有助于对小尺寸目标的检测。 

    下图所示是YOLOv2采取的各项改进带了的检测性能上的提升:

    YOLO9000 的主要检测网络也是YOLO v2,同时使用WordTree来混合来自不同的资源的训练数据,并使用联合优化技术同时在ImageNet和COCO数据集上进行训练,目的是利用数量较大的分类数据集来帮助训练检测模型,因此,YOLO 9000的网络结构允许实时地检测超过9000种物体分类,进一步缩小了检测数据集与分类数据集之间的大小代沟。

    下面将具体分析YOLOv2的各个创新点:

BN概述:

    对数据进行预处理(统一格式、均衡化、去噪等)能够大大提高训练速度,提升训练效果。BN正是基于这个假设的实践,对每一层输入的数据进行加工。

    BN是2015年Google研究员在论文《Batch Normalization: Accelerating Deep Network Training by Recing Internal Covariate Shift》一文中提出的,同时也将BN应用到了2014年的GoogLeNet上,也就是Inception-v2。

    BN层简单讲就是对网络的每一层的输入都做了归一化,这样网络就不需要每层都去学数据的分布,收敛会更快。YOLOv1算法(采用的是GoogleNet网络提取特征)是没有BN层的,而在YOLOv2中作者为每个卷积层都添加了BN层。

    使用BN对网络进行优化,让网络提高了收敛性,同时还消除了对其他形式的正则化(regularization)的依赖,因此使用BN后可以从模型中去掉Dropout,而不会产生过拟合。

BN优点:

神经网络每层输入的分布总是发生变化,加入BN,通过标准化上层输出,均衡输入数据分布,加快训练速度,因此可以设置较大的学习率(Learning Rate)和衰减(Decay);

通过标准化输入,降低激活函数(Activation Function)在特定输入区间达到饱和状态的概率,避免梯度弥散(Gradient Vanishing)问题;

输入标准化对应样本正则化,BN在一定程度上可以替代 Dropout解决过拟合问题。

BN算法:

    在卷积或池化之后,激活函数之前,对每个数据输出进行标准化,方式如下图所示:

    公式很简单,前三行是 Batch内数据归一化(假设一个Batch中有每个数据),同一Batch内数据近似代表了整体训练数据。第四行引入了附加参数 γ 和 β,此二者的取值算法可以参考BN论文,在此不再赘述。

    fine-tuning:用已经训练好的模型,加上自己的数据集,来训练新的模型。即使用别人的模型的前几层,来提取浅层特征,而非完全重新训练模型,从而提高效率。一般新训练模型准确率都会从很低的值开始慢慢上升,但是fine-tuning能够让我们在比较少的迭代次数之后得到一个比较好的效果。

    YOLO模型分为两部分,分类模型和检测模型,前者使用在ImageNet上预训练好的模型,后者在检测数据集上fine-tuning。

    YOLOv1在预训练时采用的是224*224的输入(在ImageNet数据集上进行),然后在检测的时候采用448*448的输入,这会导致从分类模型切换到检测模型的时候,模型还要适应图像分辨率的改变。

    YOLOv2则将预训练分成两步:先用224*224的输入在ImageNet数据集训练分类网络,大概160个epoch(将所有训练数据循环跑160次)后将输入调整到448*448,再训练10个epoch(这两步都是在ImageNet数据集上操作)。然后利用预训练得到的模型在检测数据集上fine-tuning。这样训练得到的模型,在检测时用448*448的图像作为输入可以顺利检测。

    YOLOv1将输入图像分成7*7的网格,每个网格预测2个Bounding Box,因此一共有98个Box,同时YOLOv1包含有全连接层,从而能直接预测Bounding Boxes的坐标值,但也导致丢失较多的空间信息,定位不准。

    YOLOv2首先将YOLOv1网络的FC层和最后一个Pooling层去掉,使得最后的卷积层可以有更高分辨率的特征,然后缩减网络,用416*416大小的输入代替原来的448*448,使得网络输出的特征图有奇数大小的宽和高,进而使得每个特征图在划分单元格(Cell)的时候只有一个中心单元格(Center Cell)。

    为什么希望只有一个中心单元格呢?由于图片中的物体都倾向于出现在图片的中心位置,特别是比较大的物体,所以有一个单元格单独位于物体中心的位置用于预测这些物体。

    YOLOv2通过引入Anchor Boxes,通过预测Anchor Box的偏移值与置信度,而不是直接预测坐标值。YOLOv2的卷积层采用32这个值来下采样图片,所以通过选择416*416用作输入尺寸最终能输出一个13*13的特征图。若采用FSRCNN中的方式,每个Cell可预测出9个Anchor Box,共13*13*9=1521个(YOLOv2确定Anchor Boxes的方法见是维度聚类,每个Cell选择5个Anchor Box)。

    在FSRCNN中,以一个51*39大小的特征图为例,其可以看做一个尺度为51*39的图像,对于该图像的每一个位置,考虑9个可能的候选窗口:3种面积3种比例。这些候选窗口称为Anchor Boxes。下图示出的是51*39个Anchor Box中心,以及9种Anchor Box示例。

YOLOv1和YOLOv2特征图数据结构:

YOLOv1:S*S* (B*5 + C) => 7*7(2*5+20)

    其中B对应Box数量,5对应边界框的定位信息(w,y,w,h)和边界框置信度(Confidience)。分辨率是7*7,每个Cell预测2个Box,这2个Box共用1套条件类别概率(1*20)。

YOLOv2:S*S*K* (5 + C) => 13*13*9(5+20)

    分辨率提升至13*13,对小目标适应性更好,借鉴了FSRCNN的思想,每个Cell对应K个Anchor box(YOLOv2中K=5),每个Anchor box对应1组条件类别概率(1*20)。

    聚类:聚类是指事先没有“标签”而通过某种成团分析找出事物之间存在聚集性原因的过程。即在没有划分类别的情况下,根据数据相似度进行样本分组。

    在FSR-CNN中Anchor Box的大小和比例是按经验设定的,然后网络会在训练过程中调整Anchor Box的尺寸,最终得到准确的Anchor Boxes。若一开始就选择了更好的、更有代表性的先验Anchor Boxes,那么网络就更容易学到准确的预测位置。

    YOLOv2使用K-means聚类方法类训练Bounding Boxes,可以自动找到更好的宽高维度的值用于一开始的初始化。传统的K-means聚类方法使用的是欧氏距离函数,意味着较大的Anchor Boxes会比较小的Anchor Boxes产生更多的错误,聚类结果可能会偏离。由于聚类目的是确定更精准的初始Anchor Box参数,即提高IOU值,这应与Box大小无关,因此YOLOv2采用IOU值为评判标准,即K-means 采用的距离函数(度量标准) 为:

d(box,centroid) = 1 - IOU(box,centroid)

    如下图,左边是聚类的簇个数和IOU的关系,两条曲线分别代表两个不同的数据集。分析聚类结果并权衡模型复杂度与IOU值后,YOLOv2选择K=5,即选择了5种大小的Box 维度来进行定位预测。

    其中紫色和灰色也是分别表示两个不同的数据集,可以看出其基本形状是类似的。更重要的是,可以看出聚类的结果和手动设置的Anchor Box位置和大小差别显着——结果中扁长的框较少,而瘦高的框更多(更符合行人的特征)。

    YOLOv2采用的5种Anchor的Avg IOU是61,而采用9种Anchor Boxes的Faster RCNN的Avg IOU是60.9,也就是说本文仅选取5种box就能达到Faster RCNN的9中box的效果。选择值为9的时候,AVG IOU更有显着提高。说明K-means方法的生成的boxes更具有代表性。

    直接对Bounding Boxes求回归会导致模型不稳定,其中心点可能会出现在图像任何位置,有可能导致回归过程震荡,甚至无法收敛,尤其是在最开始的几次迭代的时候。大多数不稳定因素产生自预测Bounding Box的中心坐标(x,y)位置的时候。

    YOLOv2的网络在特征图(13*13)的每一个单元格中预测出5个Bounding Boxes(对应5个Anchor Boxes),每个Bounding Box预测出5个值(tx,ty,tw,th,t0),其中前4个是坐标偏移值,t0是置信度结果(类似YOLOv1中的边界框置信度Confidence)。YOLOv2借鉴了如下的预测方式,即当Anchor Box的中心坐标和宽高分别是(xa,ya)和(wa,wh)时,Bounding Box坐标的预测偏移值(tx,ty,tw,th)与其坐标宽高(x,y,w,h)的关系如下:                         

tx = (x-xa)/wa

ty= (y-ya)/ha

tw = log(w/wa)

th = log(h/ha)

    基于这种思想,YOLOv2在预测Bounding Box的位置参数时采用了如下强约束方法:

    上图中,黑色虚线框是Anchor Box,蓝色矩形框就是预测的Bounding Box结果,预测出的Bounding Box的坐标和宽高为(bx,by)和(bw,bh),计算方式如图中所示,其中:对每个Bounding Box预测出5个值(tx,ty,tw,th,t0),Cell与图像左上角的横纵坐标距离为(cx,cy),σ定义为sigmoid激活函数(将函数值约束到[0,1]),该Cell对应的Anchor Box对应的宽高为(pw,ph)。

    简而言之,(bx,by)就是(cx,cy)这个Cell附近的Anchor Box针对预测值(tx,ty)得到的Bounding Box的坐标预测结果,同时可以发现这种方式对于较远距离的Bounding Box预测值(tx,ty)能够得到很大的限制。

    YOLOv2通过添加一个转移层,把高分辨率的浅层特征连接到低分辨率的深层特征(把特征堆积在不同Channel中)而后进行融合和检测。具体操作是先获取前层的26*26的特征图,将其同最后输出的13*13的特征图进行连接,而后输入检测器进行检测(检测器的FC层起到了全局特征融合的作用),以此来提高对小目标的检测能力。    

    为了适应不同尺度下的检测任务,YOLOv2在训练网络时,其在检测数据集上fine-tuning时候采用的输入图像的size是动态变化的。具体来讲,每训练10个Batch,网络就会随机选择另一种size的输入图像。因为YOLOv2用到了参数是32的下采样,因此也采用32的倍数作为输入的size,即采用{320,352,…,608}的输入尺寸(网络会自动改变尺寸,并继续训练的过程)。

这一策略让网络在不同的输入尺寸上都能达到较好的预测效果,使同一网络能在不同分辨率上进行检测。输入图片较大时,检测速度较慢,输入图片较小时,检测速度较快,总体上提高了准确率,因此多尺度训练算是在准确率和速度上达到一个平衡。

    上表反映的是在检测时,不同大小的输入图片情况下的YOLOv2和其他目标检测算法的对比。可以看出通过多尺度训练的检测模型,在测试的时候,输入图像在尺寸变化范围较大的情况下也能取得mAP和FPS的平衡。

    YOLOv1采用的训练网络是GoogleNet,YOLOv2采用了新的分类网络Darknet-19作为基础网络,它使用了较多的3*3卷积核,并把1*1的卷积核置于3*3的卷积核之间,用来压缩特征,同时在每一次池化操作后把通道(Channels)数翻倍(借鉴VGG网络)。

    YOLOv1采用的GooleNet包含24个卷积层和2个全连接层,而Darknet-19包含19个卷积层和5个最大池化层(Max Pooling Layers),后面添加Average Pooling层(代替v1中FC层),而Softmax分类器作为激活被用在网络最后一层,用来进行分类和归一化。

    在ImageNet数据集上进行预训练,主要分两步(采用随机梯度下降法):

输入图像大小是224*224,初始学习率(Learning Rate)为0.1,训练160个epoch,权值衰减(Weight Decay)为0.0005,动量(Momentum)为0.9,同时在训练时采用标准的数据增强(Data Augmentation)方式如随机裁剪、旋转以及色度、亮度的调整。

fine-tuning:第1步结束后,改用448*448输入(高分辨率模型),学习率改为0.001,训练10个epoch,其他参数不变。结果表明:fine-tuning后的top-1准确率为76.5%,top-5准确率为93.3%,若按照原来的训练方式,Darknet-19的top-1准确率是72.9%,top-5准确率为91.2%。可以看出,两步分别从网络结构和训练方式方面入手提高了网络分类准确率。

    预训练之后,开始基于检测的数据集再进行fine-tuning。    

    首先,先把最后一个卷积层去掉,然后添加3个3*3的卷积层,每个卷积层有1024个卷积核,并且后面都连接一个1*1的卷积层,卷积核个数(特征维度)根据需要检测的类数量决定。(比如对VOC数据,每个Cell需要预测5个Boungding Box,每个Bounding Box有4个坐标值、1个置信度值和20个条件类别概率值,所以每个单元格对应125个数据,此时卷积核个数应该取125。)

    然后,将最后一个3*3*512的卷积层和倒数第2个卷积层相连(提取细粒度特征),最后在检测数据集上fine-tuning预训练模型160个epoch,学习率采用0.001,并且在第60和90个epoch的时候将学习率除以10,权值衰减、动量和数据增强方法与预训练相同。

    YOLO9000通过结合分类和检测数据集,使得训练得到的模型可以检测约9000类物体,利用带标注的分类数据集量比较大的特点,解决了带标注的检测数据集量比较少的问题。具体方法是:一方面采用WordTree融合数据集,另一方面联合训练分类数据集和检测数据集。

    分类数据集和检测数据集存在较大差别:检测数据集只有粗粒度的标记信息,如“猫”、“狗”,而分类数据集的标签信息则更细粒度,更丰富。比如“狗”就包括“哈士奇”、“金毛狗”等等。所以如果想同时在检测数据集与分类数据集上进行训练,那么就要用一种一致性的方法融合这些标签信息。

    用于分类的方法,常用Softmax(比如v2),Softmax意味着分类的类别之间要互相独立的,而ImageNet和COCO这两种数据集之间的分类信息不相互独立(ImageNet对应分类有9000种,而COCO仅提供80种目标检测),所以使用一种多标签模型来混合数据集,即假定一张图片可以有多个标签,并且不要求标签之间独立,而后进行Softmax分类。

    由于ImageNet的类别是从WordNet选取的,作者采用以下策略重建了一个树形结构(称为WordTree):

遍历ImageNet的标签,然后在WordNet中寻找该标签到根节点(所有的根节点为实体对象)的路径;

如果路径只有一条,将该路径直接加入到WordTree结构中;

否则,从可选路径中选择一条最短路径,加入到WordTree结构中。

WordTree的作用就在于将两种数据集按照层级进行结合。

    如此,在WordTree的某个节点上就可以计算该节点的一些条件概率值,比如在terrier这个节点,可以得到如下条件概率值:

    进而,如果要预测此节点的概率(即图片中目标是Norfolk terrier的概率),可以根据WordTree将该节点到根节点的条件概率依次相乘得到,如下式:

其中:        

    YOLO9000在WordTree1k(用有1000类别的ImageNet1k创建)上训练了Darknet-19模型。为了创建WordTree1k作者添加了很多中间节点(中间词汇),把标签由1000扩展到1369。

    训练过程中GroundTruth标签要顺着向根节点的路径传播:为了计算条件概率,模型预测了一个包含1369个元素的向量,而且基于所有“同义词集”计算Softmax,其中“同义词集”是同一概念下的所属词。

    现在一张图片是多标记的,标记之间不需要相互独立。在训练过程中,如果有一个图片的标签是“Norfolk terrier”,那么这个图片还会获得“狗”以及“哺乳动物”等标签。

    如上图所示,之前的ImageNet分类是使用一个大Softmax进行分类,而现在WordTree只需要对同一概念下的同义词进行Softmax分类。然后作者分别两个数据集上用相同训练方法训练Darknet-19模型,最后在ImageNet数据集上的top-1准确率为72.9%,top-5准确率为91.2%;在WordTree数据集上的top-1准确率为71.9%,top-5准确率为90.4%。

    这种方法的好处是有“退而求其次”的余地:在对未知或者新的物体进行分类时,性能损失更低,比如看到一个狗的照片,但不知道是哪种种类的狗,那么就预测其为“狗”。

    以上是构造WordTree的原理,下图是融合COCO数据集和ImageNet数据集以及生成它们的WordTree的示意图(用颜色区分了COCO数据集和ImageNet数据集的标签节点), 混合后的数据集对应的WordTree有9418个类。另一方面,由于ImageNet数据集太大,YOLO9000为了平衡两个数据集之间的数据量,通过过采样(Oversampling)COCO数据集中的数据,使COCO数据集与ImageNet数据集之间的数据量比例达到1:4。

    对YOLO9000进行评估,发现其mAP比DPM高,而且YOLO有更多先进的特征,YOLO9000是用部分监督的方式在不同训练集上进行训练,同时还能检测9000个物体类别,并保证实时运行。虽然YOLO9000对动物的识别性能很好,但是对衣服或者装备的识别性能不是很好(这跟数据集的数据组成有关)。

    YOLO9000的网络结构和YOLOv2类似,区别是每个单元格只采用3个Anchor Boxes。

    YOLO9000提出了一种在分类数据集和检测数据集上联合训练的机制,即使用检测数据集(COCO)的图片去学习检测相关的信息即查找对象(例如预测边界框坐标、边界框是否包含目标及目标属于各个类别的概率),使用仅有类别标签的分类数据集(ImageNet)中的图片去扩展检测到的对象的可识别种类。

    具体方法是:当网络遇到一个来自检测数据集的图片与标记信息,就把这些数据用完整的损失函数(v2和9000均沿用了v1网络的损失函数)反向传播,而当网络遇到一个来自分类数据集的图片和分类标记信息,只用代表分类误差部分的损失函数反向传播这个图片。

    YOLO v2 在大尺寸图片上能够实现高精度,在小尺寸图片上运行更快,可以说在速度和精度上达到了平衡,具体性能表现如下所示。

coco数据集

voc2012数据集

热点内容
精通脚本 发布:2025-05-20 14:42:56 浏览:385
东方财富经典版如何更改密码 发布:2025-05-20 14:42:43 浏览:943
砸口红解压 发布:2025-05-20 14:41:02 浏览:510
配置sp失败怎么办 发布:2025-05-20 14:35:08 浏览:178
java学到什么程度 发布:2025-05-20 14:31:54 浏览:480
压缩误差分析 发布:2025-05-20 14:27:53 浏览:97
每秒上亿次访问服务器怎么处理 发布:2025-05-20 14:10:07 浏览:315
按键精灵数据库操作 发布:2025-05-20 14:08:33 浏览:592
360浏览器无法访问网络 发布:2025-05-20 14:05:13 浏览:834
存储服务器地址错误 发布:2025-05-20 14:01:46 浏览:912