Ubuntu 16.04开启dlib对于AVX或者CUDA的支持

最近在使用openface来测试人脸识别,实际过程中发现识别速度非常缓慢,平均每帧的识别速度达到了秒级水平,这个是不可接受的。跟踪代码性能,发现是dlib部分非常缓慢。

根据dlib的文档,默认使用

$ sudo pip install dlib

安装的dlib库,由于对具体硬件的要求(CPU需要支持AVX指令集),是没有开启AVX指令加速的,另外由于显卡的要求,也是默认不开启CUDA的支持。

如果想要开启这部分加速,需要手工编译安装才可以,具体操作如下:

$ cd ~
$ mkdir dlib
$ sudo pip download dlib
$ tar -zxvf tar -zxvf dlib-*.tar.gz
$ cd dlib*

#安装依赖的库
$ sudo apt-get -y install libopenblas-dev

#移除我们以前安装过的dlib
$ sudo pip uninstall dlib

#开启AVX指令集支持
$ sudo python setup.py install --yes USE_AVX_INSTRUCTIONS

上面的命令是使用AVX指令加速功能的,如果机器上安装了CUDA,则需要正确安装cuDNN 5.0以上的版本,否在编译的时候会报告

-- Checking if you have the right version of cuDNN installed.
-- *** Found cuDNN, but it looks like the wrong version so dlib will not use it. ***
-- *** cuDNN V5.0 OR GREATER NOT FOUND.  DLIB WILL NOT USE CUDA. ***
-- *** If you have cuDNN then set CMAKE_PREFIX_PATH to include cuDNN's folder.

对于使用

$ sudo apt install nvidia-cuda-toolkit

安装的CUDA-7.5来说,可以从这里下载cuDNN v6.0 (April 27, 2017), for CUDA 7.5,下载完成后,整个目录中的include目录中的文件解压缩到/usr/local/include/目录下,lib64目录中的内容整个解压缩到/usr/lib/目录下,并且在/usr/local/lib/目录下建立libcudnn.so的软链接

$ sudo ln -s /usr/lib/libcudnn.so /usr/local/lib/libcudnn.so

都配置正确后,使用如下编译命令安装:

$ sudo python setup.py install --yes DLIB_USE_CUDA

参考链接


Easily Create High Quality Object Detectors with Deep Learning

执行"luarocks install cutorch"发生错误"error: implicit declaration of function 'THLongStorage_calculateExpandGeometry'"

执行

$ luarocks install cutorch

发生如下错误:

[ 88%] Building C object lib/THC/CMakeFiles/THC.dir/THCStorageCopy.c.o
In file included from generic/THCTensor.c:1:0,
                 from /tmp/luarocks_cutorch-scm-1-8069/cutorch/lib/THC/THCGenerateAllTypes.h:17,
                 from /tmp/luarocks_cutorch-scm-1-8069/cutorch/lib/THC/THCTensor.c:7:
