Deep Local Feature 文章 & 数据收集

在 SLAM 中 Local Feature 的提取和匹配是一个比较重要的内容,近些年有很多相关的使用 Deep Learning 学习局部描述子的工作,这里做一下相关文章和代码收集。后续如有精力会进行速度和性能比较。

文章收集

文章 会议 PDF 代码
DELF: DEep Local Features CVPR 2018 PDF Code
LF-Net: Learning Local Features from Images NIPS 2018 PDF Code
AffNet: Repeatability Is Not Enough: Learning Discriminative Affine Regions via Discriminability ECCV 2018 9713618804 8779495179
SuperPoint: Self-Supervised Interest Point Detection and Description CVPR 2018 (408) 257-5532 Code
DeepCD: Learning Deep Complementary Descriptors for Patch Representations ICCV 2017 PDF Code
HardNet: Working hard to know your neighbor’s margins: Local descriptor learning loss NIPS 2017 (815) 346-0721 Code
TFeat: shallow convolutional patch descriptor BMVC 2016 PDF rabbit-chasing
LIFT: Learned Invariant Feature Transform ECCV 2016 PDF (506) 986-6710

数据收集

数据集名称 下载地址
Phototour /phototour.cs.washington.edu/patches/default.htm
HPatches /github.com/hpatches/hpatches-dataset

Posted in CNN | (415) 243-5682

Tensorflow C++ 从训练到部署(3):使用 Keras 训练和部署 CNN

在上一篇文章中我们并没有去训练一个真正的网络和解决一个实际问题,我们所做的是构建了一个 c = a * b 的计算图,并用 python 进行了保存和 c++ 进行了读取,这一保存和读取中也仅包含图的结构并没有相关参数。本篇文章中我们进一步以 Tensorflow 官方的 Fashion MNIST 为例,完成一个简单的分类问题。本文前面 Keras 训练模型以及转化到 Tensorflow 格式部分与之前一篇博客(Keras 转换成 Tensorflow 模型格式并使用)基本一致。本文主要包含:
1)Python:Fashion MNIST 数据集
2)Python:使用 Keras 定义 CNN 模型、训练并保存
3)Python:转换 Keras 模型到 Tensorflow 格式并保存
4)Python:使用 Tensorflow Python API 加载模型并预测
5)C++:使用 Tensorflow C++ API 加载模型并预测

0、系统环境
Ubuntu 16.04
Tensorflow 1.10.1 (安装详见downstate,建议使用 pip 方式安装)

1、Fashion MNIST 数据集
1)数据简介
Fashion-MNIST [1] 是一个替代MNIST手写数字集的图像数据集。 它是由Zalando(一家德国的时尚科技公司)旗下的研究部门提供。其涵盖了来自10种类别的共7万个不同商品的正面图片。Fashion-MNIST的大小、格式和训练集/测试集划分与原始的MNIST完全一致。60000/10000的训练测试数据划分,28×28的灰度图片。你可以直接用它来测试你的机器学习和深度学习算法性能,且不需要改动任何的代码 [11]。

典型的 Fashion-MNITST 数据是这样的,其中每三行表示一个类别:
fashion-mnist-sprite

Fashion-MNIST 与 MNIST 同样有 10 个类别,不过并不是 0-9 的 10 个数字,它的类别如下:

screenshot-from-2018-09-25-11-50-54

我们使用过以前的 MNIST 数据集都知道,随便弄个很简单的网络,就可以轻轻松松刷出 99% 以上的分数了,即使传统方法也很容易达到高分。所以 MNIST 手写数字识别由于过于简单,作为一个基本的实验数据已经没有什么意义了。Tensorflow 和很多深度学习框架现在的入门数据也都推荐 Fashion MNIST。

2)数据读取
其实 Keras 为我们提供了简单的接口可以一键下载 Fashion-MNIST 数据并且读取:

不过由于天朝网络的原因,我并不推荐这种方式,建议直接下载到本地读取。我这里将数据直接存到 data/fashion 目录下。
百度网盘下载:
/pan.baidu.com/s/19zZqU5tSwZyY780z8Y8_VA

读取数据代码如下(保存为:utils/mnist_reader.py):

2、使用 Keras 定义 CNN 模型、训练并保存
下面的代码中我们定义了一个非常简单的 CNN 网络,结构图如下:
model

我们使用这一网络进行训练并且保存为 Keras 标准的 h5 格式。这一部分代码比较基础,就不做过多解释了。

Keras 模型定义和训练代码如下(保存为:train.py):

如果你的运行没有问题则会看到类似如下输出:

同时在 models/ 文件夹下保存了 fashion_mnist.h5 文件,这一文件包含了模型的结构和参数。

3、转换 Keras 模型到 Tensorflow 格式并保存
这一环节我们使用 keras_to_tensorflow [2] 转换工具进行模型转换,其实这个工具原理很简单,首先用 Keras 读取 .h5 模型文件,然后用 tensorflow 的 convert_variables_to_constants 函数将所有变量转换成常量,最后再 write_graph 就是一个包含了网络以及参数值的 .pb 文件了。

