0%

In order to deploy MXNet based vision engine to projects develped in C++, we need to compile MXNet CPP API. Though the instruction of how to compile is well illustrated in Build from Source and Build the C++ package, I still confronted some difficulties. This blog records some tips for compling MXNet CPP API.

  1. Modify Source Code

    By following the instruction, I could easily complie and get the libmxnet. However, when compling cpp-package, the op.h file can not be generated correctly. In issues#14116, Vigilans provided a solution.

    Here: https://github.com/apache/incubator-mxnet/blob/master/include/mxnet/tuple.h#L744

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    namespace dmlc {
    /*! \brief description for optional TShape */
    DMLC_DECLARE_TYPE_NAME(optional<mxnet::TShape>, "Shape or None");
    MLC_DECLARE_TYPE_NAME(optional<mxnet::Tuple<int>>, "Shape or None");
    // avoid low version of MSVC
    #if !defined(_MSC_VER) // <----------- Here !
    template<typename T>
    struct type_name_helper<mxnet::Tuple<T> > {
    static inline std::string value() {
    return "tuple of <" + type_name<T>() + ">";
    }
    };
    #endif
    } // namespace dmlc

    So the specialization of mxnet::tuple was disabled for Visual Studio in the first place!
    I removed the #if block, recompile, then everything works fine.

  2. Set the Environment Variables

    In my own case, I only needed to set OpenBLAS_HOME and OpenCV_DIR. Both of the can be set by set command or -D in cmake config.

  3. Use CMake to generate VS solution

    cmake -G "Visual Studio 14 2015 Win64" -DUSE_CUDA=0 -DUSE_CUDNN=0 -DUSE_NVRTC=0 -DUSE_OPENCV=1 -DUSE_OPENMP=1 -DUSE_BLAS=open -DUSE_LAPACK=0 -DUSE_DIST_KVSTORE=0 -DUSE_CPP_PACKAGE=1 -DCMAKE_INSTALL_PREFIX=install ..

    Above command can be used to generate a solution without GPU support. By modifying config -DUSE_CUDA and -DUSE_CUDNN, we can generate a solution with GPU support.

  4. Generate op.h

    After generating libmxnet, we should run python OpWrapperGenerator.py libmxnet.dll to generate op.h. Note to place libmxnet.dll, libopenblas.dll and libopencv_world.dll together with OpWrapperGenerator.py.

  5. No mxnet_static.lib

    The cpp example project failed to link to mxnet_static.lib, which was actually named as libmxnet.lib. I modified the name of the static library. I believe the project settings can be fixed to cope with this problem.

The main steps can be found on mxnet install instruction. When following the steps, I’ve confronted with some errors.

1. nvcc path error

set the correct path using environment path, or modify USE_CUDA_PATH in config.mk

2. Error 137

It’s because of lack of memory when compiling. We need to add a swap file in size 2G

1
2
3
dd if=/dev/zero of=/swapfile bs=1k count=2048000
mkswap /swapfile
swapon /swapfile

3. openblas link error

install openblas-dev by sudo apt-get install libopenblas-dev

4. compile error when installing numpy

install python-dev by sudo apt-get install python-dev

5. gluoncv dependencies

1
2
3
4
sudo apt-get install libfreetype6-dev
sudo apt-get install pkg-config
sudo apt-get install libpng12-dev
sudo apt-get install libjpeg-dev

6. image.io error when testing GluonCV

Need to compile libmxnet.so with OpenCV. Modify USE_OPENCV in config.mk. set USE_OPENCV = 1

TITLE: CSRNet: Dilated Convolutional Neural Networks for Understanding the Highly Congested Scenes

AUTHOR: Yuhong Li, Xiaofan Zhang, Deming Chen

ASSOCIATION: University of Illinois at Urbana-Champaign, Beijing University of Posts and Telecommunications

FROM: arXiv:1802.10062

CONTRIBUTION

  1. a pure fully convolutional network (CSRNet) is proposed for understanding the highly congested scenes.
  2. CSRNet achieves the state-of-the-art performance on four datasets (ShanghaiTech dataset, the UCF CC 50 dataset, the WorldEXPO’10 dataset, and the UCSD dataset).