/tmp/luarocks_cutorch-scm-1-8069/cutorch/lib/THC/generic/THCTensor.c: In function ‘THCudaByteTensor_newExpand’:
/tmp/luarocks_cutorch-scm-1-8069/cutorch/lib/THC/generic/THCTensor.c:304:3: error: implicit declaration of function ‘THLongStorage_calculateExpandGeometry’ [-Werror=implicit-function-declaration]
   THLongStorage_calculateExpandGeometry(tensor->size,
   ^
[ 90%] Building C object lib/THC/CMakeFiles/THC.dir/THCThreadLocal.c.o
cc1: some warnings being treated as errors
lib/THC/CMakeFiles/THC.dir/build.make:686: recipe for target 'lib/THC/CMakeFiles/THC.dir/THCTensor.c.o' failed
make[2]: *** [lib/THC/CMakeFiles/THC.dir/THCTensor.c.o] Error 1
CMakeFiles/Makefile2:172: recipe for target 'lib/THC/CMakeFiles/THC.dir/all' failed
make[1]: *** [lib/THC/CMakeFiles/THC.dir/all] Error 2
Makefile:127: recipe for target 'all' failed
make: *** [all] Error 2

Error: Build error: Failed building.

解决方法为:

$ luarocks install torch
$ luarocks install cutorch

参考链接


error: implicit declaration of function ‘THLongStorage_calculateExpandGeometry’

编译Torch 7时遇到错误"make[2]: *** [lib/THNN/CMakeFiles/THNN.dir/init.c.o] Error 1"

编译Torch 7时执行

$ sudo luarocks install nn

遇到如下错误信息:

make[2]: *** [lib/THNN/CMakeFiles/THNN.dir/init.c.o] Error

原因是缺少依赖包torch导致的,在安装nn之前需要先安装torch即可解决问题。

如下方式执行:

$ sudo luarocks install torch
$ sudo luarocks install nn

参考链接


使用torch遇到的一些问题

编译Torch 7时执行luarocks install提示"Error: No results matching query were found."

编译Torch 7时执行luarocks install 提示错误信息:

Error: No results matching query were found.

这个是由于系统上安装了多个luarocks而执行安装命令的并不是Torch 7代码目录下自带的luarocks导致的。
修正的办法就是设置搜索路径,把Torch 7代码目录下的install/bin/放到搜索目录(PATH)的最前面。

参考链接


luarocks install *错误之Error: No results matching query were found.

ubuntu 16.04 LTS使用开源面部识别库Openface

Openface是一个基于深度神经网络的开源人脸识别系统。该系统基于谷歌的文章FaceNet: A Unified Embedding for Face Recognition and ClusteringOpenface是卡内基梅隆大学的Brandon Amos主导的。

1.准备系统环境

如果是服务器版本的ubuntu,可能默认Python都没有安装

#如果没有安装python的话,执行最小安装命令即可,目前我们需要的是Python2
$ sudo apt-get install python-minimal
$ sudo apt-get install python-pip
$ sudo pip install --upgrade pip

#如果没有安装git的话,此处需要手工安装
$ sudo apt-get install git

#编译dlib时候需要
$ sudo apt-get install cmake
$ sudo apt-get install libboost-dev
$ sudo apt-get install libboost-python-dev
2.下载代码
$ git clone https://github.com/cmusatyalab/openface.git
3.安装opencv
$ sudo apt-get install libopencv-dev
$ sudo apt-get install python-opencv
4.安装依赖的python
$ cd openface
$ pip install -r requirements.txt
$ sudo pip install dlib
$ sudo pip install matplotlib
5.安装Torch7

参考链接 ubuntu 16.04 LTS上安装Torch7

编译完成后,路径变量被加入了.bashrc,我们需要刷新一下Shell的环境变量

# 使 torch7 设置的刚刚的环境变量生效
source ~/.bashrc
6.安装依赖的lua
$ luarocks install dpnn

#下面的为选装,有些函数或方法可能会用到
$ luarocks install image
$ luarocks install nn
$ luarocks install graphicsmagick
$ luarocks install torchx
$ luarocks install csvigo
7.编译代码
$ python setup.py build
$ sudo python setup.py install
8.下载预训练后的数据
$ sh models/get-models.sh
#参考 https://cmusatyalab.github.io/openface/models-and-accuracies/ 下载对应的模型
$ wget https://storage.cmusatyalab.org/openface-models/nn4.v1.t7 -O models/openface/nn4.v1.t7
9.执行测试Demo

执行的脚本face_detect.py代码如下:

#!/usr/bin/env python2

import argparse
import cv2
import os
import dlib

import numpy as np
np.set_printoptions(precision=2)
import openface

from matplotlib import cm

fileDir = os.path.dirname(os.path.realpath(__file__))
modelDir = os.path.join(fileDir, '..', 'models')
dlibModelDir = os.path.join(modelDir, 'dlib')

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--dlibFacePredictor',
        type=str,
        help="Path to dlib's face predictor.",
        default=os.path.join(
            dlibModelDir,
            "shape_predictor_68_face_landmarks.dat"))
    parser.add_argument(
        '--networkModel',
        type=str,
        help="Path to Torch network model.",
        default='models/openface/nn4.v1.t7')
    # Download model from:
    # https://storage.cmusatyalab.org/openface-models/nn4.v1.t7
    parser.add_argument('--imgDim', type=int,
                        help="Default image dimension.", default=96)
    # parser.add_argument('--width', type=int, default=640)
    # parser.add_argument('--height', type=int, default=480)
    parser.add_argument('--width', type=int, default=1280)
    parser.add_argument('--height', type=int, default=800)
    parser.add_argument('--scale', type=int, default=1.0)
    parser.add_argument('--cuda', action='store_true')
    parser.add_argument('--image', type=str,help='Path of image to recognition')

    args = parser.parse_args()
    if (None == args.image) or (not os.path.exists(args.image)):
	print '--image not set or image file not exists'
	exit()

    align = openface.AlignDlib(args.dlibFacePredictor)
    net = openface.TorchNeuralNet(
        args.networkModel,
        imgDim=args.imgDim,
        cuda=args.cuda)

    cv2.namedWindow('video', cv2.WINDOW_NORMAL)

    frame = cv2.imread(args.image)  
    bbs = align.getAllFaceBoundingBoxes(frame)
    for i, bb in enumerate(bbs):
	# landmarkIndices set  "https://cmusatyalab.github.io/openface/models-and-accuracies/"
        alignedFace = align.align(96, frame, bb,
                                      landmarkIndices=openface.AlignDlib.OUTER_EYES_AND_NOSE)
        rep = net.forward(alignedFace)

        center = bb.center()
        centerI = 0.7 * center.x * center.y / \
                (args.scale * args.scale * args.width * args.height)
        color_np = cm.Set1(centerI)
        color_cv = list(np.multiply(color_np[:3], 255))

        bl = (int(bb.left() / args.scale), int(bb.bottom() / args.scale))
        tr = (int(bb.right() / args.scale), int(bb.top() / args.scale))
        cv2.rectangle(frame, bl, tr, color=color_cv, thickness=3)

    cv2.imshow('video', frame)

    cv2.waitKey (0)  

    cv2.destroyAllWindows()

