日常生活中经常会碰到大额人民币因为保管不善而变成一堆烂钞,这种情况在偏远农村普遍存在。由于农村基层金融机构缺乏,农民通常将现钞保存在手上,经常遭到虫咬鼠啃、火烧水浸,辛苦得来的钱财成了一堆碎片。

若这些碎片拿到银行去兑换,依据相关规定,残币须拼出大于原图的 50%方允许兑换。用人工方法进行拼接,费时费力。因此,有必要开发一种机器方法对碎片进行自动拼接。要实现这种自动拼接,首先要找到人民币碎片在基准图上的位置,也就是要找到一种恰当的图像匹配方法。

一般而言,图像匹配的算法可分为两类:

(1)是基于图像灰度的匹配算法

(2)是基于图像特征的匹配算法

由于基于灰度的匹配算法计算量大,Barnea 于 1972 年提出序贯相似性算法———SSDA法,而 Wong 于 1978 年提分层序贯匹配算法以加快速度传统的基于灰度的匹配方法虽然在匹配精度,对噪声具有鲁棒性等方面具有优势,但对待匹配图像间的角度旋转敏感。当待配图像间存在相对的旋转角时,就会发生错误匹配。

为克服这一缺陷,本文提出了改进的sift算法,由于人民币碎片图像不可能与基准图保持平行关系,因此要想将基于灰度的匹配算法用于碎片图像匹配,基于特征的匹配算法,则是基于图像的边缘、特征点、纹理等特征,将图像的匹配转化为少量特征的匹配,从而可提高匹配速度。

SIFT算法,即Scale Invariant Feature Transform,是David G Lowe于2004年提出。它具有许多优良的特性:

1.不变性:对旋转、尺度缩放、亮度变化保持不变。

2.独特性:能在大量特征数据中进行快速、准确的匹配。

Read more »

深度学习框架

Theano是一个Python库(貌似已经停止更新了),支持CPU或GPU,不支持分布式训练。

Keras是一个高层神经网络API,Keras由纯Python编写而成并基于Tensorflow、Theano以及CNTK。Keras 为支持快速实验而生,支持CPU和GPU。它具有高度模块化,极简,和可扩充特性,比较适合简易和快速的原型设计。

CNTK是微软开源的深度学习框架,支持分布式训练。

Tensorflow与mxnet是现在比较火的2种深度学习框架,都支持分布式训练。

Caffe原生的只有单机版本,现在有多个项目支持caffe的分布式版本比如Yahoo的caffe on spark,caffeMPI(Caffe-MPI是全球首个集群并行版的Caffe深度学习计算框架),PMLS-Caffe: Distributed Deep Learning Framework on Petuum

在这里插入图片描述

Read more »

常用的实践建议

得到更好的训练数据:

越大的数据集越好。DNN 对数据很饥渴,越多越好。
去除所有包含损坏数据的训练样本,比如极短文字,高度扭曲的图像,错误的输出标签,包含许多null values的属性。
Data Augmentation(数据增强):生成新样例,比如对于图像来说,进行尺度缩放,增加噪声等。

选择恰当的激活函数:

对于MLP和CNN,一般使用ReLU或者它的变体;
对于RNN/LSTM,一般使用tanh做激活函数,sigmoid函数来参与门机制。

隐藏单元和隐层(Hidden Units and Layers)的数量:

隐层单元的数量宁可多点也不要少。
通过增加隐藏单元的数目,模型会得到所需的灵活性,这样可以在预训练中过滤出最合适的信息。
不停增加层,直到测试误差不再减少。

权重初始化 :

永远用小的随机数字初始化权重。
如果可以考虑使用BN来降低权重初始化的选择难度;如果不是用BN,可以考虑xavier或者其变体来初始化,或者用一些经过试验的经验公式。

学习率的设置和调整:

Read more »

背景:

正如人在看一段文字的时候,会有上下文的记忆和理解。类似的对于NLP相关的任务,都是需要上下文理解的。 如何处理这样的序列类型的任务导致了RNN以及变种的出现。

常用场景:

RNN的每个训练样本都是连续的序列(序列从语义上包括时间上的或者空间上的), 序列的长短不一(序列的长度一般也叫时间步),每个序列元素都是一个向量。比如一段段连续的语音,一段段连续的手写文字。这样的序列相关任务是RNN比较擅长的。

RNN的基本模型结构

在这里插入图片描述

RNN概述

RNN的基本模型结构的假设:在序列索引号t位置的隐藏状态h(t),由x(t)和在t−1位置的隐藏状态h(t−1)共同决定。

RNN是一种共享参数的网络:参数在每个时间步上共享。

RNN的反向传播算法也叫做BPTT(back-propagation through time),除了梯度表达式不同,训练思路类似DNN。即使RNN每个时间步都有对应的输出,但是权重更新也是在一个mini-batch的所有时间步结束后才利用BPTT来实现的。

Read more »

感知器图示:

在这里插入图片描述

在这里插入图片描述

感知器算法流程:(引入x0特征并设置为常量1是为了表示方便)

在这里插入图片描述

上面是感知器原始形式算法,现在一般使用训练速度更快的感知器对偶形式来代替。(对偶形式一定快吗?不一定)

如果样本数量比特征数多,此时采用对偶形式计算量较大,推荐采用原始形式优化。

感知器模型的假设是样本集线性可分,同时它只能处理二分类问题。