METHOD

CSRNet Architecture

The proposed CSRNet is composed of two major components:

  1. a convolutional neural network (CNN) is utilized as the front-end for 2D feature extraction.
  2. a dilated CNN follows the front-end for the back-end, which uses dilated kernels to deliver larger reception fields and to replace pooling operations.

In this work, the front-end CNN is same as the first ten layers of VGG-16 with three pooling layers, considering the tradeoff between acuracy and the resource overhead. The back-end CNN is a series of dilated convolutional layers and the last layer is a $ 1 \times 1 $ convolutional layer producing density map. The network architecture is shown in the following figure

Architecture

Training

The ground truth is generated using geometry-adaptive kernels to tackle the highly congested scenes. By blurring each head annotation using a Gaussian kernel (which is normalized to 1), the ground truth is generated considering the spatial distribution of all images from each dataset.

9 patches are cropped from each image at different locations with 1/4 size of the original image. The first four patches contain four quarters of the image without overlapping while the other five patches are randomly cropped from the input image. After that, double the training set by mirroring the patches.

PERFORMANCE

Architecture Comparison

Performance Shanghai

Performance UCF

Performance WorldExpo

Performance UCSD

SOME THOUGHTs

  1. How about using more advanced CNNs?

TITLE: CornerNet: Detecting Objects as Paired Keypoints

AUTHOR: Hei Law, Jia Deng

ASSOCIATION: University of Michigan

FROM: arXiv:1808.01244

CONTRIBUTION

  1. CornerNet, a new one-stage approach to object detection is introduced that does without anchor boxes. We detect an object as a pair of
  2. a new type of pooling layer, coner pooling, that helps a convolutional network better localize corners of bounding boxes is introduced.

METHOD

Motivation

The use of anchor boxes has two drawbacks.

First, a very large set of anchor boxes are of need, e.g. more than 40k in DSSD and more than 100k in RetinaNet. This is because the detector is trained to classify whether each anchor box sufficiently overlaps with a ground truth box, and a large number of anchor boxes is needed to ensure sufficient overlap with most ground truth boxes, leading to huge imbalance between positive and negative anchor boxes.

Second, the use of anchor boxes introduces many hyperparameters and design choices. These include how many boxes, what sizes, and what aspect ratios. Such choices have largely been made via ad-hoc heuristics, and can become even more complicated when combined with multiscale architectures.

DetNet Design

In CornerNet, an object is detected as a pair of keypoints, the top-left corner and bottom-right corner of the bounding box. A convolutional network predicts two sets of heatmaps to represent the locations of corners of different object categories, one set for the top-left corners and the other for the bottom-right corners. The network also predicts an embedding vector for each detected corner such that the distance between the embeddings of two corners from the same object is small. To produce tighter bounding boxes, the network also predicts offsets to slightly adjust the locations of the corners. The framework is illustrated in the following figure.

Framework

To generate heatmaps, embeddings and offsets, the following network structure is utilized. The heatmaps’ goal is detecting corners. The embeddings are used to group corners that belong to the same object. Conner pooling is used in the network to extract features for corner detection.

Framework

The annotation of heatmaps is generated in a way that similar to that in detection joints in pose estimation methods. Embeddings are generated within pairs that generated from corners. The offsets are regressed from the difference between actual division of coordinates and downsampling ratio and the floored division.

The backbone of the network is two hourglasses.

PERFORMANCE

Performance

SOME THOUGHTs

  1. How to select numbers of hourglasses?
  2. The speed of the method is slow. The average inference time is 244ms per image on a Titan X.
  3. The key of the method is detecting corners and more work can be done in this task.

最近刚刚搬了家,突然有一些不一样的感受,最深刻的感受是跟过去的一次告别。

首先,就是因为懒。要收拾的东西太多,有些东西仔细想想好像一年也没怎么用过,甚至自从上一次搬家就没用过,它就一直在某个角落落灰。到了这次搬家,看着它脏脏的样子,掂量掂量还有点分量,再一想那边已经堆了十个收纳箱了,这东西就算了吧,遂直接留给房东,或者直接丢进垃圾箱。