Shell中如下执行代码:

$ python demos/face_detect.py --image=xx.jpeg

识别完成后会弹出识别到的面部图片。

ubuntu 16.04 LTS上安装Torch7

1.安装luarocks

$ sudo apt-get install luarocks

2.安装torch

$ git clone https://github.com/torch/distro.git ~/torch --recursive
$ cd ~/torch; bash install-deps;
$ ./install.sh

如果要使用NVIDIA CUDA加速版本的Torch7则使用如下方法

1.安装luarocks

$ sudo apt-get install luarocks

2.下载NVIDIA CUDA适配的代码

$ git clone https://github.com/torch/cutorch.git

3.安装编译依赖的库

$ sudo apt install nvidia-cuda-toolkit

4.编译代码

$ cd cutorch
$ mkdir build
$ cd build
$ cmake ..
$ make

参考链接


macOS Sierra (10.12.4)系统上Caffe借助现有的模型训练自己的数据集

Caffe代码中自带一些模型的例子,这些例子在源代码的models目录下,这些都是其他项目中用来训练的配置文件,学习的时候,我们没有必要完全自己从头到尾搭建自己的网络模型,而是直接使用例子中的模型,后期在这些模型上简单调整一下,一般可以满足大多数的需求。

下面我们以models/bvlc_alexnet目录下的模型配置文件为例子,训练我们自己的神经网络。

继续阅读macOS Sierra (10.12.4)系统上Caffe借助现有的模型训练自己的数据集

Caffe用训练好的caffemodel来进行分类

caffe程序自带有一张小猫图片,存放路径为caffe根目录下的examples/images/cat.jpg, 如果我们想用一个训练好的caffemodel来对这张图片进行分类,那该怎么办呢? 如果不用这张小猫图片,换一张别的图片,又该怎么办呢?如果学会了小猫图片的分类,那么换成其它图片,程序实际上是一样的。

