海思AI芯片有一个NNIE单元,全称:Neural Network Inference Engine,是海思媒体 SoC 中专门针对神经网络特别是深度学习卷积神经网络进行加速处理的硬件单元,支持现有大部分的公开网络,如 Alexnet、VGG16、Googlenet、Resnet18、Resnet50 等分类网络,Faster RCNN、YOLO、SSD、RFCN 等检测网络,以及 SegNet、FCN 等场景分割网络。目前 NNIE 配套软件及工具链仅支持以 Caffe 框架,使用其他框架的网络模型需要转化为 Caffe 框架下的模型。
所以要想在hi3519a和hi3559a上跑AI程序,必须要深入学习caffe。
caffe训练和推理可以在CPU上,也可以在GPU上,当然GPU比CPU要快很多,而NNIE又要比GPU快很多。
caffe安装网上有很多,从完整安装到运行mnist的很少,个人电脑情况不一样,大多都有一些坑在里面,下面是我的安装步骤,亲自测试过的,绝对没有坑!
我的目的:
- Linux上安装caffe(CPU版)。
- 运行caffe里的一个样例mnist,测试自己手写数字能否正确识别。
主机环境:ubuntu16.04
一:安装caffe
1.1 下载Caffe
直接从GitHub仓库克隆即可(仓库地址:https://github.com/BVLC/caffe),输入下面的命令,克隆Caffe到本地:
git clone https://github.com/BVLC/caffe.git
克隆完成后,用户目录下将出现一个名为caffe的文件夹。
1.2 安装Caffe的依赖
$ sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev
$ sudo apt-get install libopencv-dev libhdf5-serial-dev protobuf-compiler
$ sudo apt-get install --no-install-recommends libboost-all-dev
$ sudo apt-get install libatlas-base-dev
$ sudo apt-get install python-dev
$ sudo apt-get install libgflags-dev
$ sudo apt-get install libgoogle-glog-dev
$ sudo apt-get install liblmdb-dev
1.3 修改Makefile.config
创建Makefile.config文件,用于配置caffe的编译
$ cp Makefile.config.example Makefile.config
打开Makefile.config文件:
因为我是用CPU训练,所以把Makefile.config文件里第8行:
#CPU_ONLY := 1
前面的#号去掉。
还需要加入hdf5的头文件和库的依赖,定位到INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include,在后面加上/usr/include/hdf5/serial:
INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include /usr/include/hdf5/serial
在LIBRARY_DIRS后添加/usr/lib/x86_64-linux-gnu/hdf5/serial:
LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu/hdf5/serial
1.4 编译
输入命令:make all
1.5 编译测试程序
输入命令:make test
1.6 运行下面的命令进行测试
输入命令:make runtest
如果全部顺利完成,那么Caffe则已经编译好了。
二:mnist测试手写数字
下载下来的caffe目录有一个经典样例mnist,可以根据MNIST 数据集训练一个分类模型,利用该模型可以识别手写数字。
MNIST 数据集来自美国国家标准与技术研究所, National Institute of Standards and Technology (NIST). 训练集 (training set) 由来自 250 个不同人手写的数字构成, 其中 50% 是高中学生, 50% 来自人口普查局 (the Census Bureau) 的工作人员. 测试集(test set) 也是同样比例的手写数字数据.
2.1训练模型
安装编译完caffe后,其主目录下有:
在caffe目录下直接运行脚本可以下载mnist数据集:
特别说明:caffe运行任何程序及脚本都要在根目录下执行,本人已踩坑。
下载完数据集后会在data/mnist目录下得到四个文件,
由于caffe支持的图像类型为lmdb类型,所以其他任何格式的都要转为lmdb类型。
直接运行脚本可以转换图片格式:
完成后会在examples/mnist目录下生成两个目录:
mnist样例已经提供网络模型examples/mnist/lenet_train_test.prototxt,我们需要配置关于模型优化的文件:
我的配置文件如下:修改solver_mode为CPU,max_iter是最大迭代次数,可以改小一点,不过会损失精度,snapshot_prefix即为模型文件保存路径,这里我是新建一个文件夹来保存。
接下来一步就是进行训练了,直接执行命令就可以:
训练完成后可以看到训练的精度:
2.2 识别手写图片:
2.2.1 准备图片
首先需要准备一张图片,可以用Windows画图工具画一张黑底白字的图片,网上都说图片要28×28像素的图片,我实测并没有这个要求。
下面是我画好的图片:
链接:https://pan.baidu.com/s/13JTDjhUDcPZlcr7hiG7jgQ
提取码:5ji6
2.2.2 生成deploy.prototxt文件
要了解deploy.prototxt文件的作用请自行百度或google,这里我们需要知道的是,他和lenet_train_test.prototxt文件类似,或者说对后者改动可得到前者。在熟悉生成文件的原理及方法之后我们可以之间在原训练prototxt网络文件中改动。在examples/mnist目录下复制一份lenet_train_test.prototxt修改并保存后得到deploy.prototxt如下:
name: "LeNet"
input: "data"
input_dim:1
input_dim:1
input_dim:28
input_dim:28
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
convolution_param {
num_output: 20
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
}
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
convolution_param {
num_output: 50
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
}
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool2"
top: "ip1"
inner_product_param {
num_output: 500
weight_filler {
type: "xavier"
}
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "ip1"
top: "ip1"
}
layer {
name: "ip2"
type: "InnerProduct"
bottom: "ip1"
top: "ip2"
inner_product_param {
num_output: 10
weight_filler {
type: "xavier"
}
}
}
layer {
name: "prob"
type: "Softmax"
bottom: "ip2"
top: "prob"
}
2.2.3 生成labels.txt标签文件
在当前目录下新建一个txt文件,命名为synset_words.txt,里面内容为我们训练mnist的图片内容,共有0~9十个数,那么我们就建立如下内容的标签文件:
2.2.4 生成mean.binaryproto二进制均值文件
图片减去均值后,再进行训练和测试,会提高速度和精度。因此,一般在各种模型中都会有这个操作。
那么这个均值怎么来的呢,实际上就是计算所有训练样本的平均值,计算出来后,保存为一个均值文件,在以后的测试中,就可以直接使用这个均值来相减,而不需要对测试图片重新计算。
caffe作者为我们提供了一个计算均值的文件compute_image_mean.cpp,放在caffe根目录下的tools文件夹里面,运行下面命令生成mean.binaryproto二进制均值文件。
sudo build/tools/compute_image_mean examples/mnist/mnist_train_lmdb examples/mnist/mean.binaryproto
生成的mean.binaryproto均值文件保存在了examples/mnist目录下。
2.2.5 分类器classification.bin
在example文件夹中有一个cpp_classification的文件夹,打开它,有一个名为classification的cpp文件,这就是caffe提供给我们的调用分类网络进行前向计算,得到分类结果的接口。
在编译caffe时会在./build/examples/cpp_classification/得到classification.bin,具体我们可以不用管它,在其他caffemodel下不用修改也可以用,不像均值文件,不同的模型需要不同的均值文件。
2.2.6 准备测试
./build/examples/cpp_classification/classification.bin examples/mnist/deploy.prototxt examples/mnist/lenet_iter_10000.caffemodel examples/mnist/mean.binaryproto examples/mnist/synset_words.txt examples/images/3.jpg
请根据你们自己建立的文件的具体位置更改路径。
下面看看我的测试结果吧!
测试的图片:
可以看到测试出5的结果为100%,精准预测!!!