等东西都搬到了新屋子,发现户型、家具都不一样,以前摆在外面的陈设要么跟房间不搭配、要么没有地方放,就收在收纳箱里。这些陈设可能是我们珍视的合影、得奖的奖状、前公司的工牌……那些定义了我们曾经是谁的东西都被收藏了起来。在搬家之前,它们潜移默化地提醒着我们曾经的经历,但是现在却会慢慢被遗忘了。

搬了新家,自然还要制备一些新事物,这可是体现我们喜新厌旧本性的时候。新买的肯定会得到更多的宠爱,而那些颜老色衰的就被慢慢冷落了。等下次再搬家的时候,估计它们就是那些被留下的一批了。

Rencently I’ve been trying to update my Ubuntu16.04 using apt and it failed again and again. At first, I thought it was because of the GFW and the sources. It turned out that any effort on these settings was in vain.

At last, after analyzing the update logs and digging into my deepest memories, I found that it was because I installed Nvidia JetPack to use Jetson TX1/2. I had to remove a pile of things related to JetPack by following commands.

1
2
apt-get remove .*:arm64
dpkg --remove-architecture arm64

写在30岁之前

人还是需要一些仪式感的,自从2017年7月份开始出来创业,自己的仪式感越来越弱,很多事情能省就省。可能过了刚刚出来日日担心饭辙的阶段,也可能是被折磨得麻木了,现在倒觉得人活着还是要开心一些想开一些,该有的仪式感还是要有,不然这日子过得挺没意思。因此,为了迎接自己的30岁,在这里胡乱絮叨絮叨。

除了仪式感,其实本来早就想写一写近期以来的感受,尤其是创业以来,随着角色的转变,不管是主动的还是被迫的,内心里有很多感触。有些时候,总不知道这些感受该对谁说。可能跟谁说,谁都会觉得我的感触都是一种矫情,写出来也权当一种发泄。

2007-2011

想了想,既然是写在30岁之前,除了这一年半的创业,还不如再往前追溯追溯,从高考开始写吧。都过去十年了,现在还能想起来的那些事,估计就是我人生中最重要的一些标记了。

高考

当时老师家长为了缓解大家的压力:人生今后遇到的坎多了,回过头来看高考真不算什么。不知道十年后有多少人真的是这样的感受,我不敢说高考真不算什么,起码它是我到现在的人生轨迹的起点。另外,这也真是一个坎。

高考前的那两个月一直很凉爽,经常下雨,不知道是不是就是因为贪凉,我的咳嗽一直没好。高考前第二天下了大雨,高考前一天放晴,天气突然很热。下午我在自习室里感觉身上很难受,忽冷忽热的,就去医务室量了体温,39度的高烧。也不知道是谁帮我找的老师,谁给我父母打了电话,印象中傍晚的时候家里开车来接我。临上车,我的语文老师对我说:志轩,没事!到了医院,大夫说是肺炎,不记得是不是说让我住院了,我说明天我要高考。在医院输了两个小时液,回家。现在已经完全不记得当晚是什么感受了。

高考第一天上午考语文,下午考数学。考语文的时候很虚弱,全身都没有力气,有一种世界离我而去的感觉,视野也在变窄。最后写作文,作文题目里有一首诗,完全没有读懂那首诗是什么意思,硬着头皮写。那感觉就好像在潜水,肺一直被水压着,呼吸困难。支持着我写完的就一个念想:考不上我认了,但是我绝不能因为没考完而去复读。下午考数学之前又开始发烧,去医务室打退烧针,大夫跟我说一定要多喝水,因为退烧需要出大量的汗来散热,很容易因为脱水而虚脱。下午我就是在湿透的衬衫下进行考试,估计也是因为太虚弱了,也没有什么胡思乱想,很专心的答题。晚上回去接着发烧,折腾半宿。