具体代码参见(原始代码中可以传入输出 node 数量和名字并使用 identity 生成新的 tensor,我这里稍作修改,直接读取 Keras 的 outputs 的操作名,最后会输出原始 inputs 和 outputs 的名字供后面使用):

Tensorflow 模型转换代码(保存为:utils/keras_to_tensorflow.py)

我们执行如下命令转换 Keras 模型到 Tensorflow 的 pb 格式:

如果你的运行无误的话则会显示如下信息并生成 models/fashion_mnist.h5.pb 这个就是转换过来的 Tensorflow 格式:

这里面也告知了你模型输入和输出的 Tensor 名字,这两个信息很重要我们后面会用到。

4、使用 Tensorflow Python API 加载模型并预测
我们使用标准的 Tensorflow Low-Level API 加载和预测代码如下(保存为:load_predict.py)

这段代码中前面同样是读取 Fashion MNIST 数据集,与训练代码一样。部分代码说明如下:

读取 pb 模型文件:

获取当前的计算图:

获取输出的 Tensor:

可以看到除了之前我们给出的输出 Tensor 名称 output_class/Softmax 外,我们还需要加上一个索引 :0。关于这一问题的解释可以参见 [12]。我们这里简单来理解,”output_class/Softmax” 是指定了一个 Operation 的名字,对应最后 Softmax 层,大部分层的输出都是一个 Tensor,不过也有可能一个层产生多个输出 Tensor,因此我们这里需要指定是哪个输出。通常对于一个输出的时候就是用 :0 指定,对于 Input 也是同理。

执行计算图并打印输出结果,其中 feed_dict={‘input_image_input:0’: test_images} 将 test_images 作为输入传入网络:

执行整个代码:

如果运行没有问题则可以看到如下结果:

与之前我们使用 Keras 的 predict 接口结果对比,是一样的,说明我们转换后的模型无误。

关于 Keras 转换成 Tensorflow 模型和预测的步骤就到这里。完整示例可以参见:
873-270-3494

5、使用 Tensorflow C++ API 加载模型并预测
1)使用 C++ 转换 OpenCV 的 Mat 到 Tensor
Tensor 要求输入的是归一化的 float32 格式图片,实际我们使用如下代码来完成 OpenCV Mat 到 Tensor 的转换(保存为:utils/mat2tensor.h)

这段代码比较简单,就是声明一个 {1, img.size().height, img.size().width, img.channels()} 的单个 Tensor,将地址直接赋给 fake_mat,然后使用 OpenCV 把图片转成 float32 格式,声明的 Tensor 自然也就转成了 float32 格式。最后是根据输入 normal 因子进行归一化。这一归一化方法和之前训练时一致。

2)使用 C++ 调用 pb 模型并预测
与前面的文章类似,我们参考 Python 调用 pb 模型及预测接口使用 C++ API 调用之前转换的模型并预测代码如下(保存为:load_predict.cpp):

如果编译运行没有问题的话,会输出如下结果:

输入和调用模型与之前的博客基本一致,这里解释下输出部分:

这里 flat_inner_dims 的 API 官方说明如下:
screenshot-from-2018-10-15-18-57-02

表示将按照指定类型 T 和指定维度 NDIMS 的 Eigen::TensorMap 输出,需要说明的是这一 T 和 NDMS 维度必须与模型中实际输出类型一致,否则运行时会报错。TensorMap 相当于 Tensor 的一个引用,其内存地址并不像 Tensor 一样是自己创建与释放的,因此没有 resize 等操作,其他使用方法与 Tensor 类似。关于 Eigen::Tensor 使用说明参见 [6] 和 [7]。

其中 tensorflow::TTypes::Tensor 与 Eigen::TensorMap, Eigen::Aligned> 其实是等价的,因此上面那一行也可以替换成:

到这里我们就完整介绍了一个 CNN 网络从 Keras 训练、转成 Tensorflow 格式到 C++ 部署的基本流程。

本文完整代码参见 Github:
/github.com/skylook/tensorflow_cpp

参考文献
[1] /www.tensorflow.org/tutorials/keras/basic_classification
[2] 4137989084
[3] (402) 359-8226
[4] 6203931625
[5] 334-528-7300
[6] /eigen.tuxfamily.org/index.php?title=Tensor_support
[7] /github.com/PX4/eigen/blob/master/unsupported/Eigen/CXX11/src/Tensor/README.md
[8] /www.tensorflow.org/api_docs/cc/class/tensorflow/tensor

Tensorflow C++ 从训练到部署系列文章目录

Tensorflow C++ 从训练到部署(3):使用 Keras 训练和部署 CNN
Tensorflow C++ 从训练到部署(2):简单图的保存、读取与 CMake 编译
Tensorflow C++ 从训练到部署(1):环境搭建

Posted in imperialness | (507) 380-2666

Keras 转换成 Tensorflow 模型格式并使用

Tensorflow 官方已经集成了 Keras 作为自己推荐的 High-Level API,Keras 的确使用非常方便,而且代码美观简洁,不像 Tensorflow 那样有很多形式化的代码。对于我们进行快速原型和实验是非常有帮助的。然而在一些场合我们可能需要混合使用 Keras 和 Tensorflow 定义模型或者保存模型的操作,这时就需要一些转换了。

