/
search.xml
232 lines (232 loc) · 146 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[K-Net:Towards Unified Image Segmentation]]></title>
<url>%2F2022%2F05%2F20%2FK-Net%2F</url>
<content type="text"><![CDATA[Paper: [NeurIPS 2021] K-Net: Towards Unified Image Segmentation Arxiv: https://arxiv.org/abs/2106.14855 Github: https://github.com/ZwwWayne/K-Net/ 介绍 语义、实例和全景分割之间尽管存在潜在联系,但是它们使用不同的和特定的框架来解决各自任务。这个工作为这些任务提供了一个统一、简单且有效的框架,即 K-Net。它通过一组可学习的 kernels 来分割实例和语义类别,其中每个 kernel 负责为潜在实例或 stuff 类别生成 mask。为了解决区分不同实例的困难,论文提出一种 kernel update 策略,改策略使每个 kernel 能够动态并以输入图像中意义组为条件。K-Net 可以通过二分匹配进行端到端的训练,其中训练和推理是不需要 NMS 和 矩形框的。 在传统的语义分割中,每个 convolutinal kernel 对应一个语义类。我们的框架扩展了这个概念,是每个 kernel 对应一个潜在的实例或者一个语义类。 在本文中,我们首次尝试制定一个统一且有效的框架,通过 kernels 的概念来连接看似不同的图像分割任务(语义、实例和全景)。我们的方法被称为 K-Net(“K”代表内核)。它从一组随机初始化的卷积核开始,并根据现有的分割目标学习 kernels,即用于语义类别的 semantic kernels 和用于实例身份的 instance kernels(图1b))。semantic kernels 和 instance kernels 的简单组合可以自然地进行全景分割(图1c)。在前向传递中,kernels 对图像特征进行卷积以获得相应的分割预测。 K-Net 的多功能性和简单性是通过两种设计实现的。首先,我们制定了 K-Net,以便它动态更新 kernels,使它们以它们在图像上的激活为条件。这种内容感知(content-aware)机制对于确保每个 kernel(尤其是 instance kernel)准确响应图像中的不同对象至关重要。通过迭代应用这种自适应 kernel 更新策略,K-Net 显着提高了 kernels 的判别能力并提升了最终的分割性能。值得注意的是,这种策略普遍适用于所有分割任务的 kernels 。 其次,受目标检测 DETR 最新进展的启发,我们采用二分匹配策略为每个内核分配学习目标。这种训练方法有利于传统的训练策略,因为它在图像中的 kernels 和实例之间建立了一对一的映射。因此,它解决了处理图像中不同数量的实例的问题。此外,它是纯 mask 驱动的,不涉及 boxes。因此,K-Net 自然是无 NMS 和无框的,这对实时应用很有吸引力。 方法 K-Net 尽管“有意义的组”有不同的定义,但所有分割任务本质都将每个像素分配给一个预定义的有意义的组。由于通常假设图片中的组数是有限的,因此我们可以将分割任务的最大组设置为 N。例如,有 N 个预定义的语义类用于语义分割,或者图像中最多有 N 个目标用于实例分割。对于全景分割,N 是图像中 stuff 类和 objects 的总数。因此,我们可以使用 N 个内核将图像划分为 N 个组,其中每个 kernel 负责找到属于期对应组的像素。具体来说,给定由深度神经网络生成的 B 副图像的输入特征图 \(F \in R^{B \times C \times H \times W}\),我们只需要 N 个内核 \(K \in R^{N \times C}\) 与 \(F\) 进行卷积即可获得相应的分割预测 \(M \in R^{B \times N \times H \times W}\) 为 \[M = \sigma (K \ast F),\] 其中 C,H 和 W 分别是特征图的通道数、高度和宽度。如果我们只想将每个像素分配给一个 kernel(通常用于语义分割),则激活函数 \(\sigma\) 可以是 softmax 函数。如果我们允许一个像素属于多个 mask,则 Sigmoid 函数也可以用作激活函数,通过在激活图上设置一个阈值(如 0.5)(通常用于实例分割),这会产生 N 个二进制 masks。 这个公式已经主导了语义分割多年。在语义分割中,每个 kernel 负责在图像中找到相似类别的所有像素。而在实例分割中,每个像素组对应一个对象。然而,以前的方法通过额外的步骤而不是 kernel 来分离实例。 本文是第一个探讨语义分割中的 kernel 概念是否同样适用于实例分割,以及更普遍的全景分割的研究。为了通过内核分离实例,K-Net 中的每个内核最多只能分割图像中的一个对象(图 1b)。通过这种方式,K-Net 区分实例并同时进行分割,无需额外步骤即可一次性实现实例分割。为简单起见,我们在本文中将这些内核称为 semantic kernel 和 instance kernels,分别用于语义和实例分割。实例内核和语义内核的简单组合可以自然地执行全景分割,将像素分配给 an instance ID 或 a class of stuff(图1c))。 Group-Aware Kernels 尽管 K-Net 很简单,但直接通过内核分离实例并非易事。因为实例 kernels 需要区分图像内和图像间尺度和外观不同的 objects。没有像语义类别这样的共同和明确的特征,instance kernels 需要比 static kernels 更强的判别能力。 为了克服这一挑战,我们提供了一种方法,通过 kernel update head 使 kernel 以相应的像素组为条件,如图2所示。Kernel update head \(f_i\) 包含三个关键步骤:组特征组装(group feture assembling)、自适应内核更新(adaptive kernel update),和内核交互(kernel interaction)。首先,使用 mask 预测 \(M_{i-1}\) 组装每个像素组的 group feature \(F^K\)????。由于是每个组的上下文将它们彼此区分开来,因此使用 \(F^K\) 自适应地更新其对应的内核 \(K_{i-1}\)。之后,内核相互交互,对图像上下文进行全面建模。 最后,获得的 group-aware kernels \(K_i\) 对特征图 \(F\) 进行卷积以获得更准确的 mask 预测 \(M_i\)。 如图3所示,这个过程可以迭代地进行,因为更精细的分区通常会降低组特征中的噪声,从而产生更具辨别力的内核。这个过程被表述为 \[K_i, M_i = f_i(M_{i-1},K_{i-1},F)。\] 一组 learned kernels 首先与特征图 \(F\) 进行卷积以预测 mask \(M_0\)。然后这个 kernel update head 将 mask 预测 \(M_0\)、learned kernels \(K_0\) 和 特征图 \(F\) 作为输入,并生成类预测、group-aware (dynamic) kenrels 和 mask 预测。生成的 mask 预测、dynamic kernels 和特征图 \(F\) 被发送到下一个 kernel update head。迭代执行此过程以逐步细化 kernel 和 mask 预测。 值得注意的是,具有迭代细化的 kernel update head 是通用的,因为它不依赖于 kernel 的特性。因此,它不仅可以增强 instance kernels,还可以增强 semantic kernels。 实验 表4a表明 adaptive kernel update 和 kernel interaction 是高性能的必要条件。从表4b中可以看出,positional information 是有益的,positional encoding 略好于 coordinate convolution。但是两者组合没有进一步提升性能,因此在此框架中进使用了 positional enconding。表4c表明 kernel update 的轮数在第4轮的时候,性能接近饱和。最后,在 instance kernels 的数量实验中,增加 N 的数量可以提升性能,但是当 N 较大时,提升幅度变缓。 可视化分析 Kernels 的总体分布。我们通过分析 val split 中 5000 个图像中 100 个实例内核的掩码激活平均值,仔细分析了在 K-Net 中学习到的实例内核的属性。所有 masks 都调整大小以具有类似的 \(200 \times 200\) 分辨率以进行分析。如图 4a 所示,学习到的 kernels 是有意义的。不同的 kernels 专注于图像的不同区域和不同大小的对象,而每个 kernel 关注图像中靠近位置的相似大小的对象。 通过 Kernel Update 优化的 Masks。我们进一步分析了如何通过图 4b 中的 kernel update 来改进 kernel 的 mask 预测。在这里,我们采用 K-Net 进行全景分割,以彻底分析语义和实例掩码。static kernels 生成的 masks 是不完整的,例如,河流和建筑物的掩码缺失。内核更新后,分割掩码完全覆盖了内容,尽管掩码的边界仍然不理想。更多内核更新后,边界得到了细化。内核更新后实例的分类置信度也会增加。 总结 本文探讨了可以在分割过程中学习分离实例的实例内核。因此,以前辅助实例分割的额外组件可以被实例内核替换,包括边界框、嵌入生成和手工制作的后处理,如 NMS、内核融合和像素分组。这种尝试首次允许通过统一的框架处理不同的图像分割任务。该框架被称为 K-Net,首先通过学习的静态内核将图像划分为不同的组,然后通过从划分组中组装的特征迭代地细化这些内核及其对图像的划分。K-Net 在全景和语义分割基准上获得了新的SOTA的单模型性能,并在最近的实例分割框架中以最快的推理速度超越了成熟的 Cascade Mask R-CNN。我们希望 K-Net 和分析能够为未来统一图像分割框架的研究铺平道路。]]></content>
<tags>
<tag>Instance Segmentation</tag>
</tags>
</entry>
<entry>
<title><![CDATA[SOTR:Segmenting Objects with Transformers [ICCV 2021]]]></title>
<url>%2F2022%2F05%2F19%2FSOTR%2F</url>
<content type="text"><![CDATA[Paper: [ICCV 2021] SOTR: Segmenting Objects with Transformers Arxiv: https://arxiv.org/abs/2108.06747 Github: https://github.com/easton-cau/SOTR 介绍 最近 tansformer-based 模型在视觉任务上表现出令人印象深刻的性能,甚至超过了卷积神经网络。在这项工作中,作者提出了一种新颖、灵活且有效的 tranformer-based 模型用于高质量的实例分割。所提出的模型,即 Segmenting Objects with TRansformers (SOTR),简化了分割的pipeline,具有2个并行的子任务:(1)通过 transformer 预测每个实例类别,(2)使用多层级上采样模块动态生成 segmentation mask。SOTR 可以分别通过特征金字塔(FPN)和 twin transformer 有效地提取较低级别的特征表示(lower-level feature representations)并不惑远程上下文依赖关系(long-range context dependencies)。同时,与原始的 tranformer 相比,多提出的 twin transformer 在时间和资源上都是有效的,因为只涉及行和列注意力(a row and a column attention )来编码像素。此外,SOTR 很容易与各种 CNN backbones 和 transformer 模型变体结合,从而显著提高分割精度和收敛性。 现代实例分割方法通常建立在 CNN 之上并遵循先检测后分割范式,该范式由一个用于识别和定位所有目标的检测器和一个用于生成分割掩码的掩码分支组成。这这种分割方法的成功归功于以下优点,即平移和位置不变性(tanslation equivariance and location),但面临以下障碍:1)由于感受野受限,CNN 在高级视觉语义信息中相对缺少特征的连贯性(features' coherence)来关联实例,导致对大目标的次优结果;2)分割质量和推理速度都严重依赖目标检测器,在复杂场景中性能较差。 为了克服这些缺点,提出了一些 Bottom-up 的策略。Bottom-up 的方法的主要缺点是在不同场景的数据集上不稳定的聚类(例如,)和较差的泛化能力。SOTR有效学习了位置敏感特征和动态生成实例分割结果,不需要后处理聚合,不受限于边界框位置和尺寸。我们提出了一种创新的自下而上模型 SOTR,它巧妙地结合了 CNN 和 Transformer 的优势。 方法 Transformer Twin attention. self-attention 是 transformer 模型的关键组件,它内在地在输入序列上的每个元素之间捕获了全图的上下文信息并且学习到了长距离的交互。然而,self-attention 具有二次时间和内存复杂性,在高维维度序列(如图像)上产生更高的计算成本,并阻碍了不同设置下的模型可扩展性。 为了解决这个问题,本文提出了 twin attention 机制使用稀疏表示简化了注意力矩阵。这个策略主要将感受野限制为固定步幅的设计块模式。它首先计算每列内的注意力,同时保持不同列中的元素独立。该策略可以在水平尺度上聚合元素之间的上下文信息(如图3(1)所示)。然后,在每一行内执行类似的注意力,以充分利用垂直尺度的特征交互(如图3(2)所示)。两个尺度中的注意力一次连接到最后一个,它具有全局感受野,覆盖了两个维度上的信息。 FPN的第i层特征定义为 \(F_i \in \mathbb{R}^{H \times W \times C}\),SOTR 首先将这个特征图切分成 \({N \ast N}\) 个 patches \({P_i \in \mathbb{R}^{N \times N \times C}}\) ,然后将它们沿垂直和水平方向堆叠成固定的 blocks。Position embeddings 被添加到这些 blocks 中以保留位置信息,这意味着列和行的 position embedding 空间是 \(1 \ast N \ast C\) 和 \(N \ast 1 \ast C\)。两个注意力层都采用了 multi-head attention 机制。为了便于多层连接和后处理,在 twin attention 中所有子层都会产生 \(N \times N \times C\) 的输出。Twin attention 机制可以有效地将内存和计算复杂度从标准的 \(O((H \times W)^2)\) 降低到 \(O(H \times W^2 + W \times H^2)\)。 Transformer Layer. 在本节中,我们介绍3个不同的基于编码器的 transformer 层作为我们的基本构建块,如图3所示。原始的 transformer 层类似于 NLP 中使用的编码器,如图3a所示,它包括2个部分:1)经过 a layer normalization 后的 a multi-head self-attention 机制,以及 2)在 a layer normalization 之后的 a multi-layer perception。除此之外,使用残差连接来连接这两个部分。最后,可以得到一个多维序列特征作为这些 transformer 层的 K 个串联的输出,用于不同功能 heads 的后续预测。 为了在计算成本和特征提取效果之间做出最佳权衡,我们遵循原来的 Transformer 层设计,仅在纯 Twin Transformer 层中用 twin attention 代替 multi-head attention ,如图3b所示。为了进一步提升 twin tranformer 的性能,我们还设计了图 3c 所示的 hybrid twin transformer。它将两个 \(3 \times 3\) 卷积层通过 Leaky ReLU 层连接到每个 twin attention 模块。 假设添加的卷积操作可以作为注意力机制的有效的补充,更好地捕获局部信息并增强特征表示。 Functional heads. 来自 transformer 模块的特征图被输入到不同的功能 heads 以进行后续预测。class head 包括 a single linear layer 来输出一个 \(N \times N \times M\) 的分类结果,其中 \(M\) 是类别的数量。由于每个 patch 只为中心落入这个 patch 的单个目标分配一个类别,如 YOLO,我们利用多级预测并在不同特征级别共享这些 heads,以进一步提高模型在不同尺度对象上的性能和效率。 Kernel head 也由 a linear layer 组成,与 class head 并行输出一个 \({N \times N \times D}\) 的张量用于后续的 mask 生成,其中张量表示具有D个参数的 \(N \times N\) 个卷积核。在训练期间,Focal Loss 应用于分类,而对这些卷积核的所有监督都来自最终的 mask 损失。 Mask 为 instance-aware 和 position-sensitive 分割构建 mask 特征表示,一种直接的方式是对不同尺度的特征图进行预测。但是,这会增加时间和资源。收 Panoptic FPN 的启发,我们呢设计了 multi-level upsampling 模块,将每个 FPN 层级和 transformer 的特征合并为统一的 mask 特征。首先,从 transformer 模块中获取具有位置信息的相对低分辨率特征图 P5,并与 FPN 中的 P2-P4 结合执行融合。对于每个尺度的特征图,执行 \(3 \times 3\) Conv,Group Norm 和 ReLU 操作。然后 P3-P5 被双线性上采样 2x、4x、8x,分别为(H4,W4)分辨率。最后,将处理后的 P2-P5 相加后,执行逐点卷积和上采样以创建最终统一的 \(H \times W\) 特征图。 对于实例掩膜预测,SOTR 通过对上述统一特征图执行动态卷积操作,为每个 patch 生成 mask。给定来自 kernel head 的预测卷积核 \(k \in RN \times N \times D\),每个 kernel 负责对应的 patch 中实例 mask 的生成。具体操作可以表示如下: \[Z^{H \times W \times N^2} = F^{H \times W \times C} \ast K^{N \times N \times D}\] 其中 \(\ast\) 表示卷积操作,\(Z\) 是最终生成的 mask,维度为 \(H \times W \times N^2\)。其中,\(D\) 的取值取决于卷积核的形状,也就是说,D等于 \(\lambda 2 C\),其中 \(\lambda\) 的 kernel 大小。最终的实例分割 mask 可以由 Matrix NMS[37] 生成,每个 mask 由 Dice Loss 独立监督。 实验 用于特征编码的 Transformer。我们用三种不同的 transformers 来衡量我们模型的性能。这些变体的结果如表 2 所示。我们提出的 pure and hybrid twin transformers 在所有指标上都大大超过了 original transformer,这意味着 twin transformer 架构不仅成功地捕获了垂直和水平维度上的远程依赖关系,而且是更适合与 CNN 主干结合来学习图像的特征和表示。对于 pure and twin transformers,后者效果更好。我们假设原因是 \(3 \ast 3\) Conv 可以提取局部信息并改进特征表达以增强 twin transformer 的合理性。 我们展示了掩码特征的可视化。对于每一行,左边是原始图片,右边是与其对应的 positional-sensitive mask。 我们将我们方法的分割结果与 Mask R-CNN 、Blendmask 和 SOLOv2 进行比较。代码和训练好的模型由原作者提供。 所有模型都使用 ResNet-101-FPN 作为主干,并且基于 Pytorch 和 Detectron2。 我们的 Mask 质量更好。 动态卷积。对于 mask 生成,我们有两种选择:以静态卷积方式直接输出实例 mask 或通过动态卷积操作连续分割对象。前者不需要额外的 functional head 来预测卷积核,而后者包括卷积核以在融合特征的帮助下生成最终 mask。 我们在表 5 中比较了这两种模式。如图所示,没有 twin transformer 的 SOTR 实现了 39.7% 的 AP,表明 twin transformer 带来了 0.5% 的增益。 此外,动态卷积策略可以将性能提高近 1.5% AP。 原因是:一方面,由于非线性,动态卷积显着提高了表示能力。另一方面,动态卷积比静态卷积有助于更好更快地收敛。]]></content>
<tags>
<tag>Transformer</tag>
<tag>Instance Segmentation</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Efficient DETR]]></title>
<url>%2F2021%2F12%2F27%2FEfficient-DETR%2F</url>
<content type="text"><![CDATA[Paper:https://arxiv.org/abs/2104.01318 Code:暂未开源 摘要 最近提出的端到端 transformer 检测器 (例如 DETR 和 Deformable DETR)有一个堆叠的 6 个解码器层的级联结构,以用来迭代更新 object queries,否则它们的性能会严重下降。在这篇论文中,作者研究了 object containers 的随机初始化,object containers 包含 object queries 和 reference points,用于负责多次迭代的要求。基于这个发现,作者提出 Efficient DETR,一种用于端到端目标检测的简单高效的流程。通过同时利用密集检测(dense detection)和稀疏集合检测(sparse set detection),Efficient DETR 在初始化 object containers 利用密集先验,并且弥补了 1 层 decoder 结构和 6 层 decoder 结构的性能差异。在 MS COCO 上进行的实验表明,该的方法只有 3 encoder layers 和 1 decoder layer,与 state-of-the-art 目标检测方法相比,性能具有竞争力。 Efficient DETR 在拥挤的场景中也很强大,它在 CrowdHuman 数据集上大大优于当前的目标检测器。 介绍 最近,DETR 提出一种基于 encoder-decoder transformer 架构和二部图匹配构建的端到端框架,改框架可以直接预测一组边界框,而无需后处理(NMS)。然而,DETR 需要比当前主流检测器 10 到 20 倍训练的 epoch 才能收敛,并且在检测小目标方面表现出相对较低的性能。 DETR 的检测流程可以抽象成 Fig.1(a)。我们首先定义 object container 作为一种结构信息的容器,它可以包含不同种的目标特征。object queries 和 reference points 都属于 object container,因为 object queries 和 reference points 可以表示抽象的特征和目标的位置信息。一组随机初始化的 object containers 被送入特征精练器(feature refiner)中,用于和从图像提取的特征做交互作用。具体来说,具有 cross-attention 模块的 6 decoder layers 扮演了 cascade feature refiner的角色,它迭代的更新 object containers。这个精练之后的 object containers 有助于 DETR最后的预测。此外,图片的特征是通过 feature extractor 提取到的,在 DETR 中的 feature extractor 包括 a CNN backbone 和 6 encoder layer。总之,图像和随机初始化的 object containers 通过 feature extractor 和 cascade feature refiner 得到最终的结果。在这个流程中,DETR 和 Deformable DETR 都具有 6-encoder 和 6-decoder transformer 架构。我们假设这种结构是 DETR 系列 实现目标检测高精度的关键。 在这篇论文中,作者研究了 DETR 的各个组成部分,并且了解其机制。作者通过大量实验发现具有额外辅助损失的 decoder layer 对性能的贡献最大。transformer decoders 迭代地用特征图与 object containers 进行交互。作者探索了 DETR 中 object containers 随机初始化和多次修正的要求导致了收敛缓慢。 然而,很难直接分析 object queries,因为它们只是一组抽象特征。Deformable DETR 为 object queries 提出了 reference points。Reference points 是一个2维张量,表示猜想的框的中心点。通过可视化训练模型的参考点,作者发现它们被证明仅用作基于锚点的方法中的 anchor points。 此外,作者报告了 1-decoder 结构的 reference points 的不同初始化导致巨大性能差异。 问题来了:对于端到端检测器中的 object containers,哪种初始化更好? 探索 DETR 回归 DETR Encoder and decoder. DETR 系列方法是在一个 encoder-decoder transformer 架构上。encoder 和 decoder 都级联了 6 个相同的层。An encoder layer 由 a mullti-head self-attention 和 a feed-forward network (FFN) 组成,而 a decoder layer 有一个额外的 multi-head cross attention layer。encoder layer 起到了与卷积类似的作用,并且从具有 multi-head self-attention 的 CNN backbone 上提取上线文特征。在 decoders 中,一组 256 维的 object queries 与整个图像的 encoder features 进行交互,并通过 multi-head cross attention 聚合信息。辅助二分匹配损失应用于每一个 decoder layer。表 1 说明 DETR 对 decoder layer 的数量更加的敏感,这意味着 decoder 比 encoder 对于 DETR 来说更加的重要。特别是,采用具有 3-encoders 和 3-decoders 的 DETR 作为我们的 baseline。如果在 decoder 中移除 2 层 layer,AP 可以减少约 9.3。相比之下,删除 encoder 中的 2 层 layer,仅导致 1.7 AP 的下降。 为什么 decoder 比 encoder 更加的重要? 它们都是在一个级联的框架下,但是 decoder 的每个相同的层上都有 一个额外的辅助损失。在表 1 中,我们发现这个辅助的解码损失是 DETR 对 decoder layer 数量敏感的主要原因。在没有辅助损失的情况下,encoder 和 decoder 的行为趋于相同。我们指出辅助解码损失在更新 query feature 时引入了强监督,这使得 decoder 更高效。decoder 级联结构通过逐层的辅助损失来精练特征。迭代次数越多,辅助解码监督越有效。 为了进一步套索 decoder 的级联结构,作者尝试了不同数量的 decoder layer。表 2 显示,随着级联次数的减少,性能显著降低。6-layer decoder 和 1-layer decoder 存在 10.3 AP 的巨大下降。值得注意的是,在 decoder 中每次迭代后,仅仅 object queries 得到了更新。Object queries 与性能密切相关,因为最终的预测是来自 object queries 并由检测头预测。然而,object queries 在训练开始时是随机初始化的。我们假设这种随机初始化不能提供良好的初始状态,这可能是 DETR 需要 6 次迭代的级联结构来实现竞争性能的原因。 Object Containers 初始化的影响 基于前面的分析,object queries 的初始是值得研究的。object query 属于object container 中的特征信息。object query 被定义为可学习的位置嵌入,它是一个 256 维的抽象张量,因此很难分析。然而,我们观察到 DETR 中的每个 object query 都学会了专注于具有多种操作模式的特定区域和框的大小。我们假设研究 object query 的空间投影可能有助于直观的理解。 Deformable DETR 引入了一个新的组件,即与 object queries 相关的 reference point。Reference points 是表示框中心预测的 2 维张量,属于 object container 的位置信息。此外,参考点是通过线性投影从 256 维 object queries 中预测的。它们可以作为 object query 在 2D 空间中的投影,并提供 object query 中位置信息的直观表示。Reference point 和 object query 在 decoder 迭代期间更新,并作用到最终结果。 考虑到 reference points 直观地表示 object queries 中的位置信息,开始对其进行研究。在传递到 decoder layers 之前,reference points 试试通过随机初始化的 object queries 的线性投影生成的,如图 3(a)所示。我们称这个过程为参考点的初始化。图 2 展示了模型收敛之后的参考点。初始阶段的参考点均匀分布在图像上,覆盖整个图像区域。这种初始化类似于 anchor-based detectors 的 anchor points 的生成。随着迭代阶段的增加,reference points 逐渐聚集到前景的中心,最终在最后阶段几乎覆盖了所有的前景。直观的说,reference points 充当定位前景的 anchor points,并使得注意力模块专注于前景周围的一小组关键采样点。 在研究了 reference points 的更新之后,我们开始探索它们的初始化,这就是参考点的生成方式。对于剩下的部分,我们将 reference points 和 object queries 的初始化称为 object containers 的初始化。 Reference Point 不同的初始化。 在 anchor-based detectors 中,anchors 的生成对模型的性能有一个较大的影响。anchors 在每一个滑动窗口的位置生成,并且为目标可能出现的位置提供了一个合适的初始化。在 reference points 的初始化中,它的作用类似于 anchor points,可能对 Deformable DETR 的性能有影响。作者针对级联(6-decoder)和非级联(1-decoder)结构尝试了不同的初始化,并且比较它们的性能。如表 3 所示,不同的初始化在非级联结构上表现确实不同。相反,在级联结构上它们有一个相似的性能。与推测一致,网格(grid)初始化是在滑动窗口的中心生成 reference points,它的结果类似于可学习的初始化。然而,另外两种初始化,中心(center)和边界(border),在没有迭代的情况下,导致了准确率的巨大下降。为了更好的分析,我们再几个阶段可视化了不同初始化的 reference points,如图 4 所示。随着迭代的增加,它们的 reference points 往往处于相同的分布,并且在最终的阶段以相似的模式定位前景。总之,reference points 的不同初始化导致模型在非级联结构中性能的巨大差异,而级联结构通过多次迭代带来了它们的差距。 从另一个角度来看,更好的 reference points 初始化可能会提高非级联结构的性能。 我们能否通过更好的初始化来弥补 1-decoder 结构和 6-decoder 结构的差距? 基于以上的发现,reference points 更好的初始化可以提升性能,尤其对 1-decoder 结构。考虑到 reference points 类似于 anchor points,我们假设在主流检测器中 anchor 的先验可以帮助解决这个问题。在当前的 two-stage 检测器中,region proposals 通过 RPN 以一个滑窗的操作生成的,它可以针对前景提供一组类比无关的候选区域。 RPN 使用 dense 的先验生成前景的粗糙的边界框。如图 3(b) 所示,我们将 RPN 层添加到从 encoder 出来的 dense feature 上。RPN head 共享 encoder 的特征,并且为每一个 anchor 预测 objectness score 和 偏移。得分较高的边界框被选择作为 region proposals。然后,我们再非级联的结构中使用这些 region proposals 的中心作为 reference points 的初始化。表 3 表明了这种方式带来的较大的性能提升。图 5 可视化了这个方法,这里 reference points 作为初始化阶段得到了与其他方法最后阶段相似的分布。Region proposals 以一种更合理的分布初始化了 reference points,提升了非级联结构的 Deformable DETR 的准确性。 如表 4 所示,使用 dense 先验作为 reference point 的初始化,使得它达到了一个更好的初始化状态,并且在 1-decoder 结构中带来了显著的性能提升。然而,reference point 仅仅是 object query 的空间映射,object query 包含额外的抽象信息。因此,怎么同时使用 dense 先验初始化 256-d 的 object feature呢? 直观上,对于 proposal 初始化中的每个 reference point,我们从特征图中选择其对应的特征,即来自 encoder 的 256-d 张量,作为其 object query 的初始化。我们的方法如图 3(c) 所示。 在表 4 中,我们的方法将 1-decoder 结构进一步改进了 3 AP。此外,仅使用 dense 先验初始化 object query 并使用没有reference point 的原始 decoder 也可以显着改善 baseline。 这些结果表明 object container 的初始状态,包括 Deformable DETR 中的 reference point 和 object query,与非级联结构的性能高度相关。RPN 中的 proposals 信息提供了更好的初始化,有可能通过 dense 先验提高性能。基于我们的研究,我们提出了 Efficient DETR,它能够缩小 1-decoder 结构和 6-decoder 结构之间的性能差距。 Efficient DETR Efficient DETR 包含 3 encoder layers 和仅仅 1 decoder layer,并且在 decoder 中没有级联结构。这个框架如图 5 所示。Efficient DETR 包含两个部分:dense 和 sparse。Dense 部分在来自 encoder 的 dense 特征上做预测。它从 dense 的预测结果中选择 top-k proposals。这个 4-d proposals 和它对应的 256-d feature 作为 reference points 和 object queries 的初始化。在 sparse 部分,object containers(包含 reference points 和 object queries )使用 dense 先验作为初始化,并且送入到 1-layer decoder,使其与 encoder feature 做信息交互更新特征。最终的预测结果来自于这个更新之后的 object containers。 实验部分]]></content>
<categories>
<category>Object Detection</category>
</categories>
<tags>
<tag>Object Detection</tag>
<tag>Transformer</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Deformable DETR]]></title>
<url>%2F2021%2F11%2F24%2FDeformable-DETR%2F</url>
<content type="text"><![CDATA[Paper:https://arxiv.org/abs/2010.04159 Code:https://github.com/fundamentalvision/Deformable-DETR 介绍 最近提出的 DETR 消除了目标检测中很多手工设计的组件,然而降低了精度。除此之外,由于受到 Tranformer attention 模块在处理图片特征的限制,导致它收敛很慢,并且限制了特征空间分辨率。 为了解决上述问题,论文提出了 Deformable DETR,它的 attention 模块仅仅关注 参考点 附近的一组关键采样点。Deformable DETR 可以获得比 DETR 更好的性能(尤其是在小物体上),并且训练次数减少了 10 倍。 DETR存在的两个问题:(1)比起现存的目标检测器,它的收敛要求太长时间的训练周期。例如,在COCO数据集上,DETR 需要 500 epochs 才能收敛,而这大约比 Faster RCNN 慢了 10~20 倍。(2)DETR 在检测小目标上存在较低的性能。当前的检测器通常利用多尺度特征,这这些特征上小目标可以从高分辨率特征上被检测。然而,高分辨率的特征图给 DETR 带来的严重的计算代价。 上述问题主要归因于 Transformer 组件在处理图像特征图方面的不足。在初始化的时候,attention modules 将几乎统一的注意力权重投射到特征图中的所有像素。让学习注意力权重专注于稀疏有意义的位置,长时间的训练周期是必要的。 另一方面,Transformer 编码器中的注意力权重计算是像素数的平方计算量。 因此,处理高分辨率特征图具有非常高的计算和内存复杂性。 在图片领域,deformable 卷积是一种强有力且高效的关注稀疏空间位置的机制。它可以天然的避免上述提到的问题。然而它缺乏元素关系建模机制,这是DETR成功的关键。 在这篇论文中,作者提出 Deformable DETR,它缓解了 DETR 收敛慢和高计算复杂性的问题。它组合了 deformable 卷积的稀疏空间采样特性和 Transformer 的相关性的建模能力。论文提出的 deformable attention 模块将一小组采样位置作为所有特征图像素中重要的关键元素的预过滤器。 由于其快速收敛以及计算和内存效率,Deformable DETR 为我们开辟了利用端到端对象检测器变体的可能性。 作者探索了一种简单有效的迭代边界框细化(iterative bounding box refinement)机制来提高检测性能。 论文还尝试了一个 two-stage Deformable DETR,其中 region proposal 也是由 Deformable DETR 的变体生成的,它们被进一步输入 decoder 以进行 iterative bounding box refinement。 回顾 Transformer 和 DETR Multi-Head Attention in Transformers Transformers 是针对机器翻译任务设计的一种基于注意力机制的网络结构。给一个 query 元素(例如,在一个输出句子中的一个目标单词)和一组 key 元素(例如,在输入句子中的原单词),multi-head attention 模块根据注意力权重自适应地汇聚关键信息,这个注意力权重可以测量 query-key 对 质检的一致性。为了允许让模型从不同表示子空间和不同位置中关注信息,不同 attention heads 的输出是使用学到的权重线性聚合的结果。Multi-head attention 特征可以计算为: \[ \operatorname{MultiHeadAttn}\left(\boldsymbol{z}_{q}, \boldsymbol{x}\right)=\sum_{m=1}^{M} \boldsymbol{W}_{m}\left[\sum_{k \in \Omega_{k}} A_{m q k} \cdot \boldsymbol{W}_{m}^{\prime} \boldsymbol{x}_{k}\right] \] \(q \in \Omega_{q}\) 表示 一个 query 元素的索引,其特征表示为 \(z_q \in \mathbb{R}^{C}\) \(k \in \Omega_{k}\) 表示一个 key 元素的索引,其特征表示为 \(x_k \in \mathbb{R}^C\) \(C\) 特征的维度 \(M\) attention head 的数量,\(m\) 是 attention head 的索引 \(\mathbf{W}_{m}^{\prime} \in \mathbb{R}^{C_{v}\times C}\) 和 \(\mathbf{W}_{m} \in \mathbb{R}^{C_{v}\times C}\) 是可学习的权重,并且 \(C_{v} = C/M\) \(A_{m q k} \propto \exp \left\{\frac{\mathbf{z}_{q}^{T} \mathbf{U}_{m}^{T} \mathbf{V}_{m} \mathbf{x}_{k}}{\sqrt{C_{v}}}\right\}\) 是 attention 权重,它被归一化,并且 \(\sum_{k\in \Omega_{k}} A_{mqk}=1\) 其中 \(\mathbf{U}_{m}\) 和 \(\mathbf{V}_{m}\) 也是可学习的权重。 为了消除不同空间位置的歧义,表示特征 \(x_q\) 和 \(x_k\) 通常是和 positional embedding 的串联/求和。 DETR 对于 DETR 中的 Transformer encoder,query 和 key 元素都是特征图中的像素。输入是 ResNet 特征图(带有编码的 positional embeddings)。让 \(H\) 和 \(W\) 分别表示特征图的高度和宽度。 self-attention 的计算复杂度为 \(O(H^2 W^2 C)\) ,随空间大小呈二次方增长。 对于 DETR 中的 Transformer dncoder,输入包括来自 encoder 的特征图和 由可学习位置嵌入(例如,N = 100)表示的 N object queries。decoder 中有两种注意力模块,即 cross-attention 和 self-attention 模块。在 cross-attention 模块中,object query 从特征图中提取特征。query 元素属于object queries,key 元素属于encoder 的输出特征图。其中,\(N_q = N\),\(N_k = H \times W\),交叉注意力的复杂度为 \(O(HWC^2 + NHWC)\)。复杂性随着特征图的空间大小线性增长。在 self-attention 模块中,object queries 相互交互,以捕获它们的关系。 query 和 key 元素都是 object queries。 其中,\(N_q = N_k = N\),self-attention 模块的复杂度为 \(O(2NC^2 +N^2 C)\)。 中等数量的对象查询的复杂性是可以接受的。 这主要是因为处理图像特征的注意力模块很难训练。 例如,在初始化时,cross-attention 模块几乎对整个特征图具有平均注意力。而在训练结束时,attention maps 被学习到非常稀疏,只关注对象的外轮廓(extremities)。 似乎 DETR 需要很长的训练才能学习注意力图的如此显着的变化。 Method Ddformable Transformer for End-To-End Object Detection Deformable Attention Module \[ \operatorname{DeformAttn}\left(\boldsymbol{z}_{q}, \boldsymbol{p}_{q}, \boldsymbol{x}\right)=\sum_{m=1}^{M} \boldsymbol{W}_{m}\left[\sum_{k=1}^{K} A_{m q k} \cdot \boldsymbol{W}_{m}^{\prime} \boldsymbol{x}\left(\boldsymbol{p}_{q}+\Delta \boldsymbol{p}_{m q k}\right)\right] \] 这里 \(m\) attention head 的索引,\(k\) 采样 keys 的索引,\(K\) 是总采样的 key 的数量 \((K \ll HW)\)。\(\Delta p_{mqk}\) 和 \(A_{mqk}\) 是采样的偏置和在 \(m^{th}\) attention head 上的 \(k^{th}\) 采样点的 attention weight。 Multi-scale Deformable Attention Module \[ \operatorname{MSDeformAttn}\left(\boldsymbol{z}_{q}, \hat{\boldsymbol{p}}_{q},\left\{\boldsymbol{x}^{l}\right\}_{l=1}^{L}\right)=\sum_{m=1}^{M} \boldsymbol{W}_{m}\left[\sum_{l=1}^{L} \sum_{k=1}^{K} A_{m l q k} \cdot \boldsymbol{W}_{m}^{\prime} \boldsymbol{x}^{l}\left(\phi_{l}\left(\hat{\boldsymbol{p}}_{q}\right)+\Delta \boldsymbol{p}_{m l q k}\right)\right] \] Deformable Transformer Encoder 由于提出的 multi-scale deformable attention 可以再不同多尺度特征层上交换信息,所以没有使用 FPN 结构。 在 encoder 中 multi-scale deformable attention 模块的应用中,输出是与输入具有相同分辨率的多尺度特征图。key 和 query 元素都是来自多尺度特征图的像素。对于每一个 query 像素,这个参考点(reference point)就是它自己。为了识别每个 query 像素位于哪个特征级别,除了 positional embedding 之外,我们还向特征表示中添加了 a scale-level embedding,表示为 \(e_l\)。与固定编码的 positional embedding 不同,scale-level embedding \(\{e_l\}^L_l=1\) 是随机初始化并与网络联合训练。 Deformable Transformer Decoder decoder 中有 cross-attention 和 self-attention 模块。这两种注意力模块的 query 元素都是 object queries。在 cross-attention 模块中,object queries 从特征图中提取特征,其中 key 元素是来自 encoder 的输出特征图。在 self-attention 模块中,object queries 相互交互,其中 key 元素是 object queries。由于我们提出的 deformable attantion 模块是为处理卷积特征图作为 key 元素而设计的,因此我们仅将每个 cross-attention 模块替换为 multi-scale deformable attention 模块,而保持 self-attention 模块不变。对于每个 object query,参考点 \(\hat p_q\) 的二维归一化坐标是从其 object query embedding 中通过可学习的线性投影和 \(\mathrm{sigmoid}\) 函数预测的。 因为 multi-scale deformable attention 模块提取参考点(reference point)周围的图像特征,我们让检测头将边界框预测为相对偏移,也就是参考点进一步降低优化难度。 参考点用作框中心的初始猜测。检测头预测相对偏移,也就是参考点。这样,学习到的 decoder attention 将与预测的边界框有很强的相关性,这也加速了训练收敛。 通过在 DETR 中用 deformable attention 模块替换 Transformer attention 模块,我们建立了一个高效且快速收敛的检测系统,称为 Deformable DETR。 其他改进 和 变体 Iterative Bounding Box Refinemen Two-Stage Deformable DETR 实验结果 由上图可以看出,Deformable DETR 明显提升了训练速度。 论文中的符号说明]]></content>
<categories>
<category>Object Detection</category>
</categories>
<tags>
<tag>Object Detection</tag>
<tag>Transformer</tag>
</tags>
</entry>
<entry>
<title><![CDATA[复式记账 Beancount 使用]]></title>
<url>%2F2019%2F07%2F13%2FBeancount-01%2F</url>
<content type="text"><![CDATA[Beancount Beancount 安装 1234# 首先安装 beancountpip install beancount# 然后安装 favapip install fava Fava 是复式簿记软件 Beancount 的 Web 界面,侧重于功能和可用性,使用非常友好。 我们可以先使用 bean-exampl 生成一个 Beancount 文件,文件的后缀名可以自己定义,一般用.bean或.beancount: 12345678910111213141516171819202122232425(base) XX@XX:~$ mkdir MyBean(base) XX@XX:~$ cd MyBean/(base) XX@XX:~/MyBean$ ls(base) XX@XX:~/MyBean$ bean-example > example.beanINFO : Generating Salary Employment IncomeINFO : Generating Expenses from Banking AccountsINFO : Generating Regular Expenses via Credit CardINFO : Generating Credit Card Expenses for TripsINFO : Generating Credit Card Payment EntriesINFO : Generating Tax Filings and PaymentsINFO : Generating Opening of Banking AccountsINFO : Generating Transfers to Investment AccountINFO : Generating PricesINFO : Generating Employer Match ContributionINFO : Generating Retirement InvestmentsINFO : Generating Taxes InvestmentsINFO : Generating Expense AccountsINFO : Generating Equity AccountsINFO : Generating Balance ChecksINFO : Outputting and Formatting EntriesINFO : Contextualizing to Realistic NamesINFO : Writing contentsINFO : Validating Results(base) XX@XX:~/MyBean$ lsexample.bean 运行 Beancount: 12(base) XX@XX:~/MyBean$ fava example.beanRunning Fava on http://localhost:5000 在浏览器上打开 http://localhost:5000 ,就可以看到运行界面,如下: example.bean 文件分析 复式记账的最基本的特点就是以账户为核心,Beancount的系统整体上就是围绕账户来实现的。之前提到的会计恒等式中有资产、负债和权益三大部分,现在我们再增加两个类别,分别是收入和支出。Beancount系统中预定义了五个分类: Assets 资产 Liabilities 负债 Equity 权益(净资产) Expenses 支出 Income 收入 表头信息 12345678;; -*- mode: org; mode: beancount; -*-;; Birth: 1980-05-12;; Dates: 2017-01-01 - 2019-07-12;; THIS FILE HAS BEEN AUTO-GENERATED.* Optionsoption "title" "Example Beancount file"option "operating_currency" "USD" Beancount 文件中注释使用;作为标记。 这里定义了项目的名词:Example Beancount file,和使用的货币种类:美元 USD。我们如果想使用人民币,可以同时添加 CNY,例如: 1option "operating_currency" "CNY" Assets 资产 顾名思义,Asserts 就相当于我们的存放 资产的账户,如果启用一个账户就使用 open 命令。 第一列是账户启用时间,第二列是命令,第三列是资产(Assets)名,最后一列是使用的货币种类。 123456789101112* Assets1990-09-04 open Assets:Cash:CNY CNY ; 人民币现金账户1990-09-04 open Assets:Cash:USD USD ; 美元现金账户1990-09-04 open Assets:Bank:China:CCB:CardXXX1 CNY ; 银行账户1990-09-04 open Assets:Bank:China:CCB:CardXXX8 CNY ; 银行账户1990-09-04 open Assets:Account:China:Alipay CNY ; 支付宝账户1990-09-04 open Assets:Account:China:WeChat CNY ; 微信账户1990-09-04 open Assets:Stock:China:GTJA2818 CNY ; 股票账户 我的命名规则是:资产:账户类型:国别:(银行缩写:银行卡号)/(账户名) Income 收入 这里定义我们的 收入来源,同样如果启用一个收入来源就使用 open 命令。 第一列是启用时间,第二列是命令,第三列是收入来源,最后一列是使用的货币种类。 123456* Income1990-09-04 open Income:China:XXXCompany:Salary CNY1990-09-04 open Income:China:PartTimeJob:Salary CNY1990-09-04 open Income:China:Home:RedPacket CNY1990-09-04 open Income:China:Fund:Tianhong CNY Expenses 支出 这里我们定义 花费支出,我根据自己的花销,把花费支出定义为 5 大组类,分别是:Food,Transport,Life,Fun,Health,Home,其中每个大类又有若干子类。 12345678910111213141516171819202122232425262728293031323334353637* Expenses1990-09-04 open Expenses:Food:Groceries ; 杂货店1990-09-04 open Expenses:Food:Restaurant ; 餐馆1990-09-04 open Expenses:Food:Canteen ; 食堂1990-09-04 open Expenses:Food:Cooking ; 烹饪1990-09-04 open Expenses:Food:Drinks1990-09-04 open Expenses:Food:Fruits1990-09-04 open Expenses:Transport:TransCard1990-09-04 open Expenses:Transport:Airline1990-09-04 open Expenses:Transport:Train1990-09-04 open Expenses:Transport:Taxi1990-09-04 open Expenses:Life:Clothing1990-09-04 open Expenses:Life:RedPacket1990-09-04 open Expenses:Life:Sports1990-09-04 open Expenses:Life:Shopping1990-09-04 open Expenses:Life:Commodity ; 商品1990-09-04 open Expenses:Life:SoftwareAndGame1990-09-04 open Expenses:Life:Vacation1990-09-04 open Expenses:Life:Others1990-09-04 open Expenses:Fun:Amusement1990-09-04 open Expenses:Health:Hospital1990-09-04 open Expenses:Health:Drug1990-09-04 open Expenses:Study:Book1990-09-04 open Expenses:Study:Tuition1990-09-04 open Expenses:Study:Others1990-09-04 open Expenses:Home:Rent1990-09-04 open Expenses:Home:Water1990-09-04 open Expenses:Home:Electricity1990-09-04 open Expenses:Home:Internet1990-09-04 open Expenses:Home:Phone 最后我们记录的花销就会以下图呈现出来: Liabilities 负债 负债这里我开启了一张信用卡。 123* Liabilities1990-09-04 open Liabilities:China:CreditCard:CCB:CardXXX8 CNY Equity 权益(净资产) 目前我只设置了一个 Equity 账户 Equity:Opening-Balances,用来平衡初始资产、负债账户时的会计恒等式。 12* Equity1990-09-04 open Equity:Opening-Balances 什么是复式记账法? 复式记账法是以资产与权益平衡关系作为记账基础,对于每一笔经济业务,都要以相等的金额在两个或两个以上相互联系的账户中进行登记,系统地反映资金运动变化结果的一种记账方法。 复式记账是对每一项经济业务通过两个或两个以上有关账户相互联系起来进行登记的一种专门方法。任何一项经济活动都会引起资金的增减变动或财务收支的变动。 以上内容来自百度百科。 如何记账 当前账本的交易记录主要分为三种:记录收益,记录支出,结余调整。下面分别展开进行介绍。 如何记录收益 我们首先记录一下收入情况,我们将公司CompanyA和公司CompanyB的薪水转移到资产Assets:Bank:China:CCB:CardXXX1中,这个资产定义的是我的银行卡。双引号中间的内容是注释性说明。要确保转移数值平衡,即相加为 0 。 12345672019-06-21 * "CompanyA" "Salary" Assets:Bank:China:CCB:CardXXX1 13000.00 CNY Income:China:CompanyA:Salary -13000.00 CNY2019-06-18 * "CompanyB" "Salary" Assets:Bank:China:CCB:CardXXX1 9000.00 CNY Income:China:CompanyB:Salary -9000.00 CNY 以上内容可以直接写到.bean文件中。 如何记录消费 记录消费情况和记录收益情况类似,但是要注意资产转移的方向,即数值的正负号。 1234567891011121314152019-04-17 * "储蓄卡" "餐饮(储蓄卡)" Assets:Bank:China:CCB:CardXXX1 -35 CNY Expenses:Food:Canteen 35 CNY2019-04-18 * "储蓄卡" "餐饮(储蓄卡)" Assets:Bank:China:CCB:CardXXX1 -5 CNY Expenses:Food:Canteen 5 CNY2019-04-20 * "储蓄卡" "餐饮 金稻园" Assets:Bank:China:CCB:CardXXX1 -283 CNY Expenses:Food:Restaurant 283 CNY2019-04-20 * "储蓄卡" "水果(储蓄卡)" Assets:Bank:China:CCB:CardXXX1 -20.4 CNY Expenses:Food:Fruits 20.4 CNY 以上内容也可以直接写到.bean文件中。 结余调整 我们并不能完全记录每一笔收入和支出情况,所以会造成账本资产情况和实际资产情况数值不符。但是对于小数额的差值,我们可以使用结余调整。这样就把差值的资产补回来了。例如: 1232019-01-01 * "结余调整" Assets:Bank:China:CCB:CardXXX1 200 CNY Equity:Opening-Balances -200 CNY 上边的意思是,从账户 Equity:Opening-Balances 转给账户 Assets:Bank:China:CCB:CardXXX1。Beancount的规范是使用 Equity:Opening-Balances。Equity:Opening-Balances 是权益类别下面的账户,可以表示没有记录来源的资产。 Beancount 项目目录结构 本人认为按照时间顺序记录账本的方法比较方便,所以我目前使用的目录结构如下; 123456789101112131415~/Documents/MyBean├── data│ ├── 2017.bean│ ├── 2018.bean│ └── 2017.bean├── documents.tmp/├── Importers│ ├── __init__.py│ ├── regexp.py // 原来在位于 beancount/experiments/ingest/regexp.py│ └── alipay.py├── configs│ ├── alipay.config│ └── wechat.config├── main.bean└── strip_blank.py main.bean:主要记录账户信息,包括 Assets,Liabilities,Equity,Expenses,Income 各类账户。其次使用 include 命令包含其他账本文件(.bean); data/:按照时间顺序存放收入和交易记录的账本文件(.bean); documents.tmp/:用于存放支付宝和微信的下载的交易记录文件(.csv); Importers/:用于存放自定义的导入脚本; configs/:xxxx.config 文件负责定义如何阅读并提取csv账单文件; strip_blank.py:删除 csv 文件中的所有多余空格的脚本; 当然也有其他的目录结构,如 blog 中提到的: 1234567891011~/Documents/accounting├── documents│ ├── Assets/│ ├── Expenses/│ ├── Income/│ └── Liabilities/├── documents.tmp/├── importers│ ├── __init__.py├── yc.bean└── yc.import 如何在主文件下包含其他 bean 文件 在上个章节--Beancount 项目目录结构--中,我们按照时间顺序存放收入和交易记录的账本文件(.bean),例如:2017.bean,2018.bean,2019.bean,那我们如何在主文件中导入这些子文件呢?可以使用 include 命令,如下: 12345* Includeinclude "data/2017.bean"include "data/2018.bean"include "data/2019.bean" 如果我们想把工资收入情况做单独的记录,那么可以单独建立一个 Income.bean 文件,然后在使用 include 命令包含进来。 1include "Income/Income.bean" 使用 CSV 账单文件生成流水.bean文件 我们时间和精力有限,所以并不能手工记录每一次交易情况。为了方便生成交易账单,我们可以下载支付宝、微信、银行等交易记录,并且使用程序将他们转化为账单文件(.bean)。这样节省了很多时间,并且记录准确。 bean-extract 命令 bean-extract 命令: 从每个文件中提取交易和日期。这会生成一些 Beancount 输入文本,这些文本(.bean)文件移动到您的输入文件中; 1bean-extract blais.config ~/Downloads 支付宝账单处理过程 可以参考 blog。 先把 csv 使用 wps 转换为 xls; 在使用 pandas 将 xls 转换为 utf-8 格式的 csv; 123import pandas as pddata_xls = pd.read_excel('alipay_record_20190712_2003_1.xls', index_col=0) data_xls.to_csv('alipay_tmp.csv', encoding='utf-8') 最后去除首尾的非数据信息; 使用 strip_blank.py 删除文件中的所有多余空格; 1python strip_blank.py alipay_tmp.csv > alipay.csv 使用bean-extract提取beancount数据。 1bean-extract my_alipay.config alipay.csv > data_alipay.beancount Atom Beancount 语法高亮工具 如果你使用 Atom 打开 beancount,可以安装 language-beancount,这个库可以高亮 beancount 的语法。 language-beancount fava 使用技巧 https://beancount.github.io/fava/index.html web端使用fava,可以远程访问。 可以使用如下命令,指定IP和端口号: https://github.com/beancount/fava/blob/master/contrib/deployment.rst 1fava --host localhost --port 5000 --prefix /fava /path/to/your/main.beancount Beancount 相关资料介绍 官方资料: Beancount官方网站 Beancount官方文档 Beancount邮件列表 Beancount 官方代码库 bitbucket Beancount github Fava 是 Beancount 的 web 界面,非常友好。 Fave github 强烈推荐一下博客: byvoid blog 该博客介绍的非常系统 Beancount使用经验 该博客介绍了通过Beancount导入支付宝csv账单的方法 beancount 简易入门指南 lidongchao/BeancountSample 这里包含一些代码,可以用于导入 csv 账单到 Beancount 中。 其他介绍文章 Beancount —— 命令行复式簿记 beancount 起步 利用 Beancount 打造个人的记账系统]]></content>
<categories>
<category>Tools</category>
</categories>
<tags>
<tag>Beancount</tag>
<tag>Tools</tag>
</tags>
</entry>
<entry>
<title><![CDATA[L2 Normalization]]></title>
<url>%2F2019%2F07%2F10%2Fl2normalization%2F</url>
<content type="text"><![CDATA[论文:ParseNet: Looking Wider to See Better,link L2 Normalization layers 这篇语义分割的文章提出使用 \(L_2\) Normalization layers。问题提出的结构如下图所示: 如图3所示,当我们需要组合两个或者更多的特征向量时,它们通常有不同的尺度和范数。简单的级联特征导致较差的性能,因为比较大的特征会主导较小的特征。虽然在训练期间,权重可能会相应调整,但需要非常仔细地调整参数,并且依赖于数据集,因此违背了稳健原则。我们发现,通过首先规范每个单独的特征,并学习以不同尺度进行放缩,这使得训练更加稳定,并且可以提高性能。 \(L_2\) 范数层不仅在特征组合的时候使用。如上所述,在某些情况下,后期融合也同样有效,但仅在L2归一化的帮助下。例如,如果我们想使用底层的特征去学习分类器,如图3所示,一些特征可能有很大的范数。在没有只是的权重初始化和参数调整的情况下,这非常困难。关于这个策略的一个工作就是使用一个附加的卷积层,并且使用多级微调,例如底层使用更小的学习率。这违反了简单和鲁棒的原则。在这篇论文的工作中,对分类之前的特征的每个通道,作者使用了\(L_2\)-norm并且学习了缩放参数,这导致了更加稳定的训练。 对于一个d维的输入 \(\mathbf{x}=(x_1, ..., x_d)\),我们使用 \(L_2\)-norm 规范它,即 \(\hat{x}=\frac{x}{\lVert x \rVert_2}\),其中 \(\lVert x \rVert_2=(\sum_{i=1}^{d} {\lvert x_i \rvert}^2)^{1/2}\) 是 \(\mathbf{x}\) 的 \(L_2\) 范数。 请注意,如果我们不相应地缩放它,只简单地规范化层的每个输入会改变层的尺度,将会减慢学习速度。例如,我们尝试规范化功能 s.t. \(L_2\)-norm 是1,但我们很难训练网络,因为特征变得非常小。 但是,如果我们将其规范化为,例如 10 或 20,网络开始较好的学习。在 batch normalization 和 PReLU 的推动下,我们为每个通道引入缩放参数 \(\gamma_i\),它缩放了归一化的值 \(y_i=\gamma_i \hat{x}_i\)。 额外参数的数量等于通道的总数,并且可以忽略不计,并且可以通过反向传播来学习。 实际上,通过设置 \(\gamma_i={\lVert x_i \rVert}^2\),我们可以恢复 \(L_2\) 归一化的特征。这很容易实现,因为规范化和缩放参数学习仅依赖于每个输入特征向量,并且不需要像批量规范化那样聚合来自其他样本的信息。在训练期间,我们使用反向传播和链规则来计算关于缩放银子 \(\gamma\) 和输入数据 \(\mathbf{x}\) 的导数。 Pytorch Code 12import torch.nn.functional as Fx = F.normalize(x, p=2, dim=1) 12345678910111213141516import torchimport torch.nn.functional as FIn [54]: x = torch.randn((1, 1, 10)) In [55]: out = F.normalize(x, p=2, dim=2) In [56]: out Out[56]:tensor([[[ 0.2941, -0.3471, -0.0732, 0.0674, -0.3557, -0.1949, 0.6813, -0.1356, -0.0153, -0.3686]]])In [57]: x / torch.sqrt((x**2).sum(2)) Out[57]:tensor([[[ 0.2941, -0.3471, -0.0732, 0.0674, -0.3557, -0.1949, 0.6813, -0.1356, -0.0153, -0.3686]]])]]></content>
<categories>
<category>Deep Learning</category>
</categories>
<tags>
<tag>Deep Learning</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Pandas Tutorial]]></title>
<url>%2F2019%2F06%2F23%2FPandas-Tutorial%2F</url>
<content type="text"><![CDATA[10 Minutes to pandas 本文原网址 导入所需要的包。 123In [1]: import pandas as pdIn [2]: import numpy as npIn [3]: import matplotlib.pyplot as plt 目标创建 通过传递一个列表创建 Series,让pandas创建一个默认的整型索引: 1234567891011In [4]: s = pd.Series([1,3,5,np.nan,6,8])In [5]: sOut[5]:0 1.01 3.02 5.03 NaN4 6.05 8.0dtype: float64 通过传递一个Numpy数组创建一个DataFrame数据,用时间和有标签的列作为索引: 12345678910111213141516171819In [6]: dates = pd.date_range('20130101', periods=6)In [7]: datesOut[7]:DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'], dtype='datetime64[ns]', freq='D')In [8]: df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))In [9]: dfOut[9]: A B C D2013-01-01 0.469112 -0.282863 -1.509059 -1.1356322013-01-02 1.212112 -0.173215 0.119209 -1.0442362013-01-03 -0.861849 -2.104569 -0.494929 1.0718042013-01-04 0.721555 -0.706771 -1.039575 0.2718602013-01-05 -0.424972 0.567020 0.276232 -1.0874012013-01-06 -0.673690 0.113648 -1.478427 0.524988 通过传递一个序列对象的字典创建DataFrame。 123456789101112131415In [10]: df2 = pd.DataFrame({ 'A' : 1., ....: 'B' : pd.Timestamp('20130102'), ....: 'C' : pd.Series(1,index=list(range(4)),dtype='float32'), ....: 'D' : np.array([3] * 4,dtype='int32'), ....: 'E' : pd.Categorical(["test","train","test","train"]), ....: 'F' : 'foo' }) ....:In [11]: df2Out[11]: A B C D E F0 1.0 2013-01-02 1.0 3 test foo1 1.0 2013-01-02 1.0 3 train foo2 1.0 2013-01-02 1.0 3 test foo3 1.0 2013-01-02 1.0 3 train foo 得到的DataFrame的列有不同的类型: 123456789In [12]: df2.dtypesOut[12]:A float64B datetime64[ns]C float32D int32E categoryF objectdtype: object 浏览数据 可以看基本章节。 这里我们查看一下frame的前几行和后几行: 123456789101112131415In [14]: df.head()Out[14]: A B C D2013-01-01 0.469112 -0.282863 -1.509059 -1.1356322013-01-02 1.212112 -0.173215 0.119209 -1.0442362013-01-03 -0.861849 -2.104569 -0.494929 1.0718042013-01-04 0.721555 -0.706771 -1.039575 0.2718602013-01-05 -0.424972 0.567020 0.276232 -1.087401In [15]: df.tail(3)Out[15]: A B C D2013-01-04 0.721555 -0.706771 -1.039575 0.2718602013-01-05 -0.424972 0.567020 0.276232 -1.0874012013-01-06 -0.673690 0.113648 -1.478427 0.524988 显示索引和列,并且显示隐含的NumPy数据: 1234567891011121314151617In [16]: df.indexOut[16]:DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'], dtype='datetime64[ns]', freq='D')In [17]: df.columnsOut[17]: Index(['A', 'B', 'C', 'D'], dtype='object')In [18]: df.valuesOut[18]:array([[ 0.4691, -0.2829, -1.5091, -1.1356], [ 1.2121, -0.1732, 0.1192, -1.0442], [-0.8618, -2.1046, -0.4949, 1.0718], [ 0.7216, -0.7068, -1.0396, 0.2719], [-0.425 , 0.567 , 0.2762, -1.0874], [-0.6737, 0.1136, -1.4784, 0.525 ]]) describe()显示一个快速的你的数据的统计信息: 1234567891011In [19]: df.describe()Out[19]: A B C Dcount 6.000000 6.000000 6.000000 6.000000mean 0.073711 -0.431125 -0.687758 -0.233103std 0.843157 0.922818 0.779887 0.973118min -0.861849 -2.104569 -1.509059 -1.13563225% -0.611510 -0.600794 -1.368714 -1.07661050% 0.022070 -0.228039 -0.767252 -0.38618875% 0.658444 0.041933 -0.034326 0.461706max 1.212112 0.567020 0.276232 1.071804 转置你的数据: 1234567In [20]: df.TOut[20]: 2013-01-01 2013-01-02 2013-01-03 2013-01-04 2013-01-05 2013-01-06A 0.469112 1.212112 -0.861849 0.721555 -0.424972 -0.673690B -0.282863 -0.173215 -2.104569 -0.706771 0.567020 0.113648C -1.509059 0.119209 -0.494929 -1.039575 0.276232 -1.478427D -1.135632 -1.044236 1.071804 0.271860 -1.087401 0.524988 通过一个维度进行排序: 123456789In [21]: df.sort_index(axis=1, ascending=False)Out[21]: D C B A2013-01-01 -1.135632 -1.509059 -0.282863 0.4691122013-01-02 -1.044236 0.119209 -0.173215 1.2121122013-01-03 1.071804 -0.494929 -2.104569 -0.8618492013-01-04 0.271860 -1.039575 -0.706771 0.7215552013-01-05 -1.087401 0.276232 0.567020 -0.4249722013-01-06 0.524988 -1.478427 0.113648 -0.673690 通过数值排序: 123456789In [22]: df.sort_values(by='B')Out[22]: A B C D2013-01-03 -0.861849 -2.104569 -0.494929 1.0718042013-01-04 0.721555 -0.706771 -1.039575 0.2718602013-01-01 0.469112 -0.282863 -1.509059 -1.1356322013-01-02 1.212112 -0.173215 0.119209 -1.0442362013-01-06 -0.673690 0.113648 -1.478427 0.5249882013-01-05 -0.424972 0.567020 0.276232 -1.087401 选择 得到数据 选择一个列,这会产生一个Series, 等同于df.A: 123456789In [23]: df['A']Out[23]:2013-01-01 0.4691122013-01-02 1.2121122013-01-03 -0.8618492013-01-04 0.7215552013-01-05 -0.4249722013-01-06 -0.673690Freq: D, Name: A, dtype: float64 通过[]进行选择,这可以切开行: 12345678910111213In [24]: df[0:3]Out[24]: A B C D2013-01-01 0.469112 -0.282863 -1.509059 -1.1356322013-01-02 1.212112 -0.173215 0.119209 -1.0442362013-01-03 -0.861849 -2.104569 -0.494929 1.071804In [25]: df['20130102':'20130104']Out[25]: A B C D2013-01-02 1.212112 -0.173215 0.119209 -1.0442362013-01-03 -0.861849 -2.104569 -0.494929 1.0718042013-01-04 0.721555 -0.706771 -1.039575 0.271860 通过标签选择 更多请看here。 使用标签获得一个截面: 1234567In [26]: df.loc[dates[0]]Out[26]:A 0.469112B -0.282863C -1.509059D -1.135632Name: 2013-01-01 00:00:00, dtype: float64 通过标签选择多个轴线: 123456789In [27]: df.loc[:,['A','B']]Out[27]: A B2013-01-01 0.469112 -0.2828632013-01-02 1.212112 -0.1732152013-01-03 -0.861849 -2.1045692013-01-04 0.721555 -0.7067712013-01-05 -0.424972 0.5670202013-01-06 -0.673690 0.113648 显示一个标签切片,并且也包括结束点: 123456In [28]: df.loc['20130102':'20130104',['A','B']]Out[28]: A B2013-01-02 1.212112 -0.1732152013-01-03 -0.861849 -2.1045692013-01-04 0.721555 -0.706771 可视化 基础绘画: plot 123456In [2]: ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))In [3]: ts = ts.cumsum()In [4]: ts.plot()Out[4]: <matplotlib.axes._subplots.AxesSubplot at 0x1c2ead5a20> Alt text 1234In [15]: plt.figure();In [16]: df.iloc[5].plot.bar(); plt.axhline(0, color='k')Out[16]: <matplotlib.lines.Line2D at 0x1c318b4f60> Alt text 123In [17]: df2 = pd.DataFrame(np.random.rand(10, 4), columns=['a', 'b', 'c', 'd'])In [18]: df2.plot.bar(); Alt text 直方图(Histograms) 12345678In [21]: df4 = pd.DataFrame({'a': np.random.randn(1000) + 1, 'b': np.random.randn(1000), ....: 'c': np.random.randn(1000) - 1}, columns=['a', 'b', 'c']) ....:In [22]: plt.figure();In [23]: df4.plot.hist(alpha=0.5)Out[23]: <matplotlib.axes._subplots.AxesSubplot at 0x1c2f3fb2e8> Alt text 1234In [24]: plt.figure();In [25]: df4.plot.hist(stacked=True, bins=20)Out[25]: <matplotlib.axes._subplots.AxesSubplot at 0x1233ad2b0> Alt text 1234In [28]: plt.figure();In [29]: df['A'].diff().hist()Out[29]: <matplotlib.axes._subplots.AxesSubplot at 0x1c333967f0> Alt text 123456789In [30]: plt.figure()Out[30]: <Figure size 640x480 with 0 Axes>In [31]: df.diff().hist(color='k', alpha=0.5, bins=50)Out[31]:array([[<matplotlib.axes._subplots.AxesSubplot object at 0x1c2b9669e8>, <matplotlib.axes._subplots.AxesSubplot object at 0x1c3184a0b8>], [<matplotlib.axes._subplots.AxesSubplot object at 0x1c2e766668>, <matplotlib.axes._subplots.AxesSubplot object at 0x1c319e1240>]], dtype=object) Alt text 12345678In [32]: data = pd.Series(np.random.randn(1000))In [33]: data.hist(by=np.random.randint(0, 4, 1000), figsize=(6, 4))Out[33]:array([[<matplotlib.axes._subplots.AxesSubplot object at 0x1c2f245898>, <matplotlib.axes._subplots.AxesSubplot object at 0x1c2fd204a8>], [<matplotlib.axes._subplots.AxesSubplot object at 0x1c2f326240>, <matplotlib.axes._subplots.AxesSubplot object at 0x1c2e751b00>]], dtype=object) Alt text]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python</tag>
<tag>Pandas</tag>
</tags>
</entry>
<entry>
<title><![CDATA[变量——看见社会小趋势]]></title>
<url>%2F2019%2F06%2F20%2FBook-BianLiang%2F</url>
<content type="text"><![CDATA[作者简介 何帆,男,现任北京大学汇丰商学院经济学教授,兼熵一资本首席经济学家。曾任中国社会科学院世界经济与政治研究所副所长,在政策研究领域研究已经超过20年 [3] ,发表学术论文100多篇,出版专著10余部,如《变量》《何帆大局观》等 。现被厦门大学EMBA管理学院特聘为EMBA讲师,同陆磊教授一同讲授EMBA课程-《宏观经济理论与实践》。同时,何帆是得到App《何帆大局观》《何帆的读书俱乐部》《何帆报告》课程主理人。 作者简介来自百度百科 摘抄 第一章 这样观察一棵树 2018年是一个新的开端。生活在2018年的人感受到的是中国经济遇到的各种冲击:中美贸易战、经济增长回落、股市下跌。他们会感到焦虑和担忧。旧路标已经消失,新秩序尚未出现。未来30年出现的一系列变化将挑战我们的认知,但历史从来都是一位“魔术师”,未来会出现意想不到的变化。在这一章,我会讲述如何像细致地观察一棵树一样观察历史,怎样从每年长出的“嫩芽”去判断中国文明这棵大树的生命力。我还会告诉你两个重要的概念:慢变量和小趋势。感知历史,就要会从慢变量中寻找小趋势。 第二章 在无人地带寻找无人机 2018年,关于技术发展路径的讨论引起全民关注。中国到底是应该集中全力补上“核心技术”,还是应该扬己所长发展“应用技术”呢?我将带你回顾美国在工业革命时期的经验,并试图发现中国在信息化时代的最佳战略。我找到的第二个变量是:技术赋能。在创新阶段,寻找新技术的应用场景更重要,在边缘地带更容易找到新技术的应用场景,技术必须与市场需求匹配。我们会到新疆去看无人机,而你很可能会在酒店里邂逅机器人。中国革命的成功靠的是“群众路线”,中国经济的崛起也要走“群众路线”。 第三章 老兵不死 2018年,谁是新兴产业,谁是传统产业?哪个更胜一筹?在过去几年,互联网大军就好像当年来自中亚大草原的游牧民族,兵强马壮,来去如风。在互联网大军的攻势下,传统产业的护城河形同虚设。到了2018年,这股“为跨不破”,精于“降维打击”的大军,却在一座城堡前久攻不下。这就是工业化的代表————已经有上百年历史的汽车行业。2018年,我发现的第三个变量是:老兵不死。我要带你到传统制造业的腹地,看看他们是如何抵御互联网行业的迅猛攻势。在这里,你会看到,传统行业的老兵早已经悄悄穿上了新的军装,而新兴的产业正在积极地想传统产业学习。新兴产业和传统产业的边界,也许并没有你想象的那般泾渭分明。 第四章 在菜市场遇见城市设计师 2018年,人们最关心的是房价是否会出现拐点,但从长时间来看更值得关注的是城市化的拐点。自上而下的城市化已不可持续。我观察到的第四个变量是:自下而上的力量浮出水面。城市化的进程不会停止,未来会有更多的城市圈,但这些都市圈是放大了的城市,还是一种新的城市物种呢?未来的城市不一定都能扩张,假如城市不得不“收缩”,该怎样才能像瘦身一样,瘦了更健康?未来的城市将深受互联网影响,城市空间布局会跟过去有很大的不同。“位置、位置、位置”的传统房地产“金律”很可能不再适用。我们会看到,城市会爆发一场“颜值革命”。这场“颜值革命”来自哪里呢?归根到底,它来自人民群众自己创造美好生活的能量。 第五章 阿那亚和范家小学 2018年,我们听到了很多负面的社会新闻:米脂杀人、衡阳装车、高铁霸座......这个社会变得越来越糟糕了吗?其中这是一种误解。虽然从表明上看,有些人只关心自我私利,但大家对集体生活的向往并没有泯灭。中国人已经意识到,只有重建集体生活,才能更好地发现自我。我看到的第五个变量就是:重建社群。有哪些地方的人们正在“凝结”起来,形成新的社群?这些新的社群只是孤岛,还是将成为群岛?培养孩子也需要一个社群。我会带你到一所偏僻的农村小学看看。2018年,我找到的中国教育理念最先进的小学不是北京或上海名校,而是山区里的一所农村小学。你不必吃惊,社会发展的剧情经常会有令人意想不到的转变。]]></content>
<categories>
<category>Book</category>
</categories>
<tags>
<tag>Book</tag>
</tags>
</entry>
<entry>
<title><![CDATA[High-level Semantic Feature Detection A New Perspective for Pedestrian Detection]]></title>
<url>%2F2019%2F05%2F29%2FCVPR2019-CSP%2F</url>
<content type="text"><![CDATA[Paper Link Code 简介 CSP: Center and Scale Prediction CVPR19_CSP_pipeline 20190529_CVPR19_CSP_architecture 20190529_CVPR19_CSP_annotations 方法 实验 20190529_CVPR19_CSP_points 20190529_CVPR19_CSP_scale 20190529_CVPR19_CSP_downsampling_factors 20190529_CVPR19_CSP_multi_scale 20190529_CVPR19_CSP_Caltech_new 20190529_CVPR19_CSP_CityPersons 代码 准备ground truth 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152def calc_gt_center(C, img_data,r=2, down=4,scale='h',offset=True): def gaussian(kernel): sigma = ((kernel-1) * 0.5 - 1) * 0.3 + 0.8 s = 2*(sigma**2) dx = np.exp(-np.square(np.arange(kernel) - int(kernel / 2)) / s) return np.reshape(dx,(-1,1)) gts = np.copy(img_data['bboxes']) igs = np.copy(img_data['ignoreareas']) scale_map = np.zeros((int(C.size_train[0]/down), int(C.size_train[1]/down), 2)) if scale=='hw': scale_map = np.zeros((int(C.size_train[0] / down), int(C.size_train[1] / down), 3)) if offset: offset_map = np.zeros((int(C.size_train[0] / down), int(C.size_train[1] / down), 3)) seman_map = np.zeros((int(C.size_train[0]/down), int(C.size_train[1]/down), 3)) seman_map[:,:,1] = 1 if len(igs) > 0: igs = igs/down for ind in range(len(igs)): x1,y1,x2,y2 = int(igs[ind,0]), int(igs[ind,1]), int(np.ceil(igs[ind,2])), int(np.ceil(igs[ind,3])) seman_map[y1:y2, x1:x2,1] = 0 # 被忽视的区域在第1个通道上置0 if len(gts)>0: gts = gts/down for ind in range(len(gts)): # x1, y1, x2, y2 = int(round(gts[ind, 0])), int(round(gts[ind, 1])), int(round(gts[ind, 2])), int(round(gts[ind, 3])) x1, y1, x2, y2 = int(np.ceil(gts[ind, 0])), int(np.ceil(gts[ind, 1])), int(gts[ind, 2]), int(gts[ind, 3]) c_x, c_y = int((gts[ind, 0] + gts[ind, 2]) / 2), int((gts[ind, 1] + gts[ind, 3]) / 2) dx = gaussian(x2-x1) dy = gaussian(y2-y1) gau_map = np.multiply(dy, np.transpose(dx)) seman_map[y1:y2, x1:x2,0] = np.maximum(seman_map[y1:y2, x1:x2,0], gau_map) # 在第0个通道上置高斯值 seman_map[y1:y2, x1:x2,1] = 1 # 前景在第1个通道上置1 seman_map[c_y, c_x, 2] = 1 # 在第2个通道上目标中心位置1 if scale == 'h': scale_map[c_y-r:c_y+r+1, c_x-r:c_x+r+1, 0] = np.log(gts[ind, 3] - gts[ind, 1]) scale_map[c_y-r:c_y+r+1, c_x-r:c_x+r+1, 1] = 1 elif scale=='w': scale_map[c_y-r:c_y+r+1, c_x-r:c_x+r+1, 0] = np.log(gts[ind, 2] - gts[ind, 0]) scale_map[c_y-r:c_y+r+1, c_x-r:c_x+r+1, 1] = 1 elif scale=='hw': scale_map[c_y-r:c_y+r+1, c_x-r:c_x+r+1, 0] = np.log(gts[ind, 3] - gts[ind, 1]) scale_map[c_y-r:c_y+r+1, c_x-r:c_x+r+1, 1] = np.log(gts[ind, 2] - gts[ind, 0]) scale_map[c_y-r:c_y+r+1, c_x-r:c_x+r+1, 2] = 1 if offset: offset_map[c_y, c_x, 0] = (gts[ind, 1] + gts[ind, 3]) / 2 - c_y - 0.5 offset_map[c_y, c_x, 1] = (gts[ind, 0] + gts[ind, 2]) / 2 - c_x - 0.5 offset_map[c_y, c_x, 2] = 1 if offset: return seman_map,scale_map,offset_map else: return seman_map, scale_map seman_map有三个位面,第一个是高斯值mask,第二个是学习权重,第三个是目标中心点的位置。 20190529_CVPR19_CSP_seman_map0 20190529_CVPR19_CSP_seman_map2 20190529_CVPR19_CSP_scale_map0 网络结构 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162def nn_p3p4p5(img_input=None, offset=True, num_scale=1, trainable=False): bn_axis = 3 x = ZeroPadding2D((3, 3))(img_input) x = Convolution2D(64, (7, 7), strides=(2, 2), name='conv1', trainable=False)(x) x = BatchNormalization(axis=bn_axis, name='bn_conv1')(x) x = Activation('relu')(x) x = MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x) x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1), trainable=False) x = identity_block(x, 3, [64, 64, 256], stage=2, block='b', trainable=False) stage2 = identity_block(x, 3, [64, 64, 256], stage=2, block='c', trainable=False) # print('stage2: ', stage2._keras_shape[1:]) x = conv_block(stage2, 3, [128, 128, 512], stage=3, block='a', trainable=trainable) x = identity_block(x, 3, [128, 128, 512], stage=3, block='b', trainable=trainable) x = identity_block(x, 3, [128, 128, 512], stage=3, block='c', trainable=trainable) stage3 = identity_block(x, 3, [128, 128, 512], stage=3, block='d', trainable=trainable) # print('stage3: ', stage3._keras_shape[1:]) x = conv_block(stage3, 3, [256, 256, 1024], stage=4, block='a', trainable=trainable) x = identity_block(x, 3, [256, 256, 1024], stage=4, block='b', trainable=trainable) x = identity_block(x, 3, [256, 256, 1024], stage=4, block='c', trainable=trainable) x = identity_block(x, 3, [256, 256, 1024], stage=4, block='d', trainable=trainable) x = identity_block(x, 3, [256, 256, 1024], stage=4, block='e', trainable=trainable) stage4 = identity_block(x, 3, [256, 256, 1024], stage=4, block='f', trainable=trainable) # print('stage4: ', stage4._keras_shape[1:]) x = conv_block(stage4, 3, [512, 512, 2048], stage=5, block='a', strides=(1, 1), dila=(2, 2), trainable=trainable) x = identity_block(x, 3, [512, 512, 2048], stage=5, block='b', dila=(2, 2), trainable=trainable) stage5 = identity_block(x, 3, [512, 512, 2048], stage=5, block='c', dila=(2, 2), trainable=trainable) # print('stage5: ', stage5._keras_shape[1:]) P3_up = Deconvolution2D(256, kernel_size=4, strides=2, padding='same', kernel_initializer='glorot_normal', name='P3up', trainable=trainable)(stage3) # print('P3_up: ', P3_up._keras_shape[1:]) P4_up = Deconvolution2D(256, kernel_size=4, strides=4, padding='same', kernel_initializer='glorot_normal', name='P4up', trainable=trainable)(stage4) # print('P4_up: ', P4_up._keras_shape[1:]) P5_up = Deconvolution2D(256, kernel_size=4, strides=4, padding='same', kernel_initializer='glorot_normal', name='P5up', trainable=trainable)(stage5) # print('P5_up: ', P5_up._keras_shape[1:]) P3_up = L2Normalization(gamma_init=10, name='P3norm')(P3_up) P4_up = L2Normalization(gamma_init=10, name='P4norm')(P4_up) P5_up = L2Normalization(gamma_init=10, name='P5norm')(P5_up) conc = Concatenate(axis=-1)([P3_up, P4_up, P5_up]) feat = Convolution2D(256, (3, 3), padding='same', kernel_initializer='glorot_normal', name='feat', trainable=trainable)(conc) feat = BatchNormalization(axis=bn_axis, name='bn_feat')(feat) feat = Activation('relu')(feat) x_class = Convolution2D(1, (1, 1), activation='sigmoid', kernel_initializer='glorot_normal', bias_initializer=prior_probability_onecls(probability=0.01), name='center_cls', trainable=trainable)(feat) x_regr = Convolution2D(num_scale, (1, 1), activation='linear', kernel_initializer='glorot_normal', name='height_regr', trainable=trainable)(feat) if offset: x_offset = Convolution2D(2, (1, 1), activation='linear', kernel_initializer='glorot_normal', name='offset_regr', trainable=trainable)(feat) return [x_class, x_regr, x_offset] else: return [x_class, x_regr] Loss 12345678910111213141516def cls_center(y_true, y_pred): classification_loss = K.binary_crossentropy(y_pred[:, :, :, 0], y_true[:, :, :, 2]) # firstly we compute the focal weight positives = y_true[:, :, :, 2] negatives = y_true[:, :, :, 1]-y_true[:, :, :, 2] foreground_weight = positives * (1.0 - y_pred[:, :, :, 0]) ** 2.0 background_weight = negatives * ((1.0 - y_true[:, :, :, 0])**4.0)*(y_pred[:, :, :, 0] ** 2.0) focal_weight = foreground_weight + background_weight assigned_boxes = tf.reduce_sum(y_true[:, :, :, 2]) class_loss = 0.01*tf.reduce_sum(focal_weight*classification_loss) / tf.maximum(1.0, assigned_boxes) assigned_boxes) return class_loss]]></content>
<categories>
<category>Pedestrian Detection</category>
</categories>
<tags>
<tag>Pedestrian Detection</tag>
<tag>Deep Learning</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Deep High-Resolution Representation Learning for Human Pose Estimation]]></title>
<url>%2F2019%2F05%2F23%2FCVPR19-HRNet%2F</url>
<content type="text"><![CDATA[Paper Link Code 介绍 High-Resolution Net (HRNet) 这篇论文解决人体姿态估计问题,重点关注学习高分辨率表示。大多数现有的方法通过一个由高到低分辨率的网络,从一个低分辨率的表示中恢复高分辨率的表示。相反,本论文提出的网络自始至终都保持了高分辨率的表示。 作者从高分辨率子网作为第一个阶段,逐渐添加 高->低 分辨率的子网形成更多的阶段,并且并行连接这些多分辨率子网。作者多次进行多尺度融合,使得每一个高->低分辨率的表示可以从其他并行的表示中接收信息,从而生成丰富的高分辨率表示。因此,预测的关键点热图可以更准确,空间更精确。作者在COCO关键点检测数据集和MPII Human Pose数据集上进行了验证。 与其他方法之前的区别 该方法并行级联高->低分辨率子网,而不是以序列的方式。因此,该方法保持了高分辨率,而不是从低分辨率中恢复高分辨率。所以预测的热图的空间上更准确。 现存的融合策略集成底层(low-level)和高层(high-level)的表示。 而该方法通过相似深度和相同层级的低分辨率表示的帮助,执行重复的多尺度融合提升高分率表示。 图1展示了提出的HRNet网络的结构。它包含并行的高->低分辨率的子网,重复的在不同分辨率子网之间的信息交换,即多尺度融合。水平和垂直方向分别对应于网络的深度和特征图的比例。 图2展示了其他方法的一些网络结构,这些方法都是依靠high-to-low和low-to-high框架的姿态估计网络结构。其中(a)表示Hourglass网络,(b)表示Cascaded pyramid networks,(c)表示SimpleBaseline网络:转置卷积(transposed convolutions)用于low-to-high过程。(d)组合空洞卷积(dilated convolutions)。 方法介绍 序列多尺度子网 用\(N_{sr}\)表示子网络在第s个stage,r表示分辨率的序号,它的分辨率是第一个子网络分辨率的\(\frac{1}{r^{r-1}}\)倍。有S=4个stege的high-to-low网络可以表示为: \[N_{11} \to N_{22} \to N_{33} \to N_{44}\] 并行多尺度子网 我们从一个高分辨率子网络作为第一个stage起始,逐渐地增加high-to-low分辨率子网络,形成新的sgates,并且并行地连接多分辨率子网络。因此,后一阶段并行子网的分辨率包括前一阶段的分辨率和一个更低的分辨率。 这里给出一个网络结构的例子,包含4个并行的子网络,如下: 重复多尺度融合 图3展示了交换单元(Exchange Unit)如何为高、中和底层融合信息的。右侧的注释表示:strided 3x3=stride 3x3卷积,up samp. 1x1=最近邻上采样和一个1x1卷积。 我们在不同的并行子网之间引入交换单元(exchange unit),这样每个子网可以重叠地从其他并行网络中接收信息。这里给出了一个交换信息框架的例子,如下图表示的结构。我们将第三个stage分成几个exchange blocks,并且每一个block有三个并行的卷积单元构成,一个交换单元在并行的卷积单元之间,如下: 其中,\(C^b_{sr}\)表示在第s个stage,第b个block的第r分辨率的卷积单元。\(\varepsilon^b_s\)是对应的交换的单元。 交换单元如图3所示。 热图估计 我们简单地从最后一个交换单元(exhcange unit)输出的高分辨率表示中回归热图。损失函数(定义为均方误差)用于比较预测的热图和groundtruth热图。通过应用2D高斯生成的groundtruth热图,其中标准偏差为1像素,并以每个关键点的标注位置为中心。 网络实例 实验中提出了两种网络,一个小网络HRNet-W32,一个大网络HRNet-W48,其中32和48分别表示在后3个sgate中的高分辨率子网络的宽度(C)。对于HRNet-W32,其他三个并行的子网络的宽度分别是64,128,256,对于HRNet-W48是96,192,384。 实验 代码 Exchange Unit 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556def _make_fuse_layers(self): if self.num_branches == 1: return None num_branches = self.num_branches num_inchannels = self.num_inchannels fuse_layers = [] for i in range(num_branches if self.multi_scale_output else 1): fuse_layer = [] for j in range(num_branches): if j > i: fuse_layer.append( nn.Sequential( nn.Conv2d( num_inchannels[j], num_inchannels[i], 1, 1, 0, bias=False ), nn.BatchNorm2d(num_inchannels[i]), nn.Upsample(scale_factor=2**(j-i), mode='nearest') ) ) elif j == i: fuse_layer.append(None) else: conv3x3s = [] for k in range(i-j): if k == i - j - 1: num_outchannels_conv3x3 = num_inchannels[i] conv3x3s.append( nn.Sequential( nn.Conv2d( num_inchannels[j], num_outchannels_conv3x3, 3, 2, 1, bias=False ), nn.BatchNorm2d(num_outchannels_conv3x3) ) ) else: num_outchannels_conv3x3 = num_inchannels[j] conv3x3s.append( nn.Sequential( nn.Conv2d( num_inchannels[j], num_outchannels_conv3x3, 3, 2, 1, bias=False ), nn.BatchNorm2d(num_outchannels_conv3x3), nn.ReLU(True) ) ) fuse_layer.append(nn.Sequential(*conv3x3s)) fuse_layers.append(nn.ModuleList(fuse_layer)) return nn.ModuleList(fuse_layers) HighResolutionModule 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165class HighResolutionModule(nn.Module): def __init__(self, num_branches, blocks, num_blocks, num_inchannels, num_channels, fuse_method, multi_scale_output=True): super(HighResolutionModule, self).__init__() self._check_branches( num_branches, blocks, num_blocks, num_inchannels, num_channels) self.num_inchannels = num_inchannels self.fuse_method = fuse_method self.num_branches = num_branches self.multi_scale_output = multi_scale_output self.branches = self._make_branches( num_branches, blocks, num_blocks, num_channels) self.fuse_layers = self._make_fuse_layers() self.relu = nn.ReLU(True) def _check_branches(self, num_branches, blocks, num_blocks, num_inchannels, num_channels): if num_branches != len(num_blocks): error_msg = 'NUM_BRANCHES({}) <> NUM_BLOCKS({})'.format( num_branches, len(num_blocks)) logger.error(error_msg) raise ValueError(error_msg) if num_branches != len(num_channels): error_msg = 'NUM_BRANCHES({}) <> NUM_CHANNELS({})'.format( num_branches, len(num_channels)) logger.error(error_msg) raise ValueError(error_msg) if num_branches != len(num_inchannels): error_msg = 'NUM_BRANCHES({}) <> NUM_INCHANNELS({})'.format( num_branches, len(num_inchannels)) logger.error(error_msg) raise ValueError(error_msg) def _make_one_branch(self, branch_index, block, num_blocks, num_channels, stride=1): downsample = None if stride != 1 or \ self.num_inchannels[branch_index] != num_channels[branch_index] * block.expansion: downsample = nn.Sequential( nn.Conv2d( self.num_inchannels[branch_index], num_channels[branch_index] * block.expansion, kernel_size=1, stride=stride, bias=False ), nn.BatchNorm2d( num_channels[branch_index] * block.expansion, momentum=BN_MOMENTUM ), ) layers = [] layers.append( block( self.num_inchannels[branch_index], num_channels[branch_index], stride, downsample ) ) self.num_inchannels[branch_index] = \ num_channels[branch_index] * block.expansion for i in range(1, num_blocks[branch_index]): layers.append( block( self.num_inchannels[branch_index], num_channels[branch_index] ) ) return nn.Sequential(*layers) def _make_branches(self, num_branches, block, num_blocks, num_channels): branches = [] for i in range(num_branches): branches.append( self._make_one_branch(i, block, num_blocks, num_channels) ) return nn.ModuleList(branches) def _make_fuse_layers(self): if self.num_branches == 1: return None num_branches = self.num_branches num_inchannels = self.num_inchannels fuse_layers = [] for i in range(num_branches if self.multi_scale_output else 1): fuse_layer = [] for j in range(num_branches): if j > i: fuse_layer.append( nn.Sequential( nn.Conv2d( num_inchannels[j], num_inchannels[i], 1, 1, 0, bias=False ), nn.BatchNorm2d(num_inchannels[i]), nn.Upsample(scale_factor=2**(j-i), mode='nearest') ) ) elif j == i: fuse_layer.append(None) else: conv3x3s = [] for k in range(i-j): if k == i - j - 1: num_outchannels_conv3x3 = num_inchannels[i] conv3x3s.append( nn.Sequential( nn.Conv2d( num_inchannels[j], num_outchannels_conv3x3, 3, 2, 1, bias=False ), nn.BatchNorm2d(num_outchannels_conv3x3) ) ) else: num_outchannels_conv3x3 = num_inchannels[j] conv3x3s.append( nn.Sequential( nn.Conv2d( num_inchannels[j], num_outchannels_conv3x3, 3, 2, 1, bias=False ), nn.BatchNorm2d(num_outchannels_conv3x3), nn.ReLU(True) ) ) fuse_layer.append(nn.Sequential(*conv3x3s)) fuse_layers.append(nn.ModuleList(fuse_layer)) return nn.ModuleList(fuse_layers) def get_num_inchannels(self): return self.num_inchannels def forward(self, x): if self.num_branches == 1: return [self.branches[0](x[0])] for i in range(self.num_branches): x[i] = self.branches[i](x[i]) x_fuse = [] for i in range(len(self.fuse_layers)): y = x[0] if i == 0 else self.fuse_layers[i][0](x[0]) for j in range(1, self.num_branches): if i == j: y = y + x[j] else: y = y + self.fuse_layers[i][j](x[j]) x_fuse.append(self.relu(y)) return x_fuse]]></content>
<categories>
<category>Deep Learning</category>
</categories>
<tags>
<tag>Deep Learning</tag>
<tag>Pose Estimation</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Adaptive NMS Refining Pedestrian Detection in a Crowd]]></title>
<url>%2F2019%2F05%2F20%2FAdaptive-NMS%2F</url>
<content type="text"><![CDATA[paper link 简介 这篇论文主要提出一个新颖的非极大值抑制(Non-Maximum Suppression, NMS)算法更好地改善检测器给出的检测框。本文主要贡献: 提出adaptive-NMS,该算法根据目标的密度使用一个动态抑制阈值。 设计一个高效网络学习密度得分,这个得分可以方便地嵌入到single-stage和two-stage检测器中。 实现了CityPersons和CrowdHuman数据集上的 state of the art 结果。 Motivation 图1展示了不同阈值下的greedy-NMS的结果。蓝色的框表示丢失的目标,红色的框表示假正例(false positives)。(b)中的检测框是Faster R-CNN在NMS之前的检测结果。如图c,一个低的NMS阈值可能会移除正例(true positives)。如同d,一个高的NMS阈值可能会增加假正例(false positives)。 在本文中,作者提出了一种新的NMS算法,名为adaptive-NMS,它可以作为人群中行人检测的更有效的替代方案。直观地,高NMS阈值保持更多拥挤的实例,而低NMS阈值消除更多误报。因此,自适应NMS应用动态抑制策略,其中阈值随着实例聚集和相互遮挡而上升,并且当实例单独出现时衰减。为此,我们设计了一个辅助且可学习的子网络来预测每个实例的自适应NMS阈值。 Adaptive-NMS 当物体处于拥挤区域时,增加NMS的阈值可以保留高覆盖率。同样,在稀疏场景下,应该去掉重复度高的候选框,因为它们很可能是假正例。 \[ d_i:= \max_{b_j \in \mathcal{G}, i \neq j} \mathrm{iou}(b_i, b_j) \] 目标\(i\)的密度被定义和在ground truth集合\(\mathcal{G}\)中的其他目标的最大紧致框的IoU的值。目标的密度表示拥挤遮挡的程度。 使用这个定义,我们提出更新下面策略中的移除步骤, \[ N_\mathcal{M} := \max(N_t, d_\mathcal{M}) \] \(N_t\)表示对于\(\mathcal{M}\)的adaptive NMS的阈值,\(d_{\mathcal{M}}\)表示目标\(\mathcal{M}\)覆盖的密度。 这个抑制策略有三个性质: 1. 当相邻的框远离\(\mathcal{M}\)时,即\(\mathrm{iou}(\mathcal{M}, b_i) < N_t\),它们与原始NMS保持一致。 2. 如果\(\mathcal{M}\)定位到拥挤的区域,即\(d_{\mathcal{M}} > N_t\),\(\mathcal{M}\)的密度被使用作为adaptive NMS的阈值。 3. 对与稀疏区域的目标,即\(d_{\mathcal{M}} \leq N_t\),NMS阈值\(N_\mathcal{M}\)和原始NMS阈值相等,非常接近的框被作为假正例所抑制。 这个算法具体步骤如图2所示。 Density Prediction 作者把密度估计作为一个回归问题,目标密度值的计算根据它的定义,使用Smooth-L1损失函数作为训练损失。 一个天然的方式就是为这个回归在网络顶部添加一个并行的层,像分类和定位一样。然而,用于检测的特征仅仅包含目标自己的信息,比如外表、语义特征和位置。对于密度估计,使用独立目标的信息很难估计其密度,密度估计需要使用其周围目标的更多的线索。 为了解决这个,作者设计了一个额外的网络,它由三层卷积层构成,如图3所示。首选使用一个1x1的卷积层做特征维度降维,然后级联降维后的特征、用于RPN分类的特征和用于RPN回归的特征。最后使用一个大尺度的卷积核5x5作为最后的卷积层,为了把周围的信息送入网络。具体如图中Density subnet绿色框区域结构。 Experiments]]></content>
<categories>
<category>Pedestrian Detection</category>
</categories>
<tags>
<tag>Pedestrian Detection</tag>
<tag>Deep Learning</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Squeeze-and-Excitation Networks]]></title>
<url>%2F2019%2F05%2F17%2FSqueeze-and-Excitation-Networks%2F</url>
<content type="text"><![CDATA[SENet介绍 卷积神经网络(CNNs)的核心模块是卷积操作,这个操作使得网络能够通过每层的局部感受野融合空间和通道的信息,来构建有信息的特征。之前大量的工作已经研究了这种关系的空间组成部分,试图通过提高整个特征层次中空间编码的质量来增强CNN的表征能力。在这项工作中,作者将重点放在通道关系上,并且提出一个新的构架单元,成为“Squeeze-and-Excitation”(SE)块,通过明确地建模通道之间的相互依赖性来自适应地重新校准通道方面的特征响应。 Squeeze-and-Excitation Blocks Squeeze: 全局信息嵌入 Excition: 适应性地校准 实例化到ResNet和Inception 代码 Caffe Caffe SENet 第三方实现 Caffe. SE-mudolues are integrated with a modificated ResNet-50 using a stride 2 in the 3x3 convolution instead of the first 1x1 convolution which obtains better performance: Repository. TensorFlow. SE-modules are integrated with a pre-activation ResNet-50 which follows the setup in fb.resnet.torch: Repository. TensorFlow. Simple Tensorflow implementation of SENets using Cifar10: Repository. MatConvNet. All the released SENets are imported into MatConvNet: Repository. MXNet. SE-modules are integrated with the ResNeXt and more architectures are coming soon: Repository. PyTorch. Implementation of SENets by PyTorch: Repository. Chainer. Implementation of SENets by Chainer: Repository. Pytorch实现SE模块 来自https://github.com/moskomule/senet.pytorch/blob/master/senet/se_module.py的se_module.py文件 1234567891011121314151617181920from torch import nnclass SELayer(nn.Module): def __init__(self, channel, reduction=16): super(SELayer, self).__init__() self.avg_pool = nn.AdaptiveAvgPool2d(1) self.fc = nn.Sequential( nn.Linear(channel, channel // reduction, bias=False), nn.ReLU(inplace=True), nn.Linear(channel // reduction, channel, bias=False), nn.Sigmoid() ) def forward(self, x): b, c, _, _ = x.size() y = self.avg_pool(x).view(b, c) y = self.fc(y).view(b, c, 1, 1) return x * y.expand_as(x)]]></content>
<categories>
<category>Deep Learning</category>
</categories>
<tags>
<tag>Deep Learning</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Pillow Tutorial]]></title>
<url>%2F2019%2F04%2F11%2FPillow-Tutorial%2F</url>
<content type="text"><![CDATA[Pillow 教程 PIL(Python Image Library)是python的第三方图像处理库。其官方主页为:PIL。 PIL历史悠久,原来是只支持python2.x的版本的,后来出现了移植到python3的库pillow, pillow号称是friendly fork for PIL。 Pillow is the friendly PIL fork by Alex Clark and Contributors. PIL is the Python Imaging Library by Fredrik Lundh and Contributors. for Python2 Python Imaging Library (PIL) for Python3 The Python Imaging Library Handbook python-pillow Pillow Github Pillow Docs 123from PIL import Imageimport matplotlib.pyplot as plt%matplotlib inline 从一个文件加载图片,使用在Image模块下的open()函数。 1im = Image.open("lena.jpg") 1. 使用Image类 如果成功,这个函数会返回一个Image目标。你可以使用实例属性去测试这个文件的内容: 12from __future__ import print_functionprint(im.format, im.size, im.mode) JPEG (512, 512) RGB format属性判断图片的来源。如果一个图片不是从一个文件读入,它会被设置成None。size属性是一个2元组,包含宽和高。mode属性定义图片通道的数量和名字,以及像素类型和深度。通常的模式包含:“L”(luminance)表示灰度图像,”RGB“表示真彩色图像,”CMYK“表示印前(pre-press)图像 如果文件没有被打开,会给出IOError。 一旦你有一个Image类的实例,你可以使用这个类定义的方法取处理这个图片。例如,显示我们刚加载的图片: 1im.show() 使用matplotlib进行可视化 1plt.imshow(im) <matplotlib.image.AxesImage at 0x7f1173b85518> png 2. 读取和写入图像 3. 剪切、复制和合并图像 Image类包含允许您操作图像中的区域的方法。要从图像中提取矩形区域,请使用crop()方法。 从一个图片中复制一个矩形区域 123box = (100, 100, 400, 400)region = im.crop(box)print(region.size) (300, 300) 这个区域使用一个4元组定义,它的坐标是(left, upper, right, lower)。Python Imaging Library在左上角使用(0, 0)的坐标系统。坐标表示像素之间的位置,因此上边例子中的区域是300x300像素。 处理一个矩形区域,并且把它粘贴回原来位置 123region = region.transpose(Image.ROTATE_180)im.paste(region, box)plt.imshow(im) <matplotlib.image.AxesImage at 0x7f11721e2518> png 当把区域粘贴回去,区域的尺寸必须相同。除此之外,这个区域不能超越图像的边界。 12345678910111213def roll(image, delta): """Roll an image sideways.""" xsize, ysize = image.size delta = delta % xsize if delta == 0: return image part1 = image.crop((0, 0, delta, ysize)) part2 = image.crop((delta, 0, xsize, ysize)) image.paste(part1, (xsize-delta, 0, xsize, ysize)) image.paste(part2, (0, 0, xsize-delta, ysize)) return image 拆分和合并通道 123r, g, b = im.split()im = Image.merge("RGB", (b, g, r))plt.imshow(im) <matplotlib.image.AxesImage at 0x7f11721c9b38> png 保存图像 1im.save(r'out.jpg') 新建图像 12newIm= Image.new('RGB', (50, 50), 'red')plt.imshow(newIm) <matplotlib.image.AxesImage at 0x7f1175c2d630> png 123# 十六进制颜色newIm = Image.new('RGBA',(100, 50), '#FF0000')plt.imshow(newIm) <matplotlib.image.AxesImage at 0x7f1175bfd8d0> png 1234# 传入元组形式的RGBA值或者RGB值# 在RGB模式下,第四个参数失效,默认255,在RGBA模式下,也可只传入前三个值,A值默认255newIm = Image.new('RGB',(200, 100), (255, 255, 0, 120))plt.imshow(newIm) <matplotlib.image.AxesImage at 0x7f1175bd1be0> png 复制图片 12copyIm = im.copy()copyIm.size (512, 512) 调整图片大小 123width, height = copyIm.sizeresizedIm = im.resize((width, int(0.5* height)))resizedIm.size (512, 256) 4. 几何变换 1234im = Image.open("lena.jpg")out = im.resize((128, 128))out = im.rotate(45) # degrees counter-clockwiseplt.imshow(out) <matplotlib.image.AxesImage at 0x7f11721370b8> png 转置图像 123456out = im.transpose(Image.FLIP_LEFT_RIGHT)out = im.transpose(Image.FLIP_TOP_BOTTOM)out = im.transpose(Image.ROTATE_90)out = im.transpose(Image.ROTATE_180)out = im.transpose(Image.ROTATE_270)plt.imshow(out) <matplotlib.image.AxesImage at 0x7f1172111080> png 5. 颜色变换 在不同models之间转换 123from PIL import Imageim = Image.open("lena.jpg").convert("L")print(im.mode) L 6. 图片增强 滤波器 123from PIL import ImageFilterout = im.filter(ImageFilter.DETAIL)plt.imshow(out) <matplotlib.image.AxesImage at 0x7f1172073860> png 123# 高斯模糊out = im.filter(ImageFilter.GaussianBlur)plt.imshow(out) <matplotlib.image.AxesImage at 0x7f117204f470> png 123# 边缘增强im.filter(ImageFilter.EDGE_ENHANCE)plt.imshow(out) <matplotlib.image.AxesImage at 0x7f1171faf0b8> png 1234567891011121314# 普通模糊im.filter(ImageFilter.BLUR)# 找到边缘im.filter(ImageFilter.FIND_EDGES)# 浮雕im.filter(ImageFilter.EMBOSS)# 轮廓im.filter(ImageFilter.CONTOUR)# 锐化im.filter(ImageFilter.SHARPEN)# 平滑im.filter(ImageFilter.SMOOTH)# 细节im.filter(ImageFilter.DETAIL) png 应用点变换 12# multiply each pixel by 1.2out = im.point(lambda i: i * 1.2) 增强图像 12345from PIL import ImageEnhanceenh = ImageEnhance.Contrast(im)out = enh.enhance(1.3)plt.imshow(out) <matplotlib.image.AxesImage at 0x7f1171f906a0> png 7. 图片序列 1234567891011from PIL import Imageim = Image.open("chi.gif")im.seek(1) # skip to the second frametry: while 1: im.seek(im.tell()+1) # do something to imexcept EOFError: pass # end of sequence 1plt.imshow(im) <matplotlib.image.AxesImage at 0x7f1171eec208> png 使用ImageSequence Iterator类 12345678from PIL import ImageSequencecount = 1for frame in ImageSequence.Iterator(im): # ...do something to frame... count += 1 if count % 10 == 0: plt.imshow(frame) plt.show() png png png 8. Postscript printing Drawing Postscript 12345678910111213141516171819from PIL import Imagefrom PIL import PSDrawim = Image.open("hopper.ppm")title = "hopper"box = (1*72, 2*72, 7*72, 10*72) # in pointsps = PSDraw.PSDraw() # default is sys.stdoutps.begin_document(title)# draw the image (75 dpi)ps.image(box, im, 75)ps.rectangle(box)# draw titleps.setfont("HelveticaNarrow-Bold", 36)ps.text((3*72, 4*72), title)ps.end_document() %!PS-Adobe-3.0 save /showpage { } def %%EndComments %%BeginDocument /S { show } bind def /P { moveto show } bind def /M { moveto } bind def /X { 0 rmoveto } bind def /Y { 0 exch rmoveto } bind def /E { findfont dup maxlength dict begin { 1 index /FID ne { def } { pop pop } ifelse } forall /Encoding exch def dup /FontName exch def currentdict end definefont pop } bind def /F { findfont exch scalefont dup setfont [ exch /setfont cvx ] cvx bind def } bind def /Vm { moveto } bind def /Va { newpath arcn stroke } bind def /Vl { moveto lineto stroke } bind def /Vc { newpath 0 360 arc closepath } bind def /Vr { exch dup 0 rlineto exch dup neg 0 exch rlineto exch neg 0 rlineto 0 exch rlineto 100 div setgray fill 0 setgray } bind def /Tm matrix def /Ve { Tm currentmatrix pop translate scale newpath 0 0 .5 0 360 arc closepath Tm setmatrix } bind def /Vf { currentgray exch setgray fill setgray } bind def %%EndProlog gsave 226.560000 370.560000 translate 0.960000 0.960000 scale gsave 10 dict begin /buf 384 string def 128 128 scale 128 128 8 [128 0 0 -128 0 128] { currentfile buf readhexstring pop } bind false 3 colorimage %%%%EndBinary grestore end grestore 72 144 M 504 720 0 Vr /PSDraw-HelveticaNarrow-Bold ISOLatin1Encoding /HelveticaNarrow-Bold E /F0 36 /PSDraw-HelveticaNarrow-Bold F 216 288 M (hopper) S %%EndDocument restore showpage %%End 9. 更多关于图像读取 123from PIL import Imageim = Image.open("hopper.ppm")plt.imshow(im) <matplotlib.image.AxesImage at 0x7f1171d5a400> png 1234from PIL import Imagewith open("hopper.ppm", "rb") as fp: im = Image.open(fp) plt.imshow(im) png 10. 控制解码器 使用草稿(draft)模式读取 12345im = Image.open("lena.jpg")print("original =", im.mode, im.size)im.draft("L", (100, 100))print("draft =", im.mode, im.size) original = RGB (512, 512) draft = L (128, 128) 12]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Focal Loss for Dense Object Detection]]></title>
<url>%2F2019%2F01%2F10%2FFocal-Loss%2F</url>
<content type="text"><![CDATA[本文代码:https://github.com/facebookresearch/Detectron 本文主要解决在one-stage的密集检测器中,大量前景和背景不平衡的问题。作者通过降低被很好分类样本的权重来解决类别不平衡的问题。Focal Loss集中于在稀疏难样本(hard examples)上的训练,并且在训练中防止大量的容易的反例(easy negatives)淹没检测器。 提出Focal Loss, 解决正负样本不平衡问题; 提出one-stage检测模型,RetinaNet。 作者提出一个新的损失函数 Focal Loss, 该方法通过添加因子\((1-p_t)^\gamma\)到标准的交叉熵损失函数。设定\(\gamma>0\)会减少被很好分类样本(\(p>0.5\))的相对损失,更加关注于难和错误分类的样本。 图中显示了,RetinaNet检测器使用了focal loss,结果由于之前的one-stage和two-stage检测器。 类别不平衡问题 在R-CNN这一类检测器中,类别不平衡问题通过two-stage级联和采样策略被解决。在候选区域提取阶段,Selective Search, EdgeBoxes, RPN等方法,缩小候选区域位置的数量到1~2k个,大量过滤掉了背景。在第二分类阶段,采样策略,例如固定前景背景比率(1:3),或者在线难样本挖掘(OHEM)方法被执行用于保持前景和背景的一个可控的平衡。 Focal Loss Focal Loss被设计用以解决one-state目标检测器训练中大量正反例样本不平衡的问题,通常是(1:1000)。我们首先介绍二值分类的交叉熵损失: \[ CE(p, y)=\begin{cases} -log(p) & y=1\\ -log(1-p) & otherwise. \end{cases} \] 3.1 Balanced Cross Entropy 一种通用的解决类别不平衡的方法是对类别1引入一个权重因子\(\alpha \in [0, 1]\),对类别class-1引入\(1-\alpha\)。我们写成\(\alpha-\)balanced CE loss: \[CE(p_t)=-\alpha_t log(p_t)\] 3.2 Focal Loss Definition 试验中显示,在训练dense detectors是遭遇的大量类别不平衡会压倒交叉熵损失。容易分类的样本会占损失的大部分,并且主导梯度。尽管\(\alpha\)平衡了正负(positive/negative)样本的重要性,但是它没有区分易和难的样本(easy/hard)。相反,作者提出的更改过后的损失函数降低了容易样本的权重并且集中训练难反例样本。 我们定义focal loss: \[FL(p_t)=-(1-p_t)^\gamma log(p_t)\] 3.4 Class Imbalance and Two-stage Detectors Two-stage检测器通常没有使用\(\alpha-\)balancing 或者我们提出的loss。代替这些,他们使用了两个机制来解决类别不平衡问题:(1) 一个两级的级联,(2) 有偏置的小批量采样。第一级联阶段的候选区域提取机制减少了大量可能的候选位置。重要的是,这些选择的候选框不是随机的,而是选择更像前景的可能位置,这样就移除了大量的容易的难反例样本(easy negatives)。第二阶段,有偏置的采样通常使用1:3比率的正负样本构建小批量(minibatches)。这个采样率类似\(\alpha-\)balancing因子,并且通过采样来实现。作者提出的focal loss主要设计用于解决one-stage检测系统中的这些问题。]]></content>
<categories>
<category>Object Detection</category>
</categories>
<tags>
<tag>Object Detection</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Docker 安装与使用]]></title>
<url>%2F2018%2F10%2F10%2Fdocker%2F</url>
<content type="text"><![CDATA[Docker 安装与使用 @(工具学习记录)[Docker] 1. Docker安装 参考官网教程 卸载旧的版本 1$ sudo apt-get remove docker docker-engine docker.iSET UP THE REPOSITORY SET UP THE REPOSITORY 1$ sudo apt-get update 12345$ sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ software-properties-common 1$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 123456$ sudo apt-key fingerprint 0EBFCD88pub 4096R/0EBFCD88 2017-02-22 Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88uid Docker Release (CE deb) <docker@docker.com>sub 4096R/F273FCD8 2017-02-22 x86_64/amd64 1234$ sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable" 安装 DOCKER CE 更新包的索引 1$ sudo apt-get update 安装最新版本的Docker CE 1$ sudo apt-get install docker-ce 安装特定版本Docker CE 123$ apt-cache madison docker-cedocker-ce | 18.03.0~ce-0~ubuntu | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages 验证是否安装正确 1$ sudo docker run hello-world 2.nvidia-docker 安装 参考nvidia-docker nstalling version 2.0 Debian-based distributions 123456curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \ sudo apt-key add -distribution=$(. /etc/os-release;echo $ID$VERSION_ID)curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \ sudo tee /etc/apt/sources.list.d/nvidia-docker.listsudo apt-get update 12sudo apt-get install nvidia-docker2sudo pkill -SIGHUP dockerd 3. detectron 配置 参考detectron install 12cd $DETECTRON/dockerdocker build -t detectron:c2-cuda9-cudnn7 . 运行这个镜像 1nvidia-docker run --rm -it detectron:c2-cuda9-cudnn7 python detectron/tests/test_batch_permutation_op.py 4. docker 基本命令 对容器生命周期管理 run docker run :创建一个新的容器并运行一个命令 12345678910111213141516使用docker镜像nginx:latest以后台模式启动一个容器,并将容器命名为mynginx。docker run --name mynginx -d nginx:latest使用镜像nginx:latest以后台模式启动一个容器,并将容器的80端口映射到主机随机端口。docker run -P -d nginx:latest使用镜像 nginx:latest,以后台模式启动一个容器,将容器的 80 端口映射到主机的 80 端口,主机的目录 /data 映射到容器的 /data。docker run -p 80:80 -v /data:/data -d nginx:latest绑定容器的 8080 端口,并将其映射到本地主机 127.0.0.1 的 80 端口上。$ docker run -p 127.0.0.1:80:8080/tcp ubuntu bash使用镜像nginx:latest以交互模式启动一个容器,在容器内执行/bin/bash命令。runoob@runoob:~$ docker run -it nginx:latest /bin/bashroot@b8573233d675:/# start/stop/restart kill rm docker rm :删除一个或多少容器 语法 1docker rm [OPTIONS] CONTAINER [CONTAINER...] OPTIONS说明: -f :通过SIGKILL信号强制删除一个运行中的容器 -l :移除容器间的网络连接,而非容器本身 -v :-v 删除与容器关联的卷docker rm :删除一个或多少容器 语法 docker rm [OPTIONS] CONTAINER [CONTAINER...] OPTIONS说明: -f :通过SIGKILL信号强制删除一个运行中的容器 -l :移除容器间的网络连接,而非容器本身 -v :-v 删除与容器关联的卷 123456789强制删除容器db01、db02docker rm -f db01 db02移除容器nginx01对容器db01的连接,连接名dbdocker rm -l db 删除容器nginx01,并删除容器挂载的数据卷docker rm -v nginx01 pause/unpause create exec docker exec :在运行的容器中执行命令 12345678在容器mynginx中以交互模式执行容器内/root/runoob.sh脚本runoob@runoob:~$ docker exec -it mynginx /bin/sh /root/runoob.shhttp://www.runoob.com/在容器mynginx中开启一个交互模式的终端runoob@runoob:~$ docker exec -i -t mynginx /bin/bashroot@b1a0703e41e7:/# commit 命令 docker commit :从容器创建一个新的镜像。 - -a :提交的镜像作者; - -c :使用Dockerfile指令来创建镜像; - -m :提交时的说明文字; - -p :在commit时,将容器暂停。 将容器a404c6c174a2 保存为新的镜像,并添加提交人信息和说明信息。 12345runoob@runoob:~$ docker commit -a "runoob.com" -m "my apache" a404c6c174a2 mymysql:v1 sha256:37af1236adef1544e8886be23010b66577647a40bc02c0885a6600b33ee28057runoob@runoob:~$ docker images mymysql:v1REPOSITORY TAG IMAGE ID CREATED SIZEmymysql v1 37af1236adef 15 seconds ago 329 MB 容器与本地之间拷贝文件 12345将主机./RS-MapReduce目录拷贝到容器30026605dcfe的/home/cloudera目录下。docker cp RS-MapReduce 30026605dcfe:/home/cloudera将容器30026605dcfe的/home/cloudera/RS-MapReduce目录拷贝到主机的/tmp目录中。docker cp 30026605dcfe:/home/cloudera/RS-MapReduce /tmp/ 5. 学习资源 runoob docker 只要一小时,零基础入门Docker]]></content>
<tags>
<tag>docker</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Conda使用指南]]></title>
<url>%2F2018%2F09%2F09%2FConda-Tutorials%2F</url>
<content type="text"><![CDATA[Python渐渐成为最流行的编程语言之一,在数据分析、机器学习和深度学习等方向Python语言更是主流。Python的版本比较多,并且它的库也非常广泛,同时库和库之间存在很多依赖关系,所以在库的安装和版本的管理上很麻烦。Conda是一个管理版本和Python环境的工具,它使用起来非常容易。 首先你需要安装Anconda软件,点击链接download。选择对应的系统和版本类型。 Conda的环境管理 创建环境 12# 创建一个名为python34的环境,指定Python版本是3.5(不用管是3.5.x,conda会为我们自动寻找3.5.x中的最新版本)conda create --name py35 python=3.5 激活环境 123456789# 安装好后,使用activate激活某个环境activate py35 # for Windowssource activate py35 # for Linux & Mac(py35) user@user-XPS-8920:~$ # 激活后,会发现terminal输入的地方多了py35的字样,实际上,此时系统做的事情就是把默认2.7环境从PATH中去除,再把3.4对应的命令加入PATH (py35) user@user-XPS-8920:~$ python --versionPython 3.5.5 :: Anaconda, Inc.# 可以得到`Python 3.5.5 :: Anaconda, Inc.`,即系统已经切换到了3.5的环境 返回主环境 123# 如果想返回默认的python 2.7环境,运行deactivate py35 # for Windowssource deactivate py35 # for Linux & Mac 删除环境 12# 删除一个已有的环境conda remove --name py35 --all 查看系统中的所有环境 用户安装的不同Python环境会放在~/anaconda/envs目录下。查看当前系统中已经安装了哪些环境,使用conda info -e。 1234567user@user-XPS-8920:~$ conda info -e# conda environments:#base * /home/user/anaconda2caffe /home/user/anaconda2/envs/caffepy35 /home/user/anaconda2/envs/py35tf /home/user/anaconda2/envs/tf Conda的包管理 安装库 为当前环境安装库 123# numpyconda install numpy# conda会从从远程搜索numpy的相关信息和依赖项目 ### 查看已经安装的库 123# 查看已经安装的packagesconda list# 最新版的conda是从site-packages文件夹中搜索已经安装的包,可以显示出通过各种方式安装的包 查看某个环境的已安装包 12# 查看某个指定环境的已安装包conda list -n py35 搜索package的信息 12# 查找package信息conda search numpy 12345678Loading channels: done# Name Version Build Channel numpy 1.5.1 py26_1 pkgs/free ...numpy 1.15.1 py37hec00662_0 anaconda/pkgs/main numpy 1.15.1 py37hec00662_0 pkgs/main 安装package到指定的环境 1234# 安装packageconda install -n py35 numpy# 如果不用-n指定环境名称,则被安装在当前活跃环境# 也可以通过-c指定通过某个channel安装 更新package 12# 更新packageconda update -n py35 numpy 删除package 12# 删除packageconda remove -n py35 numpy 更新conda 12# 更新conda,保持conda最新conda update conda 更新anaconda 12# 更新anacondaconda update anaconda 更新Python 123# 更新pythonconda update python# 假设当前环境是python 3.5, conda会将python升级为3.5.x系列的当前最新版本 设置国内镜像 因为Anaconda.org的服务器在国外,所有有些库下载缓慢,可以使用清华Anaconda镜像源。 网站地址: 清华大学开源软件镜像站 Anaconda 镜像 Anaconda 安装包可以到 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 下载。 TUNA还提供了Anaconda仓库的镜像,运行以下命令: 123conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/conda config --set show_channel_urls yes 即可添加 Anaconda Python 免费仓库。 运行 conda install numpy 测试一下吧。 Miniconda 镜像 Miniconda 是一个 Anaconda 的轻量级替代,默认只包含了 python 和 conda,但是可以通过 pip 和 conda 来安装所需要的包。 Miniconda 安装包可以到 https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/ 下载。]]></content>
<categories>
<category>Python</category>
</categories>
</entry>
<entry>
<title><![CDATA[[MLIA] Logistic Regression]]></title>
<url>%2F2018%2F09%2F05%2FMLIA-Logistic-Regression%2F</url>
<content type="text"><![CDATA[Logistic Regression 本代码来自Machine Learning in Action。 想要了解更多的朋友可以参考此书。 Sigmoid函数 \[\sigma(z) = \frac{1}{(1+e^{-z})}\] 12345678910import numpy as npimport matplotlib.pyplot as pltdef sigmoid(inX): return 1.0/(1+np.exp(-inX))z = np.linspace(-5, 5, 100)y = sigmoid(z)plt.plot(z, y)plt.show() png 1234z = np.linspace(-60, 60, 100)y = sigmoid(z)plt.plot(z, y)plt.show() png Sigmoid函数类似一个单位阶跃函数。当x=0时,Sigmoid函数值为0.5;随着x增大,Sigmoid函数值将逼近于1;随着x减小,Sigmoid函数将逼近于0。利用这个性质可以对它的输入做一个二分类。 为了实现Logistic回归分类器,我们可以在每个特征上都乘以一个回归系数,然后把它的所有的结果值相加,将这个总和带入Sigmoid函数中,进而得到一个范围在0~1之间是数值。当大于0.5的时候,将数据分类为1;当小于0.5的时候,将数据分类为0。 Sigmoid函数的输入记为z: \[z=w_0x_0 + w_1x_1 + w_2x_2 + \cdot \cdot \cdot + w_n x_n\] Sigmoid函数的导数 Sigmoid导数具体推导过程如下: \[ \begin{align} f^{\prime}(z) &= (\frac{1}{1+e^{-z}})^{\prime}\\\ &=\frac{e^{-z}}{(1+e^{-z})^2}\\\ &=\frac{1+e^{-z}-1}{(1+e^{-z})^2}\\\ &=\frac{1}{(1+e^{-z})}(1-\frac{1}{(1+e^{-z})})\\\ &=f(z)(1-f(z)) \end{align} \] 梯度上升法 梯度上升法:顾名思义就是利用梯度方向,寻找到某函数的最大值。 梯度上升算法迭代公式: \[w:=w+\alpha \nabla_w f(w)\] 梯度下降法:和梯度上升想法,利用梯度方法,寻找某个函数的最小值。 梯度下降算法迭代公式: \[w:=w-\alpha \nabla_w f(w)\] 梯度上升算法每次更新之后,都会重新估计移动的方法,即梯度。 Logistic 回归梯度上升优化法 加载数据 12345678def loadDataSet(): dataMat = []; labelMat = [] fr = open('testSet.txt') for line in fr.readlines(): lineArr = line.strip().split() dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) labelMat.append(int(lineArr[2])) return dataMat,labelMat 12345dataArray, labelMat = loadDataSet()print("Total: ", len(dataArray))print("The first sample: ", dataArray[0])print("The second sample: ", dataArray[1])print("Label: ", labelMat) ('Total: ', 100) ('The first sample: ', [1.0, -0.017612, 14.053064]) ('The second sample: ', [1.0, -1.395634, 4.662541]) ('Label: ', [0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0]) 数据集梯度上升 123456789101112131415def sigmoid(inX): return 1.0/(1+np.exp(-inX))def gradAscent(dataMatIn, classLabels): dataMatrix = np.mat(dataMatIn) #convert to NumPy matrix labelMat = np.mat(classLabels).transpose() #convert to NumPy matrix m,n = np.shape(dataMatrix) alpha = 0.001 maxCycles = 500 weights = np.ones((n,1)) for k in range(maxCycles): #heavy on matrix operations h = sigmoid(dataMatrix*weights) #matrix mult error = (labelMat - h) #vector subtraction weights = weights + alpha * dataMatrix.transpose()* error #matrix mult return weights 1gradAscent(dataArray, labelMat) matrix([[ 4.12414349], [ 0.48007329], [-0.6168482 ]]) 绘制数据和决策边界 123456789101112131415161718192021def plotBestFit(weights): import matplotlib.pyplot as plt dataMat,labelMat=loadDataSet() dataArr = np.array(dataMat) n = np.shape(dataArr)[0] xcord1 = []; ycord1 = [] xcord2 = []; ycord2 = [] for i in range(n): if int(labelMat[i])== 1: xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2]) else: xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2]) fig = plt.figure() ax = fig.add_subplot(111) ax.scatter(xcord1, ycord1, s=30, c='red', marker='s') ax.scatter(xcord2, ycord2, s=30, c='green') x = np.arange(-3.0, 3.0, 0.1) y = (-weights[0]-weights[1]*x)/weights[2] ax.plot(x, y) plt.xlabel('X1'); plt.ylabel('X2'); plt.show() 12weights = gradAscent(dataArray, labelMat)plotBestFit(weights.getA()) png 1个epoch的随机梯度上升 梯度上升算法在每次更新系数的时候都需要便利整个数据集,如果数据集的样本比较大,该方法的复杂度和计算代价就很高。有一种改进的方法叫做随机梯度上升方法。该方法的思想是选取一个样本,计算该样本的梯度,更新系数,再选取下一个样本。 123456789def stocGradAscent0(dataMatrix, classLabels): m,n = np.shape(dataMatrix) alpha = 0.01 weights = np.ones(n) #initialize to all ones for i in range(m): h = sigmoid(sum(dataMatrix[i]*weights)) error = classLabels[i] - h weights = weights + alpha * error * dataMatrix[i] return weights 12weights = stocGradAscent0(np.array(dataArray), labelMat)plotBestFit(weights) png 上图之后遍历了一次数据集,这样的模型还处于欠拟合状态。需要多次遍历数据集才能优化好模型,接下来我们会运行200次迭代。 200个epoch的随机梯度上升 1234567891011121314def stocGradAscent0(dataMatrix, classLabels): X0, X1, X2 = [], [], [] m,n = np.shape(dataMatrix) alpha = 0.01 weights = np.ones(n) #initialize to all ones for j in range(200): for i in range(m): h = sigmoid(sum(dataMatrix[i]*weights)) error = classLabels[i] - h weights = weights + alpha * error * dataMatrix[i] X0.append(weights[0]) X1.append(weights[1]) X2.append(weights[2]) return weights, X0, X1, X2 12weights, X0, X1, X2 = stocGradAscent0(np.array(dataArray), labelMat)plotBestFit(weights) png 可视化权重(weights)的变化 12345fig, ax = plt.subplots(3, 1, figsize=(10, 5))ax[0].plot(np.arange(len(X0)), np.array(X0))ax[1].plot(np.arange(len(X1)), np.array(X1))ax[2].plot(np.arange(len(X2)), np.array(X2))plt.show() png 从上图可以看出,算法正在逐渐收敛。由于数据集并不是线性可分的,所以存在一些不能正确分类的样本点,每次更新权重引起了周期的变化。 更新过后的随机梯度上升算法 学习率alpha会在每次迭代之后调整。 采用随机选取样本的更新策略,减少周期性的波动。 1234567891011121314151617def stocGradAscent1(dataMatrix, classLabels, numIter=150): X0, X1, X2 = [], [], [] m,n = np.shape(dataMatrix) weights = np.ones(n) #initialize to all ones for j in range(numIter): dataIndex = range(m) for i in range(m): alpha = 4/(1.0+j+i)+0.0001 #apha decreases with iteration, does not randIndex = int(np.random.uniform(0,len(dataIndex)))#go to 0 because of the constant h = sigmoid(sum(dataMatrix[randIndex]*weights)) error = classLabels[randIndex] - h weights = weights + alpha * error * dataMatrix[randIndex] X0.append(weights[0]) X1.append(weights[1]) X2.append(weights[2]) del(dataIndex[randIndex]) return weights, X0, X1, X2 12weights, X0, X1, X2 = stocGradAscent1(np.array(dataArray), labelMat)plotBestFit(weights) png 可视化权重(weights)的变化 12345fig, ax = plt.subplots(3, 1, figsize=(10, 5))ax[0].plot(np.arange(len(X0)), np.array(X0))ax[1].plot(np.arange(len(X1)), np.array(X1))ax[2].plot(np.arange(len(X2)), np.array(X2))plt.show() png 示例:从疝气病症预测病马的死亡率 12345678910111213141516171819202122232425262728293031323334def classifyVector(inX, weights): prob = sigmoid(sum(inX*weights)) if prob > 0.5: return 1.0 else: return 0.0def colicTest(): frTrain = open('horseColicTraining.txt', 'r'); frTest = open('horseColicTest.txt', 'r') trainingSet = []; trainingLabels = [] for line in frTrain.readlines(): currLine = line.strip().split('\t') lineArr =[] for i in range(21): lineArr.append(float(currLine[i])) trainingSet.append(lineArr) trainingLabels.append(float(currLine[21])) trainWeights, X0, X1, X2 = stocGradAscent1(np.array(trainingSet), trainingLabels, 1000) errorCount = 0; numTestVec = 0.0 for line in frTest.readlines(): numTestVec += 1.0 currLine = line.strip().split('\t') lineArr =[] for i in range(21): lineArr.append(float(currLine[i])) if int(classifyVector(np.array(lineArr), trainWeights))!= int(currLine[21]): errorCount += 1 errorRate = (float(errorCount)/numTestVec) print "the error rate of this test is: %f" % errorRate return errorRatedef multiTest(): numTests = 10; errorSum=0.0 for k in range(numTests): errorSum += colicTest() print "after %d iterations the average error rate is: %f" % (numTests, errorSum/float(numTests)) 1multiTest() /home/tianliang/anaconda2/lib/python2.7/site-packages/ipykernel_launcher.py:2: RuntimeWarning: overflow encountered in exp the error rate of this test is: 0.328358 the error rate of this test is: 0.432836 the error rate of this test is: 0.388060 the error rate of this test is: 0.373134 the error rate of this test is: 0.373134 the error rate of this test is: 0.447761 the error rate of this test is: 0.343284 the error rate of this test is: 0.313433 the error rate of this test is: 0.328358 the error rate of this test is: 0.462687 after 10 iterations the average error rate is: 0.379104]]></content>
<categories>
<category>Machine Learning</category>
</categories>
</entry>
<entry>
<title><![CDATA[CornerNet: Detection Objects as Paired Keypoints]]></title>
<url>%2F2018%2F09%2F02%2FCornerNet-Detection-Objects-as-Paired-Keypoints%2F</url>
<content type="text"><![CDATA[前言 CornerNet: Detection Objects as Paired Keypoints 这篇论文发表在ECCV2018,本人感觉非常有意思,所以和大家分享一下。 Arxiv: https://arxiv.org/abs/1808.01244 Github: https://github.com/umich-vl/]]></content>
<categories>
<category>Object Detection</category>
</categories>
<tags>
<tag>Object Detection</tag>
</tags>
</entry>
<entry>
<title><![CDATA[行人检测(Pedestrian Detection)论文整理]]></title>
<url>%2F2018%2F08%2F17%2FPedestrian-Detection-Sources%2F</url>
<content type="text"><![CDATA[同步github地址 本文档同步至github:here 相关科研工作者 Piotr Dollár scholar Piotr Dollár homepage 张姗姗 scholar 张姗姗 homepage 欧阳万里 scholar 欧阳万里 homepage Liu Wei homepage 开放的代码 Leotju/MGAN [ICCV-2019] Mask-Guided Attention Network for Occluded Pedestrian Detection [paper] lw396285v/CSP-pedestrian-detection-in-pytorch 非官方实现 [CVPR-2019] High-level Semantic Feature Detection:A New Perspective for Pedestrian Detection [paper] liuwei16/CSP [CVPR-2019] High-level Semantic Feature Detection:A New Perspective for Pedestrian Detection [paper] liuwei16/ALFNet [ECCV-2018] Learning Efficient Single-stage Pedestrian Detectors by Asymptotic Localization Fitting rainofmine/Bi-box_Regression 非官方实现 [ECCV-2018] Bi-box Regression for Pedestrian Detection and Occlusion Estimation rainofmine/Repulsion_Loss 非官方实现 [CVPR-2018] Repulsion Loss: Detecting Pedestrians in a Crowd garrickbrazil/SDS-RCNN [ICCV-2017] Illuminating Pedestrians via Simultaneous Detection & Segmentation zhangliliang/RPN_BF [ECCV-2016] Is Faster R-CNN Doing Well for Pedestrian Detection? Paper List [ICCV-2019] Semi-Supervised Pedestrian Instance Synthesis and Detection With Mutual Reinforcement [paper] [ICCV-2019] Weakly Aligned Cross-Modal Learning for Multispectral Pedestrian Detection [paper] [ICCV-2019] Discriminative Feature Transformation for Occluded Pedestrian Detection [paper] [ICCV-2019] Mask-Guided Attention Network for Occluded Pedestrian Detection [paper] [code] [TPAMI-2019] EuroCity Persons: A Novel Benchmark for Person Detection in Traffic Scenes [paper] [CVPR-2019 oral] Adaptive NMS: Refining Pedestrian Detection in a Crowd [paper] [CVPR-2019] High-level Semantic Feature Detection:A New Perspective for Pedestrian Detection [paper] [code] [CVPR-2019] SSA-CNN: Semantic Self-Attention CNN for Pedestrian Detection [CVPR-2019] Pedestrian Detection in Thermal Images using Saliency Maps [TIP-2018] Too Far to See? Not Really:- Pedestrian Detection with Scale-Aware Localization Policy [ECCV-2018] Bi-box Regression for Pedestrian Detection and Occlusion Estimation [code] [ECCV-2018] Learning Efficient Single-stage Pedestrian Detectors by Asymptotic Localization Fitting [code] [ECCV-2018] Graininess-Aware Deep Feature Learning for Pedestrian Detection [ECCV-2018] Occlusion-aware R-CNN: Detecting Pedestrians in a Crowd [ECCV-2018] Small-scale Pedestrian Detection Based on Somatic Topology Localization and Temporal Feature Aggregation [CVPR-2018] Improving Occlusion and Hard Negative Handling for Single-Stage Pedestrian Detectors [CVPR-2018] Occluded Pedestrian Detection Through Guided Attention in CNNs [CVPR-2018] Repulsion Loss: Detecting Pedestrians in a Crowd [code] [TCSVT-2018] Pushing the Limits of Deep CNNs for Pedestrian Detection [Trans Multimedia-2018] Scale-aware Fast R-CNN for Pedestrian Detection [TPAMI-2017] Jointly Learning Deep Features, Deformable Parts, Occlusion and Classification for Pedestrian Detection [BMVC-2017] PCN: Part and Context Information for Pedestrian Detection with CNNs [CVPR-2017] CityPersons: A Diverse Dataset for Pedestrian Detection [CVPR-2017] Learning Cross-Modal Deep Representations for Robust Pedestrian Detection [CVPR-2017] What Can Help Pedestrian Detection? [ICCV-2017] Multi-label Learning of Part Detectors for Heavily Occluded Pedestrian Detection [ICCV-2017] Illuminating Pedestrians via Simultaneous Detection & Segmentation [code] [TPAMI-2017] Towards Reaching Human Performance in Pedestrian Detection [Transactions on Multimedia-2017] Scale-Aware Fast R-CNN for Pedestrian Detection [CVPR-2016] Semantic Channels for Fast Pedestrian Detection [CVPR-2016] How Far are We from Solving Pedestrian Detection? [CVPR-2016] Pedestrian Detection Inspired by Appearance Constancy and Shape Symmetry [CVPR-2016] Semantic Channels for Fast Pedestrian Detection [ECCV-2016] Is Faster R-CNN Doing Well for Pedestrian Detection? [code] [CVPR-2015] Taking a Deeper Look at Pedestrians [ICCV-2015] Learning Complexity-Aware Cascades for Deep Pedestrian Detection [ICCV-2015] Deep Learning Strong Parts for Pedestrian Detection [ECCV-2014] Deep Learning of Scene-specific Classifier for Pedestrian Detection [CVPR-2013] Joint Deep Learning for Pedestrian Detection [CVPR-2012] A Discriminative Deep Model for Pedestrian Detection with Occlusion Handling [CVPR-2010] Multi-Cue Pedestrian Classification With Partial Occlusion Handling [CVPR-2009] Pedestrian detection: A benchmark [CVPR-2008] People-Tracking-by-Detection and People-Detection-by-Tracking [ECCV-2006] Human Detection Using Oriented Histograms of Flow and Appearance [CVPR-2005] Histograms of Oriented Gradients for Human Detection 论文 [CVPR-2019 oral] Adaptive NMS: Refining Pedestrian Detection in a Crowd - paper: https://arxiv.org/abs/1904.02948 [CVPR-2019] High-level Semantic Feature Detection:A New Perspective for Pedestrian Detection - paper: https://arxiv.org/abs/1904.02948 - github: https://github.com/liuwei16/CSP [CVPR-2019] SSA-CNN: Semantic Self-Attention CNN for Pedestrian Detection - paper: https://arxiv.org/abs/1902.09080v1 [CVPR-2019] Pedestrian Detection in Thermal Images using Saliency Maps paper: https://arxiv.org/abs/1904.06859 [TIP-2018] Too Far to See? Not Really: Pedestrian Detection with Scale-Aware Localization Policy - paper: - project website: - slides: - github: [Transactions on Multimedia-2018] Scale-Aware Fast R-CNN for Pedestrian Detection Alt text| left | 300x0 paper: https://ieeexplore.ieee.org/abstract/document/8060595/ project website: slides: github: [ECCV-2018] Bi-box Regression for Pedestrian Detection and Occlusion Estimation arxiv: paper:http://openaccess.thecvf.com/content_ECCV_2018/papers/CHUNLUAN_ZHOU_Bi-box_Regression_for_ECCV_2018_paper.pdf slides: github: https://github.com/rainofmine/Bi-box_Regression [ECCV-2018] Learning Efficient Single-stage Pedestrian Detectors by Asymptotic Localization Fitting Alt text| left | 300x0 arxiv: paper:http://openaccess.thecvf.com/content_ECCV_2018/papers/Wei_Liu_Learning_Efficient_Single-stage_ECCV_2018_paper.pdf project website: slides: github: https://github.com/liuwei16/ALFNet [ECCV-2018] Graininess-Aware Deep Feature Learning for Pedestrian Detection Alt text| left | 300x0 arxiv: paper:http://openaccess.thecvf.com/content_ECCV_2018/papers/Chunze_Lin_Graininess-Aware_Deep_Feature_ECCV_2018_paper.pdf project website: slides: github: [ECCV-2018] Occlusion-aware R-CNN: Detecting Pedestrians in a Crowd Alt text| left | 300x0 arxiv:http://arxiv.org/abs/1807.08407 project website: slides: github: [ECCV-2018] Small-scale Pedestrian Detection Based on Somatic Topology Localization and Temporal Feature Aggregation Alt text| left | 300x0 arxiv:https://arxiv.org/abs/1807.01438 project website: slides: github: [CVPR-2018] Improving Occlusion and Hard Negative Handling for Single-Stage Pedestrian Detectors Alt text| left | 300x0 arxiv: paper: http://vision.snu.ac.kr/projects/partgridnet/data/noh_2018.pdf project website: http://vision.snu.ac.kr/projects/partgridnet/ slides: github: [CVPR-2018] Occluded Pedestrian Detection Through Guided Attention in CNNs Alt text| left | 300x0 arxiv: paper: http://openaccess.thecvf.com/content_cvpr_2018/papers/Zhang_Occluded_Pedestrian_Detection_CVPR_2018_paper.pdf project website: slides: github: [CVPR-2018] Repulsion Loss: Detecting Pedestrians in a Crowd Alt text| left | 300x0 arxiv:http://arxiv.org/abs/1711.07752 project website: slides: github: blog: https://zhuanlan.zhihu.com/p/41288115 [TPAMI-2017] Jointly Learning Deep Features, Deformable Parts, Occlusion and Classification for Pedestrian Detection Alt text| left | 300x0 paper: https://ieeexplore.ieee.org/abstract/document/8008790/ project website: slides: github caffe: [BMVC-2017] PCN: Part and Context Information for Pedestrian Detection with CNNs Alt text| left | 300x0 arxiv: https://arxiv.org/abs/1804.044838 project website: slides: github caffe: [CVPR-2017] CityPersons: A Diverse Dataset for Pedestrian Detection Alt text| left | 300x0 arxiv: http://arxiv.org/abs/1702.05693 project website: slides: github caffe: [CVPR-2017] Learning Cross-Modal Deep Representations for Robust Pedestrian Detection Alt text| left | 300x0 arxiv: https://arxiv.org/abs/1704.02431 project website: slides: github caffe: [CVPR-2017] What Can Help Pedestrian Detection? arxiv: https://arxiv.org/abs/1704.02431 project website: slides: github caffe: [TPAMI-2017] Towards Reaching Human Performance in Pedestrian Detection paper: http://ieeexplore.ieee.org/document/7917260/ arxiv: project website: slides: github caffe: [ICCV-2017] Multi-label Learning of Part Detectors for Heavily Occluded Pedestrian Detection paper: http://openaccess.thecvf.com/content_ICCV_2017/papers/Zhou_Multi-Label_Learning_of_ICCV_2017_paper.pdf arxiv: project website: slides: [ICCV-2017]Illuminating Pedestrians via Simultaneous Detection & Segmentation Alt text| left | 300x0 arxiv: https://arxiv.org/abs/1706.08564 project website: http://cvlab.cse.msu.edu/project-pedestrian-detection.html slides: github caffe: https://github.com/garrickbrazil/SDS-RCNN [CVPR-2016] Semantic Channels for Fast Pedestrian Detection Alt text| left | 300x0 paper: https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Costea_Semantic_Channels_for_CVPR_2016_paper.pdf project website: slides: github caffe: [CVPR-2016] How Far areWe from Solving Pedestrian Detection? paper: https://www.cv-foundation.org/openaccess/content_cvpr_2016/app/S06-29.pdf project website: slides: github caffe: [ICCV-2015] Deep Learning Strong Parts for Pedestrian Detection Alt text| left | 300x0 paper: https://www.cv-foundation.org/openaccess/content_iccv_2015/html/Tian_Deep_Learning_Strong_ICCV_2015_paper.htmler.html project website: slides: github caffe: [CVPR-2013] Joint Deep Learning for Pedestrian Detection Wanli Alt text| left | 300x0 paper: https://www.cv-foundation.org/openaccess/content_iccv_2013/html/Ouyang_Joint_Deep_Learning_2013_ICCV_paper.html project website: slides: github caffe: [CVPR-2012] A Discriminative Deep Model for Pedestrian Detection with Occlusion Handling Alt text| left | 300x0 paper: http://mmlab.ie.cuhk.edu.hk/pdf/ouyangWcvpr2012.pdf paper: https://ieeexplore.ieee.org/abstract/document/6248062/ project website: slides: github caffe: [CVPR-2010] Multi-Cue Pedestrian Classification With Partial Occlusion Handling Alt text| left | 300x0 paper: https://ieeexplore.ieee.org/abstract/document/5540111/ project website: slides: github caffe: 行人检测数据集 CityPersons Alt text CityPersons数据集是在Cityscapes数据集基础上建立的,使用了Cityscapes数据集的数据,对一些类别进行了精确的标注。该数据集是在[CVPR-2017] CityPersons: A Diverse Dataset for Pedestrian Detection这篇论文中提出的,更多细节可以通过阅读该论文了解。 上图中左侧是行人标注,右侧是原始的CityScapes数据集。 标注和评估文件 数据集下载 文件格式 123456789101112131415#评测文件$/Cityscapes/shanshanzhang-citypersons/evaluation/eval_script/coco.py$/Cityscapes/shanshanzhang-citypersons/evaluation/eval_script/eval_demo.py$/Cityscapes/shanshanzhang-citypersons/evaluation/eval_script/eval_MR_multisetup.py#注释文件$/Cityscapes/shanshanzhang-citypersons/annotations$/Cityscapes/shanshanzhang-citypersons/annotations/anno_train.mat$/Cityscapes/shanshanzhang-citypersons/annotations/anno_val.mat$/Cityscapes/shanshanzhang-citypersons/annotations/README.txt#图片数据$/Cityscapes/leftImg8bit/train/*$/Cityscapes/leftImg8bit/val/*$/Cityscapes/leftImg8bit/test/* 注释文件格式 123456789101112131415161718192021222324CityPersons annotations(1) data structure: one image per cell in each cell, there are three fields: city_name; im_name; bbs (bounding box annotations)(2) bounding box annotation format: one object instance per row: [class_label, x1,y1,w,h, instance_id, x1_vis, y1_vis, w_vis, h_vis](3) class label definition: class_label =0: ignore regions (fake humans, e.g. people on posters, reflections etc.) class_label =1: pedestrians class_label =2: riders class_label =3: sitting persons class_label =4: other persons with unusual postures class_label =5: group of people(4) boxes: visible boxes [x1_vis, y1_vis, w_vis, h_vis] are automatically generated from segmentation masks; (x1,y1) is the upper left corner. if class_label==1 or 2 [x1,y1,w,h] is a well-aligned bounding box to the full body ; else [x1,y1,w,h] = [x1_vis, y1_vis, w_vis, h_vis]; Caltech caltech Caltech官网 更所细节请阅读这篇论文, [TAPAMI-2012] Pedestrian Detection: An Evaluation of the State of the Art Alt text KITTI Alt text KITTI官网 EuroCity EuroCity 官网 EuroCity Paper [TPAMI-2019] EuroCity Persons: A Novel Benchmark for Person Detection in Traffic Scenes With over 238200 person instances manually labeled in over 47300 images, EuroCity Persons is nearly one order of magnitude larger than person datasets used previously for benchmarking. Diversity is gained by recording this dataset throughout Europe. EuroCity-01 EuroCity-02 Object Class # objects (day) # objects (night) # objects (sum) Pedestrian 183004 35309 218313 Rider 18216 1564 19780 CrowdHuman CrowdHuman 主页 CrowdHuman Paper CrowdHuman-20190918-01 CrowdHuman-20190918-02 CrowdHuman-20190918-03 性能比较 数据来自 CityPersons 官网。 Method MR (Reasonable) MR (Reasonable_small) MR (Reasonable_occ=heavy) MR (All) YT-PedDet 8.41% 10.60% 37.88% 37.22% STNet 9.78% 10.95% 36.16% 31.36% DVRNet 10.99% 15.68% 43.77% 41.48% HBA-RCNN 11.06% 14.77% 43.61% 39.54% OR-CNN 11.32% 14.19% 51.43% 40.19% Repultion Loss 11.48% 15.67% 52.59% 39.17% Adapted FasterRCNN 12.97% 37.24% 50.47% 43.86% MS-CNN 13.32% 15.86% 51.88% 39.94%]]></content>
<categories>
<category>Pedestrian Detection</category>
</categories>
<tags>
<tag>Pedestrian Detection</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Keras Tutorial]]></title>
<url>%2F2018%2F08%2F14%2FKeras-Tutorial%2F</url>
<content type="text"><![CDATA[Github地址:here Keras-Tutorials 版本:0.0.1 作者:张天亮 邮箱:zhangtianliang13@mails.ucas.ac.cn Github 加载 .ipynb 的速度较慢,建议在 Nbviewer 中查看该项目。 简介 大部分内容来自keras项目中的examples 目录 01.多层感知机实现 02.模型的保存 03.模型的加载 04.绘制精度和损失曲线 05.卷积神经网络实现 06.CIFAR10_cnn 07.mnist_lstm 08.VGG16调用 09.卷积滤波器可视化 10.variational_autoencoder 11.锁定层fine-tuning网络 12.使用sklearn wrapper进行的参数搜索 13.Keras和Tensorflow联合使用 14.Finetune InceptionV3样例 15.自编码器 16.卷积自编码器 更多Keras使用方法请查看手册 - 中文手册 - 英文手册 - github]]></content>
<categories>
<category>Deep Learning</category>
</categories>
<tags>
<tag>Keras</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Generative Adversarial Nets]]></title>
<url>%2F2018%2F08%2F14%2FGenerative-Adversarial-Nets%2F</url>
<content type="text"><![CDATA[DCGANs in TensorFlow carpedm20/DCGAN-tensorflow 我们定义网络结构: 123456789101112131415161718192021222324252627282930313233343536def generator(self, z): self.z_, self.h0_w, self.h0_b = linear(z, self.gf_dim*8*4*4, 'g_h0_lin', with_w=True) self.h0 = tf.reshape(self.z_, [-1, 4, 4, self.gf_dim * 8]) h0 = tf.nn.relu(self.g_bn0(self.h0)) self.h1, self.h1_w, self.h1_b = conv2d_transpose(h0, [self.batch_size, 8, 8, self.gf_dim*4], name='g_h1', with_w=True) h1 = tf.nn.relu(self.g_bn1(self.h1)) h2, self.h2_w, self.h2_b = conv2d_transpose(h1, [self.batch_size, 16, 16, self.gf_dim*2], name='g_h2', with_w=True) h2 = tf.nn.relu(self.g_bn2(h2)) h3, self.h3_w, self.h3_b = conv2d_transpose(h2, [self.batch_size, 32, 32, self.gf_dim*1], name='g_h3', with_w=True) h3 = tf.nn.relu(self.g_bn3(h3)) h4, self.h4_w, self.h4_b = conv2d_transpose(h3, [self.batch_size, 64, 64, 3], name='g_h4', with_w=True) return tf.nn.tanh(h4)def discriminator(self, image, reuse=False): if reuse: tf.get_variable_scope().reuse_variables() h0 = lrelu(conv2d(image, self.df_dim, name='d_h0_conv')) h1 = lrelu(self.d_bn1(conv2d(h0, self.df_dim*2, name='d_h1_conv'))) h2 = lrelu(self.d_bn2(conv2d(h1, self.df_dim*4, name='d_h2_conv'))) h3 = lrelu(self.d_bn3(conv2d(h2, self.df_dim*8, name='d_h3_conv'))) h4 = linear(tf.reshape(h3, [-1, 8192]), 1, 'd_h3_lin') return tf.nn.sigmoid(h4), h4 当我们初始化这个类时,我们将使用这些函数来创建模型。 我们需要两个版本的鉴别器共享(或重用)参数。 一个用于来自数据分布的图像的minibatch,另一个用于来自发生器的图像的minibatch。 123self.G = self.generator(self.z)self.D, self.D_logits = self.discriminator(self.images)self.D_, self.D_logits_ = self.discriminator(self.G, reuse=True) 接下来我们定义损失函数。我们在D的预测值和我们理想的判别器输出值之间使用交叉熵,而没有只用求和,因为这样的效果更好。判别器希望对“真实”数据的预测全部是1,并且来自生成器的“假”数据的预测全部是零。生成器希望判别器对所有假样本的预测都是1。 1234567891011self.d_loss_real = tf.reduce_mean( tf.nn.sigmoid_cross_entropy_with_logits(self.D_logits, tf.ones_like(self.D)))self.d_loss_fake = tf.reduce_mean( tf.nn.sigmoid_cross_entropy_with_logits(self.D_logits_, tf.zeros_like(self.D_)))self.d_loss = self.d_loss_real + self.d_loss_fakeself.g_loss = tf.reduce_mean( tf.nn.sigmoid_cross_entropy_with_logits(self.D_logits_, tf.ones_like(self.D_))) 收集每个模型的变量,以便可以单独进行训练。 1234t_vars = tf.trainable_variables()self.d_vars = [var for var in t_vars if 'd_' in var.name]self.g_vars = [var for var in t_vars if 'g_' in var.name] 现在我们准备好优化参数,我们将使用ADAM,这是一种在现代深度学习中常见的自适应非凸优化方法。ADAM通常与SGD竞争,并且(通常)不需要手动调节学习速率,动量和其他超参数。 1234d_optim = tf.train.AdamOptimizer(config.learning_rate, beta1=config.beta1) \ .minimize(self.d_loss, var_list=self.d_vars)g_optim = tf.train.AdamOptimizer(config.learning_rate, beta1=config.beta1) \ .minimize(self.g_loss, var_list=self.g_vars) 我们已经准备好了解我们的数据。在每个epoch中,我们在每个minibatch中采样一些图像,并且运行优化器更新网络。有趣的是,如果G仅更新一次,判别器的损失则不会为零。另外,我认为d_loss_fake和d_loss_real在最后的额外的调用回到是一点点不必要的计算,并且是冗余的,因为这些值是作为d_optim和g_optim的一部分计算的。作为TensorFlow中的练习,您可以尝试优化此部分并将RP发送到原始库。 1234567891011121314151617181920212223for epoch in xrange(config.epoch): ... for idx in xrange(0, batch_idxs): batch_images = ... batch_z = np.random.uniform(-1, 1, [config.batch_size, self.z_dim]) \ .astype(np.float32) # Update D network _, summary_str = self.sess.run([d_optim, self.d_sum], feed_dict={ self.images: batch_images, self.z: batch_z }) # Update G network _, summary_str = self.sess.run([g_optim, self.g_sum], feed_dict={ self.z: batch_z }) # Run g_optim twice to make sure that d_loss does not go to zero # (different from paper) _, summary_str = self.sess.run([g_optim, self.g_sum], feed_dict={ self.z: batch_z }) errD_fake = self.d_loss_fake.eval({self.z: batch_z}) errD_real = self.d_loss_real.eval({self.images: batch_images}) errG = self.g_loss.eval({self.z: batch_z}) Generative Adversarial Networks代码整理 InfoGAN-TensorFlow:InfoGAN: Interpretable Representation Learning by Information Maximizing Generative Adversarial Nets iGAN-Theano:Generative Visual Manipulation on the Natural Image Manifold SeqGAN-TensorFlow:SeqGAN: Sequence Generative Adversarial Nets with Policy Gradient DCGAN-Tensorflow:Deep Convolutional Generative Adversarial Networks dcgan_code-Theano:Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks improved-gan-Theano:Improved Techniques for Training GANs chainer-DCGAN:Chainer implementation of Deep Convolutional Generative Adversarial Network keras-dcgan]]></content>
<categories>
<category>Deep Learning</category>
</categories>
<tags>
<tag>GAN</tag>
</tags>
</entry>
<entry>
<title><![CDATA[How to use hexo?]]></title>
<url>%2F2018%2F08%2F14%2FHow-to-use-hexo%2F</url>
<content type="text"><![CDATA[Hexo基本指令 init 1$ hexo init [folder] 新建一个网站,如果没有设置`folder`,Hexo默认在目前的文件夹建立网站。 new 1$ hexo new [layout] <title> 新建一片文章。如果没有设置layout的话,默认使用_config.yml中的default_layout参数代替。如果标题包含空格的话,请使用引号括起来。 generate 12$ hexo generate$ hexo g # 简写 server 1$ hexo server 启动服务器。默认情况下,访问网址为:http://localhost:4000/。 选项 描述 -p,--port 重设端口 -s, --static 只使用静态文本 -l,--log 启动日记记录,使用覆盖记录格式 deploy 12$ hexo deploy$ hexo d # 简写 render 1$ hexo render <file1> [file2] ... 渲染文件。 clean 1$ hexo clean 清楚缓存文件(db.json)好已经生成的静态文件(public)。 在某些情况(尤其是更换主题后),如果发现您对站点的更改没有生效,可以使用此命令。 list 1$ hexo list <type> 列出网站资料。 version 1$ hexo version 显示Hexo版本。 显示草稿 1$ hexo --draft 显示source/_drafts文件夹中的草稿文件。 浏览草稿文章 1$ hexo S --draft publish 12$ hexo publish [layout] <filename>$ hexo P [layout] <filename> # 缩写 发表草稿。 其中 为不包含 md 后缀的文章名称。它的原理只是将文章从 source/_drafts 移动到 source/_posts 而已。 之后的 hexo generate 与 hexo deploy 的用法就完全一样了。 若日后想将正式文章转为为草稿,只需手动将文章从 source/_posts 目录移动到 source/_drafts 目录即可。 自定义CWD 1$ hexo --cwd /path/to/cwd 自定义当前工作目录(Current working dirctory)的路径。 在主页截断 方法1: 在文中插入以下代码 1<!--more--> 方法2: 在文章中的front-matter中添加description, 1234567---title:date: 2018-08-14 15:21:22categories:tags:description: 描述。。--- 分类和标签 只有文章支持分类和标签,您可以在 Front-matter 中设置。在其他系统中,分类和标签听起来很接近,但是在 Hexo 中两者有着明显的差别:分类具有顺序性和层次性,也就是说 Foo, Bar 不等于 Bar, Foo;而标签没有顺序和层次。 12345categories:- Diarytags:- PS3- Games 定义一段代码。 12345import osimport numpy as npfor i in range(10): print('now is ', i) 显示一幅图像。 1{% asset_img 003.jpg This is an example image %} Hexo 资源 hexo官网 theme-next使用说明 使用hexo,如果换了电脑怎么更新博客? 其他参考博客: 我的个人博客之旅:从jekyll到hexo HEXO+NEXT主题个性化配置 hexo的next主题个性化配置教程 基于Hexo+Node.js+github+coding搭建个人博客——进阶篇(从入门到入土) 数学公式渲染 让 Hexo Next (v8.0.0) 支持 LaTeX 数学公式 Rendering Math Equations in Hexo]]></content>
</entry>
</search>