高考第二天上午考理综,下午考英语。身体状态和第一天差不多,心理状态倒好了很多,估计就是破罐破摔了。考试这两天几乎一点东西都没吃,吃了也吐出来。考完试,二话没说直接就去医院住院,高烧不退三四天吧。后来看拍的胸片,右边肺全部感染,左边肺一小半感染。我是直接略过了别人考完忐忑等成绩的那几天,住院半个月,直到出分去学校领成绩单。成绩也算反映了我的状态,语文考得是一塌糊涂,数学因为心态平稳考了个一般分,理综创纪录地考了一个历史最高,英语向来是我的长项,但是那一年题太简单,完全没有拉开分数段。有惊无险地考到了北邮,当时北京是考前报志愿,很保守地报了北邮,估计也是因为这样才能心态平稳地发挥。

学生会

在北邮的本科四年,印象最为深刻的应该就是学生会。在学生会的经历重塑了我的性格,在学生会结识的朋友是我一生的挚友。还记得那一个个奋斗的夜晚、跟春晚一样长的例会、北门的砂锅聚餐……

从小我其实是一个很内向而且自卑的人,也不爱说话。小时候见到父母的同事,从来也不叫人、不说话,跟自己家人说话都是“惜字如金”,“自来水”不说“自来水”,只说“自来”。上了大学之后,觉得自己这样不行啊,得尝试改变一下。听师兄师姐说在学生会能锻炼人,于是也就想着加入学生会吧。小时候喜欢鼓捣一些小制作,也喜欢在电脑上用PS做一些图,看来看去觉得科技部很适合我,于是就加入了科技部。大一做干事,大二做部长,大三做学生会副主席。这两三年,的确让我变得开朗了很多,有时候我甚至觉得这几年的学生会打开了我的一个开关,让我变得太贫了。但不可否认的,在学生会让我变得自信了。

在学生会里,有两个人我要尤其感谢,一个是枫哥,另一个是小昭。

枫哥当时是我们的分团委书记,学生会的直接领导,北邮土著,从本科一直到现在都在北邮,绝版青春的Logo代表着一段传奇。对于枫哥,一方面打心眼里敬重,得叫一声老师。另一方面,跟枫哥特别投脾气,私下里叫一声枫哥,亲近了很多。枫哥是我的贵人,后来能够读研,枫哥的推荐起了很大作用。枫哥也是我步入职场的启蒙导师,很多影响都是潜移默化的。嗯,还有就是变贫了,也是天天跟枫哥说相声练出来的。

小昭让我第一次接触到了计算机视觉,让我找到了我的兴趣所在,以及此后的硕士研究方向和毕业后的职业发展方向。大三的时候受小昭邀请,一起组队参与大创,我们的项目主要内容是检测人员摔倒并报警。现在看来,当时的算法思想十分简朴,但是让我第一次体验了如何通过科学实验验证自己的假设并解决问题,也让当时迷茫的我,找到了未来的方向,直到现在我依旧对计算机视觉抱有极大的热忱。如果没有小昭当时的邀请,估计我不会这么幸运地找到一个让我一直抱有兴趣的方向。

07112

07112应该是我们那一届凝聚力最强的班级了吧,大家一起耍的日子里也是各种各样的嗨。那时候每年都要参加评优活动,每到这个时候,就要做一个五分钟左右的视频来展示班级的珍贵回忆,但是五分钟实在实在太短了,根本不可能把我们一起经历的事情展示完,每次都要费尽心思地压缩。我们有太多的并肩奋斗,有太多的携手共度,有太多太多的美好回忆。

2011-2014

本科四年算是开开心心地玩过去的,接下来就是努力科研的研究生三年。真的很幸运可以在MCPRL读硕士。

科研

我应该是我们实验室考研分数最低的,毕业答辩的时候庄老师说:要不是实验室刚好多出一个名额,你就只能去找调剂了。很幸运我能够在实验室读研,在实验室所做的工作让我积累了很多在计算机视觉领域内的经验,锻炼了我实现算法的编码能力,以及在实际中提出问题、思考问题、解决问题的能力。