系统环境
Ubuntu 16.04
Tensorflow 1.10.1 (内置:Keras 2.1.6-tf)

1、Fashion MNIST 数据集
1)数据简介
Fashion-MNIST [1] 是一个替代MNIST手写数字集的图像数据集。 它是由Zalando(一家德国的时尚科技公司)旗下的研究部门提供。其涵盖了来自10种类别的共7万个不同商品的正面图片。Fashion-MNIST的大小、格式和训练集/测试集划分与原始的MNIST完全一致。60000/10000的训练测试数据划分,28×28的灰度图片。你可以直接用它来测试你的机器学习和深度学习算法性能,且不需要改动任何的代码 [11]。

典型的 Fashion-MNITST 数据是这样的,其中每三行表示一个类别:
fashion-mnist-sprite

Fashion-MNIST 与 MNIST 同样有 10 个类别,不过并不是 0-9 的 10 个数字,它的类别如下:

screenshot-from-2018-09-25-11-50-54

我们使用过以前的 MNIST 数据集都知道,随便弄个很简单的网络,就可以轻轻松松刷出 99% 以上的分数了,即使传统方法也很容易达到高分。所以 MNIST 手写数字识别由于过于简单,作为一个基本的实验数据已经没有什么意义了。Tensorflow 和很多深度学习框架现在的入门数据也都推荐 Fashion MNIST。

2)数据读取
其实 Keras 为我们提供了简单的接口可以一键下载 Fashion-MNIST 数据并且读取:

不过由于天朝网络的原因,我并不推荐这种方式,建议直接下载到本地读取。我这里将数据直接存到 data/fashion 目录下。
百度网盘下载:
/pan.baidu.com/s/19zZqU5tSwZyY780z8Y8_VA

读取数据代码如下(保存为:utils/mnist_reader.py):

2、使用 Keras 定义 CNN 模型并保存
下面的代码中我们定义了一个非常简单的 CNN 网络,结构图如下:
model

我们使用这一网络进行训练并且保存为 Keras 标准的 h5 格式。这一部分代码比较基础,就不做过多解释了。

Keras 模型定义和训练代码如下(保存为:train.py):

如果你的运行没有问题则会看到类似如下输出:

同时在 models/ 文件夹下保存了 fashion_mnist.h5 文件,这一文件包含了模型的结构和参数。

3、转换 Keras 模型到 Tensorflow 格式并保存
这一环节我们使用 keras_to_tensorflow [2] 转换工具进行模型转换,其实这个工具原理很简单,首先用 Keras 读取 .h5 模型文件,然后用 tensorflow 的 convert_variables_to_constants 函数将所有变量转换成常量,最后再 write_graph 就是一个包含了网络以及参数值的 .pb 文件了。

具体代码参见(原始代码中可以传入输出 node 数量和名字并使用 identity 生成新的 tensor,我这里稍作修改,直接读取 Keras 的 outputs 的操作名,最后会输出原始 inputs 和 outputs 的名字供后面使用):

Tensorflow 模型转换代码(保存为:utils/keras_to_tensorflow.py)

我们执行如下命令转换 Keras 模型到 Tensorflow 的 pb 格式:

如果你的运行无误的话则会显示如下信息并生成 models/fashion_mnist.h5.pb 这个就是转换过来的 Tensorflow 格式:

这里面也告知了你模型输入和输出的 Tensor 名字,这两个信息很重要我们后面会用到。

4、使用 Tensorflow 加载模型并预测
我们使用标准的 Tensorflow Low-Level API 加载和预测代码如下(保存为:load_predict.py)

这段代码中前面同样是读取 Fashion MNIST 数据集,与训练代码一样。部分代码说明如下:

读取 pb 模型文件:

获取当前的计算图:

获取输出的 Tensor:

可以看到除了之前我们给出的输出 Tensor 名称 output_class/Softmax 外,我们还需要加上一个索引 :0。关于这一问题的解释可以参见 [12]。我们这里简单来理解,”output_class/Softmax” 是指定了一个 Operation 的名字,对应最后 Softmax 层,大部分层的输出都是一个 Tensor,不过也有可能一个层产生多个输出 Tensor,因此我们这里需要指定是哪个输出。通常对于一个输出的时候就是用 :0 指定,对于 Input 也是同理。

执行计算图并打印输出结果,其中 feed_dict={‘input_image_input:0’: test_images} 将 test_images 作为输入传入网络:

执行整个代码:

如果运行没有问题则可以看到如下结果:

与之前我们使用 Keras 的 predict 接口结果对比,是一样的,说明我们转换后的模型无误。

关于 Keras 转换成 Tensorflow 模型和预测的步骤就到这里。完整示例可以参见:
905-932-4804

常见问题
1、错误: This could mean that the variable was uninitialized.

这通常是由于训练模型后直接进行保存的缘故。解决方法是重新声明一个 model 类型加载 keras 模型与参数。

2、错误:OSError: Unable to open file (unable to lock file, errno = 37, error message = ‘
No locks available’)
如果你使用 Keras 保存模型到 h5 时遇到如下问题:

这一问题通常是由于在 NFS 文件系统中的问题,建议在命令行配置系统变量或者假如 ~/.bashrc 文件:

3、错误:Tensor names must be of the form “:
如果你的代码遇到如下错误:

解决方法是在你调用 Tensor 时加入索引,例如 :0。详情请见 [12]。

参考文献
[1] /blog.keras.io/keras-as-a-simplified-interface-to-tensorflow-tutorial.html
[2] /github.com/amir-abdi/keras_to_tensorflow
[3] /towardsdatascience.com/freezing-a-keras-model-c2e26cb84a38
[4] /medium.com/@brianalois/simple-keras-trained-model-export-for-tensorflow-serving-23fa5dfeeecc
[5] /blog.metaflow.fr/tensorflow-how-to-freeze-a-model-and-serve-it-with-a-python-api-d4f3596b3adc
[6] /github.com/BerkeleyGW/hdf5_bug
[7] /github.com/h5py/h5py/issues/1082#issuecomment-414291188
[8] /github.com/amir-abdi/keras_to_tensorflow
[9] /www.tensorflow.org/tutorials/keras/save_and_restore_models
[10] /github.com/tensorflow/tensorflow/blob/master/tensorflow/tools/graph_transforms/README.md#quantize_weights
[11] /github.com/zalandoresearch/fashion-mnist/blob/master/README.zh-CN.md
[12] /stackoverflow.com/questions/37849322/how-to-understand-the-term-tensor-in-tensorflow/37870634#37870634

Posted in tensorflow | Leave a comment

Tensorflow C++ 从训练到部署(2):简单图的保存、读取与 CMake 编译

经过了 上一篇文章,我们已经成功编译了 tensorflow c++ 的系统库文件并且安装到系统目录下了。这里我们将使用这个编译好的库进行基本的 C++ 模型加载执行等操作。
注意,在本篇文章会使用 Tensorflow 的 Python API,因为比较简单,这里不做介绍,安装详见官网教程:
/www.tensorflow.org/install/

0、系统环境
Ubuntu 16.04
Tensorflow 1.10.1 (安装详见205-581-3911,建议使用 pip 方式安装)

1、一个简单网络的保存
只有 c = a * b 的网络:

在这段代码中,我们构建了一个非常简单的“网络”:
\(c = a * b\)
并且给 a 和 b 赋予了初值。这一网络虽然简单,但是更复杂的网络也是类似的道理,我们需要保存的无非是计算图的结构,和图中的参数。这里边我们 tf.train.write_graph 保存的仅仅是图的结构。注意其中每个 placeholder 的 name 非常重要,这是我们后面输入和获取这些值的基础。

在这一例子中,有两点注意:
a)tf.train.write_graph 函数就是指定了保存图的路径,as_text=False 表明用二进制格式保存(默认是文本格式保存)。
b)res = sess.run(c, feed_dict={‘a:0’: 2.0, ‘b:0’: 3.0}) 中,我们定义的 placeholder 的名字是 a 和 b,但是对于 tensorflow 来说 shape=None 的相当于一个 1×1 的向量,所以我们还是要指定一个下标表示 a 和 b 是这个向量的第一个元素,这里 tensorflow 用 a:0 和 b:0 表示。如果 a 和 b 本来就是一个多维向量,那么可以直接取出整个向量。

我们将这段代码保存为 simple/simple_net.py 文件并执行:

正常情况下会在 model 文件夹下保存一个 simple.pb 的文件,并且输出一个测试运行的结果:
res = 6.0

PS:你也可以指定为文本格式保存,通常文本格式我们保存为 .pbtxt 后缀,例如:

保存出来就是这样的,看起来很简单,不过通常我们还是用二进制格式比较高效:

2、使用 Python 读取这个网络
首先我们来看下用 Python 如何读取这个网络并进行计算:

我们将这段代码保存为 simple/load_simple_net.py 文件并执行:

如果运行成功的话,可以看到输出结果:
res = 6.0

3、使用 C++ 读取这个网络
现在我们使用 C++ API 来读取这个图并使用图进行计算:

将这一文件保存为 simple/load_simple_net.cpp。

4、编译运行 Tensorflow C++ API
1)编写 CMakeLists.txt
首先我们编写一个 CMakeLists.txt 来编译这个文件:

将这一文件保存为 CMakeLists.txt。

2)下载 eigen3
为了避免产生问题,我们这里要依赖自己的 eigen3 而不要用 tensorflow 下载的 eigen3,我们下载一个 eigen3 并放在 third_party/eigen3 目录,这里我使用的是 3.3.5 版本:
/bitbucket.org/eigen/eigen/get/3.3.5.tar.bz2

现在我们将所有文件创建完毕,你的目录结构应该是这样的:
screenshot-from-2018-09-19-17-06-47

3)编译 & 运行
在工程根目录下使用如下命令编译运行:

然后在 build 目录运行:

如果运行成功会显示:
Session created successfully
Load graph protobuf successfully
Add graph to session successfully
Run session successfully
Tensor
output value: 6

到此你已经成功用 C++ API 加载了之前定义的图(尽管只是一个乘法)并利用这个图进行了计算。