如果数据线性可分,这样的超平面一般都不是唯一的,也就是说感知机模型可以有多个解。想要只有一个超平面可以采用类似SVM的方式即对分离超平面增加约束条件。

多层感知器MLP

Read more »

为什么会出现CNN?

背景:

前文提到的MLP在处理类似图片这样的高维样本的时候, 涉及到的模型参数太多, 训练耗时, 而且容易过拟合.(尽管有很多减少过拟合的方法)

创新:

发明CNN的巨人是受到了人类神经网络的启发,人在识别看到的图片的时候也是一层一层的通过不同的神经元来从简单到抽象的处理过程。
CNN的卷积核或叫filter是被不同的神经元share的,因此相对于传统的MLP需要更少的参数,更容易训练。

CNN 对图片的平移、比例缩放、倾斜等变形具有高度不变性。

CNN能够提取low/mid/high-level的特征,网络的层数越多,意味着能够提取到不同level的特征越丰富。并且,越深的网络提取的特征越抽象,越具有语义信息。

一个有趣的现象:

经过训练后的模型的filter中有很多0或者接近0的权重,也就是说filter本身是稀疏的。

CNN进化史
在这里插入图片描述

Read more »

现在有一棵合法的二叉树,树的节点都用数字表示,现在给定这棵树上所有的父子关系,求这棵树的高度

输入:
输入的第一行表示节点的个数n(1<=n<=1000),节点的编号为0到n-1组成,下面是n-1行,每行有两个整数,第一个数表示父节点的编号,第二个数表示子节点的的编号

输出
输出树的高度,为一个整数

样例输入:
5
0 1
0 2
1 3
1 4

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
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

int getLength(int **data, int i, int j)
{
int length = 0;
if (data[i][j] != -1)
{
//i->j可达
int max =0;
for (int n = 0; n < 1000; n++)
{
int temp = getLength(data, j, n)+1;
if (temp>max)
{
max = temp;
}
}
if (max==0)
{
return 1;
}
return max;
}
else
{
return 1;
}
}



int main()
{
int n;
scanf("%d", &n);

int **data = new int*[1000];
for (int i = 0; i < 1000; i++)
{
data[i] = new int[1000];
}


for (int i = 0; i < 1000; i++)
{
for (int j = 0; j < 1000; j++)
{
data[i][j] = -1;
}
}
for (int i = 0; i < n - 1; i++)
{
int a, b;
scanf("%d %d", &a, &b);
data[a][b] = 1;
}

int lengthMax = -1;
for (int i = 0; i < 1000; i++)
{
for (int j = 0; j < 1000; j++)
{
if (data[i][j] != -1)
{
int len = getLength(data, i, j);
if (len>lengthMax)
{
lengthMax = len;
}
}

}

}
cout << lengthMax << endl;
return 0;
}

结论:刚开始做这个题的时候,知道用递归或者循环的办法解决,选择数据结构首选是邻接矩阵,但是在写递归的时候,出现了错误,导致一直只有60%的测试用例通过,笔试结束后仔细写了一下算法的递归表达式,以及递归退出条件,这个代码应该是可以通过的,欢迎网友来吐槽修正。

Read more »

深度学习是机器学习研究中的一个新的领域,其动机在于建立、模拟人脑进行分析学习的神经网络,它模仿人脑的机制来解释数据,例如图像,声音和文本。深度学习是无监督学习的一种,深度学习采用了神经网络的分层结构,系统包括输入层、隐层(多层)、输出层组成的多层网络,只有相邻的节点之间有连接,同一层以及跨层节点之间相互无连接。

深度学习通过建立类似于人脑的分层模型结构,对输入数据逐级提取从底层到高层的特征,从而能很好地建立从底层信号到高层语义的映射关系。近年来,谷歌、微软、百度等拥有大数据的高科技公司相继投入大量资源进行深度学习技术研发,在语音、图像、自然语言、在线广告等领域取得显著进展。从对实际应用的贡献来说,深度学习可能是机器学习领域最近这十年来最成功的研究方向。深度学习模型不仅大幅提高了图像识别的精度,同时也避免了需要消耗大量的时间进行人工特征提取的工作,使得在线运算效率大大提升。

论文Thai Text Localization in Natural Scene Images using Convolutional Neural Network主要采用CNN的方法进行自然场景中的文本分类,并根据泰字的特点进行分类后的后处理,得到更加精确的定位效果。如图1所示为CNN网络模型,CNN网络由一个输入层,两个卷积层和两个下采样层以及一个全连接层组成,输出为一个二分类向量,即文本和非文本。

该文主要思路为将图像切块后进行训练,采用人工标注样本的方法,使得网络具有识别文本和非文本的能力。由于样本数量较少,文中采用了根据已有字体生成训练数据集的方法,包括对字体随机添加背景、调整字体风格以及应用滤波器。如图2为生成的泰字样本,文中在标签的过程中将半个字或者整个字都标记为文本,增加了网络对文字的识别率。

这里写图片描述

在使用生成好的网络进行文字定位的过程中,论文采用的编组方法结合了泰字的特点,如图3为对图像文字的初步定位,其中被标记的区域被网络识别为文字。

这里写图片描述

论文后期对标记的矩形小框区域进行了整合,结合了泰字本身的特点,如图图4所示为原始图像文字,图5为对识别结果进行的后处理,其中a,b,c将文字分为上、中、下三个部分。文中指出泰字一般的最高不超过中心线b的50%,采用这个规律进行了文字编组,得到如图6的编组结果,其中白色区域为编组结果。

这里写图片描述

Read more »