我在实验室没有做过任何横向或纵向项目,一直都是做TRECVID SED国际评测。这是一个监控视频事件检测任务,我们当时关注的事件包括”指 Pointing“、 “放东西 ObjectPut”、“跑 PersonRuns“、“拥抱 Embrace”、“聚集 PeopleMeet”和“分离 PeopleSplitUp”。做这个竞赛的好处就是让我对计算机视觉的基本问题都有了比较系统的了解,而且做了多个方面的工作,包括行人检测、多目标跟踪、人体姿态估计、动作识别、事件检测……

我记得研三在写毕业论文的时候,很多同学好像还在发愁写什么,我真的是忍不住想要多写一些,给大家分享我所做的工作,学到的知识,以及我对那些问题的思考。刚刚又去翻看了一下自己的毕业论文,最后的致谢是这样写的:

时光荏苒, 两年半的硕士研究生阶段就要结束了, 在此我必须对关心、指导和帮助过我的老师、同学和朋友们表达最衷心的感谢!

首先感谢赵衍运副教授在这两年多来对我的指导和帮助。赵老师严谨的治学态度和一丝不苟的工作精神时时刻刻都在激励并提醒我在科研中要勤奋刻苦、不能有半点马虎。同时,赵老师与我们分享她的人生阅历,也使我在科研之外的生活中获益匪浅。

同时感谢蔡安妮教授,蔡老师看问题的深刻程度和对问题的整体把握度都令我折服,蔡老师每一次参加我主讲的组会都会问到我准备最薄弱的部分,都会提出一些让我获得启发的问题, 和蔡老师的每一次交流都使我有所收获。还要感谢苏菲教授、庄伯金副教授和赵志诚老师,他们也在我的学业和科研中给予了极大的指导和帮助。

此外,还要感谢我的家人和实验室的同学,他们都在我需要的时候给我莫大的鼓励、帮助和安慰,使我不断战胜困难。最后,对所有支持、帮助过我的老师、同学和朋友致以最诚挚的谢意!

直至今天,每当想起实验室,还是这些感谢的话。

寒文轩

“寒文轩”是由三个人的名字中各取一个字组成的。

寒:小寒姐是一个精灵古怪的女孩,爱玩,很活泼也很有想法。读研期间小寒姐去西班牙交流了半年,搞科研的同时,不耽误自己在欧洲转了大半圈。跟小寒姐在一起聊天,会有一种感觉:世界上没有什么事是大不了的。

文:小F杰是那种让我羡慕的文艺青年,读了万卷书,行了万里路,追随自己内心的男子。他给自己取的昵称叫做“霞客”,非常合适。我们这个小团体的名字也是小F杰取的,也只有他能想到这么有才华的名字。小F杰应该是我们那一届考研分数第一。

轩:就是我自己了。

2014-2017

2014年硕士毕业了,到三星通信研究院工作,在这里积累了很多,结识了一帮技术达人,工作很开心,成长为职场人,不舍地离开。

现在,在计算机视觉领域最流行的框架应该就是卷积神经网络了,在我读研期间,其实完全没有接触过,到了三星之后才真正开始研究和使用卷积神经网络。2013年至2016年是深度学习大爆发的一段时间,每天都有各种各样的新理论、新结构、新方法被发表出来。因为三星特有的周期性研发节奏,让我有足够的时间汲取消化大量的新知识,并将这些技术应用到实际产品中,在这样的过程中,我也积累了宝贵的经验。在三星,参加竞赛、发专利、去韩国总部开发做报告、参与旗舰机功能的研发……还有一点就是做PPT的技术极大提升。

我们小组人员最齐整的时候有八个人,每个人有擅长的领域,也各有自己的性格,大家都是互相欣赏。我们几个人配合起来效率很高,有些工作甚至感觉像流水线一样,经过几个人的处理,马上就出活了。在技术上,大家的交流也很多,我从每一位身上都学到了很多。也正是这些同事,让我每天都十分开心地去上班,有一种打心眼里热爱工作和生活的感觉。