开发caffe的贾大牛团队,利用imagenet图片和caffenet模型训练好了一个caffemodel,供大家下载。要进行图片的分类,这个caffemodel是最好不过的了。所以,不管是用C++来进行分类,还是用python接口来分类,我们都应该准备这样三个文件:

1. caffemodel文件

可以直接在浏览器里输入地址下载,也可以运行脚本文件下载。下载地址:http://dl.caffe.berkeleyvision.org/bvlc_reference_caffenet.caffemodel

文件名称为:bvlc_reference_caffenet.caffemodel,文件大小为230M左右,为了代码的统一,将这个caffemodel文件下载到caffe根目录下的models/bvlc_reference_caffenet/文件夹下面。也可以运行脚本文件进行下载:

$ ./scripts/download_model_binary.py models/bvlc_reference_caffenet

2. 均值文件
有了caffemodel文件,就需要对应的均值文件,在测试阶段,需要把测试数据减去均值。这个文件我们用脚本来下载,在caffe根目录下执行:

$ sh ./data/ilsvrc12/get_ilsvrc_aux.sh

执行并下载后,均值文件放在 data/ilsvrc12/ 文件夹里。

3. synset_words.txt文件

在调用脚本文件下载均值的时候,这个文件也一并下载好了。里面放的是1000个类的名称。

数据准备好了,我们就可以开始分类了,我们给大家提供两个版本的分类方法:

一. C++方法

caffe根目录下的examples/cpp-classification/文件夹下面,有个classification.cpp文件,就是用来分类的。当然编译后,放在/build/examples/cpp_classification/下面

我们就直接运行命令:

# sudo ./build/examples/cpp_classification/classification.bin \
  models/bvlc_reference_caffenet/deploy.prototxt \
  models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel \
  data/ilsvrc12/imagenet_mean.binaryproto \
  data/ilsvrc12/synset_words.txt \
  examples/images/cat.jpg

命令很长,用了很多的\符号来换行。可以看出,从第二行开始就是参数,每行一个,共需要4个参数

运行成功后,输出top-5结果:

---------- Prediction for examples/images/cat.jpg ----------
0.3134 - "n02123045 tabby, tabby cat"
0.2380 - "n02123159 tiger cat"
0.1235 - "n02124075 Egyptian cat"
0.1003 - "n02119022 red fox, Vulpes vulpes"
0.0715 - "n02127052 lynx, catamount"

即有0.3134的概率为tabby cat, 有0.2380的概率为tiger cat ......

二. python方法

python接口可以使用jupyter notebook来进行可视化操作,因此推荐使用这种方法。

在这里我就不用可视化了,编写一个py文件,命名为py-classify.py

#coding=utf-8
#加载必要的库
import numpy as np

import sys,os

#设置当前目录
caffe_root = '/home/xxx/caffe/' 
sys.path.insert(0, caffe_root + 'python')
import caffe
os.chdir(caffe_root)

net_file=caffe_root + 'models/bvlc_reference_caffenet/deploy.prototxt'
caffe_model=caffe_root + 'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel'
mean_file=caffe_root + 'python/caffe/imagenet/ilsvrc_2012_mean.npy'

net = caffe.Net(net_file,caffe_model,caffe.TEST)
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
transformer.set_transpose('data', (2,0,1))
transformer.set_mean('data', np.load(mean_file).mean(1).mean(1))
transformer.set_raw_scale('data', 255) 
transformer.set_channel_swap('data', (2,1,0))

im=caffe.io.load_image(caffe_root+'examples/images/cat.jpg')
net.blobs['data'].data[...] = transformer.preprocess('data',im)
out = net.forward()


imagenet_labels_filename = caffe_root + 'data/ilsvrc12/synset_words.txt'
labels = np.loadtxt(imagenet_labels_filename, str, delimiter='\t')

top_k = net.blobs['prob'].data[0].flatten().argsort()[-1:-6:-1]
for i in np.arange(top_k.size):
    print top_k[i], labels[top_k[i]]