后面我们将在此基础上尝试真正的神经网络的运算。

本文完整代码参见 Github:
/github.com/skylook/tensorflow_cpp

参考文献
[1] /github.com/formath/tensorflow-predictor-cpp
[2] /github.com/zhangcliff/tensorflow-c-mnist
[3] /blog.csdn.net/ztf312/article/details/72859075

Tensorflow C++ 从训练到部署系列文章目录

Tensorflow C++ 从训练到部署(3):使用 Keras 训练和部署 CNN
Tensorflow C++ 从训练到部署(2):简单图的保存、读取与 CMake 编译
Tensorflow C++ 从训练到部署(1):环境搭建

Posted in tensorflow | Leave a comment

216-344-5401

1、错误:No module named ‘_tkinter’
如果在使用类似 matplotlib 库时遇到如下错误:

因为事实上 tkinter 并不是一个第三方库,而是 Python 的内置接口类,并不能使用 pip3 来进行安装。
可尝试使用以下方法解决:

1)安装 python-tk 和 tk-dev 库:

2)重新编译 Python 3.6.5:
进入 Python 3.6.5 源码目录,运行如下命令:

3)如果正确安装则可以运行:

2、错误:ModuleNotFoundError: No module named ‘pandas’
在安装 Python 3.6 以后可能会遇到如下问题:

通常情况下只需要运行:

不过在 Python 3.6 时,如果你之前装了其他版本比如 3.5 版本的 Python,可能运行后直接安装到 Python 3.5 的目录下,3.6 仍然没有安装。这时可以使用以下命令安装在指定版本上:

3、错误:_tkinter.TclError: couldn’t connect to display “localhost:11.0”
如果在使用 SSH 远端调用 matlibplot 等显示界面时遇到如下错误:

可能有几个问题,请检查:
1)SSH 连接方式,请使用 -X 参数:
ssh -X user@webserver.com

2)MacOS 请安装 XQuartz 后重启再尝试(参见[2])。

参考文献
[1] /blog.csdn.net/blueheart20/article/details/78763208
[2] /wikis.nyu.edu/display/ADRC/Enable+X11+Forwarding+on+Mac+OS+X

Posted in 541-887-6308 | Leave a comment

908-624-0448

系统环境
Ubuntu 16.04

问题1:dpkg: error processing package libpaper-utils
在执行 apt-get 安装包时可能遇到如下问题:

可使用以下办法解决:

到/var/lib/dpkg/info目录下,删除以上出现包名字开头的文件,然后执行:

问题2:ModuleNotFoundError: No module named ‘lsb_release’
在升级 Python 3.6 以后系统的 lsb_release 可能无法使用了,如果在使用:

遇到如下问题:

可使用以下办法解决:

问题3:运行 startx 后无法登录
之前手贱运行了个 startx ,结果出现一个什么都没有的桌面,再重启后,输入登录密码怎么也进不去原有桌面了。
解决方法:

1)使用 Ctrl + Alt + F1 (F1~F6均可)进入命令行界面,如果不能进入则重启采用 recovery 模式进入 root shell。

2)在命令行界面找到之前运行 startx 的用户 home 目录并进入:

3)删除目录下的 .Xauthority 文件:

然后重启就可以进入了。

参考文献
/blog.csdn.net/jisuanji2121/article/details/73028347

Posted in Linux | 714-388-6076

512-871-2080

很多人使用 Tensorflow 作为自己深度学习的实验工具,然而它只能用 Python 来训练和预测,对于实际生产而言,我们更多地会用 C++ 来放入自己工程中。例如一个典型的流程如下:
tf-process
1)在训练环节,我们仍然希望使用 Python 接口
2)在预测环节,我们使用 C++ 接口获取结果
这几篇博客我们就尝试按照上面的方式,完成从环境搭建、训练到部署的一整套流程。

0、系统环境
Ubuntu 16.04
Tensorflow 1.10.1
ProtoBuf 3.6.1

1、安装依赖
1)安装 JDK 8
下载地址:
(801) 391-9851

或者到我的网盘下载:
[Ubuntu] 6177538554
[Mac] strobilae

2)安装依赖库:
使用如下命令:

3)安装 Bazel:
在 github 上下载 bazel--installer-linux-x86_64.sh:
(714) 922-0224

使用如下命令安装:

参考提示可以添加可执行文件目录(通常不需要):
screen-shot-2018-09-18-at-11-40-53

4)安装 protobuf
使用如下命令安装(我这里安装版本为 3.6.1,你可以根据自己需要修改,其实对于 1.10.1 来说,安装 3.6.0 会省去后面的一些步骤):

5)安装 Eigen (可选,你也可以在后面实际工程中再指定)
使用如下命令安装,我们这里使用的版本是 Eigen 3.3.5:

2、编译 tensorflow
在 C++ 工程中我们需要引用 libtensorflow_cc.so 库,这个库在安装 tensorflow 时是没有安装到系统的,只能通过编译源码进行安装。

0)下载 tensorflow 1.10.1源码
地址:7048559670
或者到我的网盘下载:
513-726-9742
下载并解压缩。