也正是这些小伙伴,让我最终从三星离职,其实在三星工作的期间,真的很开心。我也对当时的领导和同事抱有极大的感恩之心,是他们让我顺利地转变了角色,我也能体会到领导对我的重视和培养,也取得了一些成绩。但是,当身边的小伙伴一个个地离职的时候,用我们开玩笑的话来说就是:有一种失恋的感觉。我们八个人的小团体后来就以“图像叛将小分队”自称了,虽然大家现在在不同的公司,但都一直保持着联系,我相信职场中很少能有这样的感情。记得枫哥曾问过我,对我的工作打多少分,我说9.5分。

2017-今天

这一年多,按说应该是感触最多的一年。但是,猛地一想,好像没法很好的进行总结,或许是因为这些感触还需要沉淀,来一波意识流吧。

创业

创业其实就是为了折腾。当初选择创业就是想趁年轻折腾折腾,纯粹就是为了折腾。在选择创业之前,我还申请过英国的PhD。14年的12月到2月,工作日上班,周末去上雅思课,自己准备研究计划书,套词……很遗憾没能成行,现在想想就当提升英语能力了。读PhD没折腾成,就选择创业吧。

创业真不是人干的。在大公司里工作有个好处,尤其在大外企里工作,很容易就可以做到工作生活两不误。工作上,只要做好自己拿一份工作,只要不断提升自己的专业技能,几乎不用再操其他心了。节假日里,大可小资一番,旅游、读书、追剧、画画、健身、望天发呆……自从开始创业,尤其是最开始的三个月,一直都很焦虑,最大的焦虑来自于对未来的不确定性,不知道公司可以走多久走多远。然后是一团乱麻的工作,在大企业里,有各个部门来共同服务员工,各司其职,但是创业就是所有事都要自己操心,什么事都得想着,什么事都得惦记着。从一个研发人员转型为一个管理人员,这个角色转变太难了。而且作为一个草根创业者,我必须既是研发人员又是管理人员。可能我的创业伙伴可以在创业这件事本身上寻找到快乐,但是我是一个必须在生活中寻找乐趣的人,但是自从创业之后,哪怕周末没有去公司,心里其实也总是惦记着公司的事,好像不能完全放松,因此有时候总觉得生活没啥乐趣。哪怕有些时候真是有个半天空闲,现在都不知道可以干点什么了。

创业真的锻炼人。草根创业就是要做各种各样的工作,因此从技术上来说,我会接触到各种各样的场景,在尝试解决这些不同问题的时候,也是对自己技术的一种锻炼。除了技术,剩下更多的就是对心智的锻炼。提升最多是抗压能力,不管是面对别人的质疑挑战、deadline的压力、未知数的恐惧,也可能是麻木了,反正有时候会觉得无所谓。

创业可以让人对自己更加了解,诌一句英文就是:know who I am。上面的很多感受其实就是创业之后才知道的,比如我要从生活中获取乐趣;相比较跟人打交道,我更擅长跟机器打交道;我是一个相当保守的人;我相对来说比较固执;《三国演义》里形容袁绍的“多谋寡断”也适合我;我会逃避现实,做一些自我欺骗的事……

感谢创业路上一起拼搏的兄弟姐妹,感谢合作伙伴,感谢那些踩过的坑吧。

六人行

拿《老友记》形容我们再合适不过了,一行六人,三男三女,从小到大的死党。去年我们聚会之后还说,大家都有自己的小生活啦,可是见面还是以前的感觉,真好。大家要多聚聚,以后没准就是孩子们一起玩,我们一起打麻将。无论什么时候,每当那首《I’ll be there for you》响起,我都会想起我们六个人。说起来真是奇怪,越是深沉的感情,好像能够表达的语言反而越少,有的就是心里那种一团暖暖的感觉。

十年恋爱

这个感触太多,酸甜苦辣咸,其中百味估计要单独写了。感谢张大夫一直以来的陪伴。

30岁

说起30岁,感觉这真是一个坎,对于我自己而言可能就是:要接受自己是一个普通人了。27、28岁的时候,可能还能厚着脸皮谈理想。但是到了现在,估计只有一起创业的小伙伴们,一起喝酒之后,才会再提起理想吧。他们说只有等你有了孩子,才算真正长大了。我感觉自己好像还没准备好长大,就已经不能再说不想长大了。

2008-2018