CTPN 算法详解_面试版
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CTPN 算法详解_面试版相关的知识,希望对你有一定的参考价值。
参考技术A 参考链接:https://blog.csdn.net/bestrivern/article/details/1008896321、CTPN 是什么
CTPN 全称是 connection text proposal network,是连接文本区域网络,用于进行横向文本检测。它通过将一系列小的文本框判断是不是标注的文本框的一部分,然后将是同一个标注文本框的小文本框连接成一个文本框区域,称为候选区域。重复上述操作,直到每个标注文本框的候选区域都生成完毕,最后对每个候选区域的大小进行微调。
2、CTPN 的网络结构
3、简述 CTPN 的步骤
① 使用 VGG16 的卷积阶段的网络层作为骨干网络,然后将图片输入 VGG16 网络中进行特征提取,生成特征图
② 在 ① 中输出的特征图中滑动进行 3*3 卷积,然后进行 im2col 操作,然后每次滑动都得到一个 3*3*通道数的特征向量,最后生成一个新的特征图,然后输入 BiLSTM 中进行序列特征提取,再传入全连接层中进一步提取特征
③ 在 ② 的全连接层后接 3 个全连接层分支,分别预测垂直坐标回归、分类得分、水平平移量回归
④ 将 ③ 中的预测垂直坐标回归和分类得分结果输入 RPN 中,而 RPN 的具体步骤如下:
a、
4、CTPN 的优点
① 将骨干网络生成的特征图输入后续网络,而不是将原图输入后续网络,减少了后续网络的计算量
② 引入了 BiLSTM 网络层,使得在进行文本检测时,网络能够利用到文本的语义信息
③ 增加了新的边界得分的预测分支,使得在预测文本框的边界时的效果更好,提高了网络的检测效果
④ 将 RPN 层后置到最后,可以使得 RPN 能够获得更丰富、更高级的特征输入,从而能够产生更好的结果
5、CTPN 的缺点
① 引入了 BiLSTM 网络层,相比于 CNN 可以并行化,BiLSTM 无法进行并行化,因此降低了网络的运行效率,增加了网络的运行时间
② 引入了 BiLSTM 网络层,可能会导致网络发生梯度消失或者梯度爆炸
③ 增加了新的边界得分预测分支,增加了标注成本
④ 只能用于水平方向的文本检测,垂直方向上会出现字与字的断开。如果存在倾斜,需要修改 anchor 的连接方式
⑤ anchor 的合并和断开是一个问题。程序使用的是水平 50 个像素内合并,垂直 IoU>0.7 合并。或许由于 BiLSTM 的引入,导致断开这个环节变差。所以对于双栏,三栏的这种文本,ctpn 会都当做一个框处理,有时也会分开处理,总之不像 EAST 效果好。
6、CTPN 可以改进的点
7、CTPN 的损失函数
分类得分损失: ,具体损失函数为交叉熵损失
边框回归损失: ,具体损失函数为 Smooth_L1
边界框得分损失: ,具体损失函数为 Smooth_L1
假设所有的 anchor 的集合为 A,则 i 表示集合 A 中的第 i 个 anchor,而 则表示第 i 个 anchor 的分类得分,分别为 0 和 1,0 表示是非文本框,而 1 表示是文本框。而 表示归一化因子,是 A 中的 anchor 个数之和。
假设 A 中的 anchor 跟 GroundTruth 的 IoU 大于 0.5 的 anchor 集合为 B,则 j 表示 B 中的第 j 个 anchor, 表示的是边框回归值。而 使用的是 Smooth_L1 进行计算损失。 是归一化因子,是 B 中的 anchor 个数之和。 是多任务平衡系数,一般取值为 1.
假设边界 anchor 的集合为 C,则 o 表示 C 中的第 o 个 anchor ,则 表示 C 中的第 k 个 anchor 的得分,而 使用 Smooth_L1 进行计算损失。 表示归一化因子,而 是多任务平衡系数,一般取值为 2.
8、Smooth_L1 损失函数
假设输入为 x ,则
当 |x| < 1 时,输出
其他情况,输出 |x| - 0.5
优点:
当 |x| < 1 时, Smooth_L1 的梯度为 x,所以即使 x 的值很小,也能有梯度;
而当 |x| ≥ 1 时,Smooth_L1 的梯度为 ±1,此时不易发生梯度爆炸。
且 Smooth_L1 对离群点和异常值不敏感
9、边框偏移计算公式
假设 anchor 的中心坐标为 y_a 和高度 h_a,而预测的中心坐标为 y_p 和高度 h_p,真实值的中心坐标为 y_t 和高度 h_t,则计算公式为:
s_p = (y_p - y_a) / h_a
s_t = (y_t - y_a) / h_a
h_pa = log(h_p / h_a)
h_ta = log(h_t / h_a)
注:y_p 和 h_p
动画详解十大经典排序算法Java版实现(上)
经典排序算法可以说是面试必考题,然而大学毕业之后基本都忘光了,正好趁这个机会拿出来好好总结复习下,也算不辜负当年老师的一片苦心了。
十大经典排序算法包括:冒泡排序,选择排序,插入排序,希尔排序,归并排序,快速排序,堆排序,计数排序,桶排序,基数排序。
本来准备一口气把十种都介绍一遍,然而整理完前五种后大脑就宕机了(亲测熬夜会使人变傻······),那干脆就分为上下两部分好了,正好也方便记忆。
接下来我们用动画的方式,先来分析前五种算法:冒泡排序,选择排序,插入排序,希尔排序,归并排序。
1. 冒泡排序
算法介绍
冒泡排序是一种简单的排序算法,它会重复遍历要排序的数列,一次比较两个元素,如果两个元素的顺序错误,就交换过来。
遍历数列需要重复进行,直到没有再需要交换的元素,才代表数列已经排序完成。
因为小的元素会经由交换慢慢“浮”到数列的顶端,就像水泡冒出来一样,所以才称之为“冒泡排序”。
动画演示
步骤描述
- 比较相邻的元素:如果第一个元素比第二个大,就交换它们;
- 比较每一对相邻元素并交换,从开始第一对到最后一对,这样最后的元素就是最大的数;
- 针对所有的元素重复以上步骤,除了最后一个;
- 重复前三个步骤,直到排序完成;
代码实现
public static void main(String[] args) {
int arr[] = {8, 5, 3, 2, 4};
//冒泡
for (int i = 0; i < arr.length; i++) {
//外层循环,遍历次数
for (int j = 0; j < arr.length - i - 1; j++) {
//内层循环,升序(如果后一个值比前一个值小,则交换)
//内层循环一次,获取一个最大值
if (arr[j + 1] < arr[j]) {
int temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
}
2. 选择排序
算法介绍
选择排序是一种简单直观的排序算法。
它首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素放到已排序序列的末尾。
以此类推,直到所有元素全部排序完毕。
动画演示
步骤描述
- 将第一个值看成最小值;
- 和后续的值进行比较,找出最小值和下标;
- 交换本次遍历的起始值和最小值;
- 重复以上步骤直到列表排序结束;
代码实现
public static void main(String[] args) {
int arr[] = {6, 5, 3, 2, 4};
// 选择
for (int i = 0; i < arr.length; i++) {
// 默认第一个是最小的
int min = arr[i];
// 记录最小的下标
int index = i;
// 通过与后面的数据进行比较得出,最小值和下标
for (int j = i + 1; j < arr.length; j++) {
if (min > arr[j]) {
min = arr[j];
index = j;
}
}
//然后将最小值与本次循环的a[i]值进行交换
arr[index] = arr[i];
arr[i] = min;
}
}
3. 插入排序
算法介绍
对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
插入排序在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
动画演示
步骤描述
- 第一个元素默认已经被排序;
- 取出下一个元素,在已经排序的元素序列中从后向前扫描;
- 如果该元素大于新元素,将该元素移到下一位置;
- 重复上一步骤,直到找到已排序的元素<=新元素的位置;
- 将新元素插入到该位置;
- 重复步骤 2 ~ 5;
代码实现
public static void main(String[] args) {
int arr[] = {7, 5, 3, 2, 4};
//插入排序
for (int i = 1; i < arr.length; i++) {
//外层循环,从第二个开始比较
for (int j = i; j > 0; j--) {
//内层循环,与前面排好序的数据比较,如果后面的数据小于前面的则交换
if (arr[j] < arr[j - 1]) {
int temp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = temp;
} else {
//如果不小于,说明插入完毕,退出内层循环
break;
}
}
}
}
4. 希尔排序
算法介绍
希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序。它与插入排序的不同之处在于,它会优先比较距离较远的元素。
希尔排序会把记录按下表的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
动画演示
动画演示效果看起来不太好理解,我们可以通过以下图片进一步加深理解:
步骤描述
-
选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;
-
按增量序列个数 k,对序列进行 k 趟排序;
-
每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序;
-
仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度;
代码实现
public static void main(String[] args) {
int arr[] = {7, 5, 3, 2, 4};
//希尔排序(插入排序变种版)
for (int i = arr.length / 2; i > 0; i /= 2) {
//i层循环控制步长
for (int j = i; j < arr.length; j++) {
//j控制无序端的起始位置
for (int k = j; k > 0 && k - i >= 0; k -= i) {
if (arr[k] < arr[k - i]) {
int temp = arr[k - i];
arr[k - i] = arr[k];
arr[k] = temp;
} else {
break;
}
}
}
//j,k为插入排序,不过步长为i
}
}
5. 归并排序
算法介绍
归并排序是建立在归并操作上的一种有效的排序算法。
该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,是一种稳定的排序方法。
排序规则是将已经有序的子序列进行合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
动画演示
步骤描述
- 把长度为n的输入序列分成两个长度为n/2的子序列;
- 对这两个子序列分别采用归并排序;
- 将两个排序好的子序列合并成一个最终的排序序列;
代码实现
public static void main(String[] args) {
int arr[] = {7, 5, 3, 2, 4, 1,6};
//归并排序
int start = 0;
int end = arr.length - 1;
mergeSort(arr, start, end);
}
public static void mergeSort(int[] arr, int start, int end) {
//判断拆分的不为最小单位
if (end - start > 0) {
//再一次拆分,直到拆成单个数据
mergeSort(arr, start, (start + end) / 2);
mergeSort(arr, (start + end) / 2 + 1, end);
//记录开始/结束位置
int left = start;
int right = (start + end) / 2 + 1;
//记录每个小单位的排序结果
int index = 0;
int[] result = new int[end - start + 1];
//如果拆分后的两块数据都还存在
while (left <= (start + end) / 2 && right <= end) {
//比较两块数据的大小,然后赋值,并且移动下标
if (arr[left] <= arr[right]) {
result[index] = arr[left];
left++;
} else {
result[index] = arr[right];
right++;
}
//移动单位记录的下标
index++;
}
//当某一块数据不存在
while (left <= (start + end) / 2 || right <= end) {
//直接赋值到记录下标
if (left <= (start + end) / 2) {
result[index] = arr[left];
left++;
} else {
result[index] = arr[right];
right++;
}
index++;
}
//最后将新的数据赋值给原来的列表,并且是对应分块后的下标
for (int i = start; i <= end; i++) {
arr[i] = result[i - start];
}
}
}
看到归并排序脑子就不行了,本篇博客就到这里,我们下期再见。
参考了博客如下,在这里表示特别感谢:
以上是关于CTPN 算法详解_面试版的主要内容,如果未能解决你的问题,请参考以下文章