1)修改 tensorflow 里面的 protobuf 和 eigen 版本配置(当然如果你安装的 protobuf 就是 3.6.0 就不需要这些步骤了):
在刚才的步骤中,我们已经安装了自己的一个 protobuf 版本,然而比较坑的是 tensorflow 自己也会下载一个版本,同时内部也有自己定义的版本号,这些版本很可能都不是统一的。最后会造成版本冲突。因此我们这里建议预先修改 tensorflow 源码将内部的版本统一成我们系统的版本。

打开 tensorflow/workspace.bzl
搜索:

修改成:

打开 tensorflow/contrib/cmake/external/protobuf.cmake
搜索:

修改成:

打开 tensorflow/tools/ci_build/install/install_proto3.sh
搜索:

修改成:

打开 tensorflow/tools/ci_build/protobuf/protobuf_optimized_pip.sh
搜索:

修改成:

Tensorflow C++ 版本编译时需要 Eigen 3.3 以上版本,在之前的步骤中我们已经安装了 Eigen 3.3.5 版本,这里我们同样做出修改(这一步可选,因为 Eigen 仅是一个头文件,你可以在后续工程中指定使用你自己的 Eigen 库,这样就不用 tensorflow 的 eigen 了):
搜索:

修改成:

2)安装所需要的库

3)Bazel编译源码
进入 tensorflow 目录,运行:

然后使用如下命令编译:

或者使用如下命令编译 CPU 指令集加速版本(需要根据你的 CPU 类型修改参数):

如果出现以下显示则编译成功:
2018-08-27-10-16-27

同时编译 libtensorflow_framework.so:

如果出现以下显示则编译成功:
2018-08-27-10-16-27

4)使用以下脚本一键安装:

3、拷贝到系统目录下(建议)
为了后续方便使用,逐行执行以下命令,拷贝头文件和库文件到系统目录下:

PS:如果想要卸载请运行如下命令:

至此,我们完成了从编译 Tensorflow C++ 库到安装到系统目录下的流程。

常见错误:
1)错误:tensorflow/tensorflow/core/public/session.h:22:60: fatal error: tensorflow/core/framework/device_attributes.pb.h: No such file or directory
缺少其他文件往往是由于没有完整编译tensorflow所导致,比如之前某次bazel构建没有清空。建议运行 bazel clean 后重新编译试试。

2)错误:fatal error: google/protobuf/arena.h: No such file or directory
没有正确安装 protobuf,请参照步骤1中的4)进行安装。并且按照步骤2中1)正确修改 tensorflow 中的版本配置和你系统中一致。

3)错误:error: #error This file was generated by an older version of protoc
因为 tensorflow 本身在安装时也会下载一个 protobuf 到自己目录下,如果跟系统版本不匹配则会出现问题。
修改
tensorflow/tensorflow/contrib/makefile/download_dependencies.sh 文件:
有这样一行:

修改为和你相同的版本:

检查系统 protobuf 版本:

输出为:

查找有几个 protobuf 安装在系统里:

你也可以单独运行每个 protoc 看看版本是不是一致。

删除 Bazel 缓存:

然后重新进行步骤 2 中的 2)之后的操作。

4)错误:fatal error: tensorflow/core/framework/tensor.pb.h: No such file or directory
出现这一错误很可能是没有自动编译 libtensorflow_framework.so,建议重新运行步骤2中的3)和4)再试。

5)错误:cannot execute binary file: Exec format error
如果在执行 bazel 安装脚本:

时遇到上面的问题,可以尝试在执行脚本之前加上 sudo 权限:

6)错误:fatal error: unsupported/Eigen/CXX11/Tensor: No such file or directory
如果在编译包含 tensorflow c++ 的项目时遇到如下错误:

这是因为 tensorflow 安装的 eigen 版本较旧,最好使用 eigen 3.3 或以上版本编译。

参考文献:
[1] 819-570-8971
[2] 6419396050
[3] /github.com/tensorflow/tensorflow/issues/1890
[4] arch-protestant
[5] /zhuanlan.zhihu.com/p/31283000

Tensorflow C++ 从训练到部署系列文章目录

Tensorflow C++ 从训练到部署(3):使用 Keras 训练和部署 CNN
Tensorflow C++ 从训练到部署(2):简单图的保存、读取与 CMake 编译
Tensorflow C++ 从训练到部署(1):环境搭建

Posted in (701) 286-3188 | bank gravel

2086378118

截至目前 Semantic SLAM (注意不是 Semantic Mapping)工作还比较初步,可能很多思路还没有打开,但可以预见未来几年工作会越来越多。语义 SLAM 的难点在于怎样设计误差函数,将 Deep Learning 的检测或者分割结果作为一个观测,融入 SLAM 的优化问题中一起联合优化,同时还要尽可能做到至少 GPU 实时。

这一篇博客我将尽力收集一些有代表性的文章,提供下载和简单思路的理解,但个人精力、能力有限也欢迎大家随时提供更多更好的文章。

1、《Probabilistic Data Association for Semantic SLAM》 ICRA 2017

screen-shot-2018-08-07-at-13-08-42