对于macOS Sierra (10.12.3)来说,需要设置python环境,(参考源代码中的python/requirements.txt),如下:

#切换到我们自己安装的python版本,系统自带版本会在安装插件时候由于权限问题而失败
$ brew install python

#安装必要的python包
$ sudo pip install Cython
$ sudo pip install numpy
$ sudo pip install scipy

#只能安装编译好的包,源代码安装失败
$ sudo pip install scikit-image
$ sudo pip install matplotlib
$ sudo pip install ipython
$ sudo pip install h5py
$ sudo pip install leveldb
$ sudo pip install networkx
$ sudo pip install nose
$ sudo pip install pandas
$ sudo pip install python-dateutil
$ sudo pip install protobuf
$ sudo pip install python-gflags
$ sudo pip install pyyaml
$ sudo pip install Pillow
$ sudo pip install six

执行这个文件,输出:

281 n02123045 tabby, tabby cat
282 n02123159 tiger cat
285 n02124075 Egyptian cat
277 n02119022 red fox, Vulpes vulpes
287 n02127052 lynx, catamount

caffe开发团队实际上也编写了一个python版本的分类文件,路径为 python/classify.py

运行这个文件必需两个参数,一个输入图片文件,一个输出结果文件。而且运行必须在python目录下。假设当前目录是caffe根目录,则运行:

$ cd python
$ sudo python classify.py ../examples/images/cat.jpg result.npy

分类的结果保存为当前目录下的result.npy文件里面,是看不见的。而且这个文件有错误,运行的时候,会提示

Mean shape incompatible with input shape

的错误。因此,要使用这个文件,我们还得进行修改:

1.修改均值计算:

定位到

mean = np.load(args.mean_file)

这一行,在下面加上一行:

mean=mean.mean(1).mean(1)

则可以解决报错的问题。

2.修改文件,使得结果显示在命令行下:

定位到

# Classify.
    start = time.time()
    predictions = classifier.predict(inputs, not args.center_only)
    print("Done in %.2f s." % (time.time() - start))

这个地方,在后面加上几行,如下所示:

  # Classify.
    start = time.time()
    predictions = classifier.predict(inputs, not args.center_only)
    print("Done in %.2f s." % (time.time() - start))
    imagenet_labels_filename = '../data/ilsvrc12/synset_words.txt'
    labels = np.loadtxt(imagenet_labels_filename, str, delimiter='\t')
    top_k = predictions.flatten().argsort()[-1:-6:-1]
    for i in np.arange(top_k.size):
        print top_k[i], labels[top_k[i]]

就样就可以了。运行不会报错,而且结果会显示在命令行下面。

参考链接


Caffe学习系列(20):用训练好的caffemodel来进行分类

macOS Sierra (10.12.3)编译Faiss

最近Facebook AI实验室开源了相似性搜索库Faiss
Faiss是用于有效的相似性搜索(similarity search)和稠密矢量聚类(clustering of dense vectors)的库。它包含了可在任何大小向量集合里进行搜索的算法,向量集合的大小甚至可达到RAM容纳不下的地步。另外,它还包含了用于评估和参数调优的支持代码。FaissC++编写,有Python/numpy的完整包装。其中最有用的一些算法则在GPU上实现。

机器上没有安装HomeBrew的,请参考让Mac也能拥有apt-get类似的功能——Brew

下面,我们介绍一下如何在macOS Sierra (10.12.3)上编译Faiss

1.下载Faiss源代码

$ git clone https://github.com/facebookresearch/faiss.git

2.安装编译需要的工具

$ brew install llvm

3.修改调整源代码,准备编译

$ cd faiss
$ cp example_makefiles/makefile.inc.Mac.brew makefile.inc

4.编译

$ make all

5.执行测试用例

#需要手工指定动态库的搜索路径,否则会提示“dyld: Library not loaded: @rpath/libomp.dylib”,导致进程无法启动

$ export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/usr/local/opt/llvm/lib/
$ ./tests/demo_ivfpq_indexing

其余的示例,参考源代码中的INSTALL文件中的内容即可。