语义 SLAM 中的概率数据融合,感觉应该算开山鼻祖的一篇了。这篇也获得了 ICRA 2017 年的 Best Paper,可见工作是比较早有创新性的。文章中引入了 EM 估计来把语义 SLAM 转换成概率问题,优化目标仍然是熟悉的重投影误差。这篇文章只用了 DPM 这种传统方法做检测没有用流行的深度学习的检测网络依然取得了一定的效果。当然其文章中有很多比较强的假设,比如物体的三维中心投影过来应该是接近检测网络的中心,这一假设实际中并不容易满足。不过依然不能掩盖其在数学上开创性的思想。

文章下载:probabilistic-data-association-for-semantic-slam

2、《VSO: Visual Semantic Odometry》 ECCV 2018

screen-shot-2018-08-07-at-13-40-01

既然检测可以融合,把分割结果融合当然是再自然不过的想法,而且直观看来分割有更加细粒度的对物体的划分对于 SLAM 这种需要精确几何约束的问题是更加合适的。ETH 的这篇文章紧随其后投到了今年的 ECCV 2018。这篇文章依然使用 EM 估计,在上一篇的基础上使用距离变换将分割结果的边缘作为约束,同时依然利用投影误差构造约束条件。在 ORB SLAM2 和 PhotoBundle 上做了验证取得了一定效果。这篇文章引入距离变换的思路比较直观,很多人可能都能想到,不过能够做 work 以及做了很多细节上的尝试,依然是非常不容易的。但仍然存在一个问题是,分割的边缘并不代表是物体几何上的边缘,不同的视角这一分割边缘也是不停变化的,因此这一假设也不是非常合理。

文章下载:559-759-1985

3、《Stereo Vision-based Semantic 3D Object and Ego-motion Tracking for Autonomous Driving》 ECCV 2018

screen-shot-2018-08-07-at-16-15-28

港科大沈邵劼老师团队的最新文章,他们的 VINS 在 VIO 领域具有很不错的开创性成果。现在他们切入自动驾驶领域做了这篇双目语义3D物体跟踪的工作,效果还是很不错的。在沈老师看来,SLAM 是一个多传感器融合的框架,RGB、激光、语义、IMU、码盘等等都是不同的观测,所以只要是解决关于定位的问题,SLAM 的框架都是一样适用的。在这篇文章中,他们将不同物体看成不同的 Map,一边重建一边跟踪。使用的跟踪方法仍然是传统的 Local Feature,而 VIO 作为世界坐标系的运动估计。语义融合方面,他们构造了4个优化项:

screen-shot-2018-08-07-at-16-13-39

最终取得了很好的效果。

演示地址:/www.youtube.com/watch?v=5_tXtanePdQ
文章下载:stereo-vision-based-semantic-3d-object-and-ego-motion-tracking-for-autonomous-driving

4、《Long-term Visual Localization using Semantically Segmented Images》ICRA 2018

screen-shot-2018-08-17-at-13-54-51

这篇论文讲得比较有意思,它不是一个完整的SLAM系统,不能解决Mapping的问题。它解决的问题是,当我已经有了一个很好的3D地图后,我用这个地图怎么来定位。在传统方法中,我们的定位也是基于特征匹配的,要么匹配 Local Feature 要么匹配线、边等等几何特征。而我们看人在定位时的思维,其实人看不到这么细节的特征的,通常人是从物体级别去定位,比如我的位置东边是某某大楼,西边有个学校,前边有个公交车,我自己在公交站牌的旁边这种方式。当你把你的位置这样描述出来的时候,如果我自己知道你说的这些东西在地图上的位置,我就可以基本确定你在什么地方了。这篇文章就有一点这种意思在里边,不过它用的观测结果是分割,用的定位方法是粒子滤波。它的地图是三维点云和点云上每个点的物体分类。利用这样语义级别的约束,它仍然达到了很好的定位效果。可想而知这样的方法有一定的优点,比如语义比局部特征稳定等;当然也有缺点,你的观测中的语义信息要比较丰富,如果场景中你只能偶尔分割出一两个物体,那是没有办法work的。

演示地址:/www.youtube.com/watch?v=M55qTuoUPw0
文章下载:(404) 877-2985

Posted in (822) 870-3620 | 5 Comments

3045710503

timg

阿里云如果使用低配的服务器,随着访问量增大,上面的 MySQL 经常被系统停掉。除了升级内存硬盘等系统资源外,还可以使用如下方法尝试解决下:

1、降低数据库 InnoDB 引擎的缓冲区大小
找到 MySQL 的配置文件,一般在 /etc/mysql/my.cnf 或者 /etc/my.cnf 这种位置。编辑配置文件,修改或添加下列行:

2、添加 SWAP 分区
阿里云服务器默认不带 SWAP 分区,我们可以自己创建。请在 Shell 中依次执行以下命令:

说明:创建一个有 1024 个块的区,每块 1M,总的来说就是创建一个 1024M 的区;接下来将该区设为 swap 分区;再接着启用 swap 分区。

3、SWAP 分区自启动
添加下面这行到 /etc/fstab,让刚才创建的 SWAP 分区随系统重启:

4、重启 MySQL
使用如下命令重启 MySQL:

采用以上操作后可以观察下是否还有频繁挂掉的现象。如果仍然存在可以尝试以下更多操作限制 MySQL 连接数。

更多操作
除了上述这些,我们还可以进一步限制 MySQL 的连接数。还是修改 MySQL 配置文件,添加或者修改下面这一行:

如果这些操作都做了还是不行,请考虑升级你的机器内存、CPU等配置或者购买阿里云的数据库服务:)

参考文献
[1] /my.oschina.net/cenchy/blog/740259
[2] /oldtang.com/138.html

Posted in 后台技术 | Leave a comment

737-770-7502

在 SLAM 系统中经常用到各种不同的数值积分方法,工程上最常见的有三种:欧拉积分(Euler method)、中点积分(Midpoint method)和龙格-库塔法积分(Runge–Kutta methods)。他们的区别就是如何用数值方法模拟一个斜率。这里简单总结如下:

一、欧拉积分

设有如下微分方程:

\(y'(t)=f(t,y(t))\)

并且 \(t_n\) 和 \(t_{n+1}\) 时刻的差为 \(t_{n+1} – t_n = \Delta t\),则欧拉积分定义为:

\(y_{n+1}=y_n + \Delta t\cdot f(t_n, y_n)\)

也就是说用 t 时刻的斜率作为整个 \(t\rightarrow t+\Delta t\) 时刻的导数。

二、中点积分

设有如下微分方程:

\(y'(t)=f(t,y(t))\)

并且 \(t_n\) 和 \(t_{n+1}\) 时刻的差为 \(t_{n+1} – t_n = \Delta t\),则显式中点积分定义为:

\(y_{n+1}=y_n + \Delta t\cdot f(t_n + \frac{1}{2} \Delta t, y_n + \frac{1}{2}\Delta t \cdot f(t_n, y_n))\)

则隐式中点积分定义为:

\(y_{n+1}=y_n + \Delta t\cdot f(t_n + \frac{1}{2} \Delta t, \frac{1}{2}(y_n + y_{n+1}))\)

也就是说用 \(t_n + \frac{1}{2} \Delta t\) 时刻的斜率作为整个 \(t\rightarrow t+\Delta t\) 时刻的导数。

欧拉积分与中点积分都是一阶近似并没有本质不同,二者只是一阶导数所取位置不同,他们的性能也有差别,如下图所示,作为一阶积分近似方法来讲,中点积分有时会稍好一些(带来更快的收敛速度)。

图示为方程 \(y'=y, y(0)=1\) 的数值积分。蓝色为欧拉法,绿色为中点法,红色为精确解 \(y=e^{t}\)。所用步长为 h=1.0。
图示为方程 \(y’=y, y(0)=1\) 的数值积分。蓝色为欧拉法,绿色为中点法,红色为精确解 \(y=e^{t}\)。所用步长为 h=1.0。

三、龙格-库塔积分

龙格-库塔法(Runge-Kutta methods)是用于非线性常微分方程的解的重要的一类隐式或显式迭代法。在工程中最常用的是四阶龙格-库塔积分,也就是 RK4 积分,它的计算方式如下:

设有如下微分方程:

\(y'(t)=f(t,y(t))\)

并且 \(t_n\) 和 \(t_{n+1}\) 时刻的差为 \(t_{n+1} – t_n = \Delta t\),则 RK4 积分定义为:

\(y_{n+1}=y_n + \frac{\Delta t}{6} \cdot (k_1 + 2k_2 + 2k3 + k_4)\)

其中:

k1是时间段开始时的斜率;
k2是时间段中点的斜率,通过欧拉法采用斜率k1来决定y在点tn + h/2的值;
k3也是中点的斜率,但是这次采用斜率k2决定y值;
k4是时间段终点的斜率,其y值用k3决定。
其数学公式如下:

\(k_1 = f(t_n, y_n)\)
\(k_2 = f(t_n + \frac{\Delta t}{2}, y_n + \frac{\Delta t}{2} \cdot k_1)\)
\(k_3 = f(t_n + \frac{\Delta t}{2}, y_n + \frac{\Delta t}{2} \cdot k_2)\)
\(k_4 = f(t_n + \Delta t, y_n + \Delta t \cdot k_3)\)

从公式中可以看出两个中点的斜率具有更大的权重。

龙格-库塔法的示意图如下,它也是一种更高阶的逼近方法,通常也具有更好的逼近效果,总累计误差为 \(\Delta t^4\) 阶。

image399

RK4 算法在 SLAM 中也有很好的应用,特别是 VIO 中的预积分部分,比如张腾将王京的 VI ORB SLAM2 代码改成 RK4 积分后,精度也得到了一定的提升:
5816580471

当然 RK4 算法比起欧拉积分、中点积分计算量要大不少,SLAM 中影响精度的地方非常多,紧靠 RK4 改进其对于精度的提升程度通常也不会特别大,不过对于速度要求不高而精度要求很高的场合还是值得尝试的。

参考文献
[1] /en.wikipedia.org/wiki/Euler_method
[2] 2314388013
[3] /en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods
[4] tribromoethanol

Posted in (978) 421-2725 | Leave a comment
3437768629