C++使用matlab卷积神经网络库MatConvNet来进行手写数字识别

环境:WIN10(64 bit)+VS2010(64 bit)+Matlab2015b(64 bit)

关于MatConvNet的介绍参考:http://www.vlfeat.org/matconvnet/

Github下载地址为:https://github.com/vlfeat/matconvnet/

我们的目的是将MatConvNet自带的手写数字识别DEMO移植到一个简单的WIN32 DEMO中使用,主要过程有以下几个步骤:

(1)配置MatConvNet,然后将手写数字识别DEMO编译成c++ shared library。

(2)编写调用代码并测试结果。

配置编译MatConvNet以及MNIST例子

首先从上面的地址中下载MatConvNet的源码并解压,然后打开Matlab2015b,将源码的matlab文件夹设置为当前路径,如下图所示:

执行mex -setup命令,此时matlab会显示可用的编译器,效果如下:

然后选择我们想用的编译器即可Microsoft Visual C++ 2010 (C)(直接用鼠标点),然后输入编译命令:vl_compilenn,执行,完成后可以看到多了一个名叫mex的文件夹,如下图所示:

这样就配置完成了,下面我们来编译examples下的mnist例子,切换matlab的当前路径到mnist文件夹,打开cnn_mnist.m文件,直接执行,如下图所示:

上面其实就是在下载对应的训练数据(数据存放在data\mnist目录下,总共有4个文件:t10k-images-idx3-ubyte,t10k-labels-idx1-ubyte,train-images-idx3-ubyte和train-labels-idx1-ubyte)。当然也可以把对应数据先下载下来,然后放到指定的目录,就可以跳过这一步啦。

等待一段时间后(默认有20个epoch,可以修改cnn_mnist_init.m文件中net.meta.trainOpts.numEpochs 的值来减少epoch数量,减少等待时间),训练完成后,打开data\mnist-baseline-simplenn文件夹可以看到训练的结果如下:

然后执行下面两条命令:

[net, ~]=cnn_mnist();
save('..\\..\\data\\mnist-baseline-simplenn\\net.mat', '-struct', 'net');

执行后可以看到mnist-baseline-simplenn目录下多了一个net.mat文件,后面我们需要用到imdb.mat和net.mat。

下面我们就需要编写一个自己的test_mnist.m文件,然后用它来生成c++ shared library。

这里需要注意一下,vl_setupnn这个函数其实就是把matlab文件夹下的所有子文件夹的路径加到matlab的路径变量中,类似VS里设置头文件目录的概念,所以为了简便,我们直接把matlab下的.m文件和matlab\mex下的.mex64文件拷贝到一个文件夹里,我直接放在D盘下的test_mnist文件夹下,并新建了一个空的文件test_mnist.m,如下图所示:

将下面的代码拷贝到test_mnist.m文件中:

function numeric = test_mnist(img, net_path, imdb_path)
net = load(net_path);
imdb = load(imdb_path);
net.layers{1, end}.type = 'softmax';
%resize inuput img
img = imresize(img, [28 28], 'bicubic');
img = single(img);
img = bsxfun(@minus, img, imdb.images.data_mean);
res = vl_simplenn(net, img);
[~, ~, n] = size(res(end).x(1, 1, :))
tmp = 0.0;
for i = 1 : n
    res(end).x(1, 1, i)
    if tmp < res(end).x(1, 1, i)
        numeric = i - 1;
        tmp = res(end).x(1, 1, i);
    end
end

注意:vl_simplenn函数返回的是一个多维的数组,最后一个维度保存的是分别识别为0~9的概率值,最大概率值就是最后的结果。

现在开始编译C++ shared library,有两种方式,第一种是用命令的方式编译,另外一种是用Matlab自带的可视化工具Library Compiler,我们采用第一种方式,输入如下命令:

mcc -W cpplib:dnrecognize -T link:lib test_mnist

dnrecognize表示生成的library name,test_mnist指定的要编译的matlab文件。

编译完成后,在当前目录下会生成不少文件,我们主要关注三个(dnrecognize.dll,dnrecognize.h,dnrecognize.lib):

好了,我们需要在C++中调用的库已经准备好了,现在我们新建一个WIN32的工程TestMnist来测试。

配置如下:

Include header file directory:

.\test_mnist;
C:\Program Files\MATLAB\R2015b\extern\include;
C:\Program Files\MATLAB\R2015b\extern\include\win64

Library directory:

.\test_mnist;
C:\Program Files\MATLAB\R2015b\extern\lib\win64\microsoft

编写WIN32部分的代码

这部分可以按自己的想法来搭建,我简单实现了一个背景黑色的窗口,然后可以用鼠标在上面画数字,左键按下就可以手写一个数字,右键擦出,中键识别手写数字,界面和效果如下:

cnn_mnist函数参数传入时,一定要注意在matlab中矩阵是按列优先存储的,切记切记。

对本人劣质代码有兴趣的下载地址如下:

http://download.csdn.net/detail/jieleiping/9500490

存在的问题:

(1)似乎手写的数字8就没正确过?不知道什么原因。

(2)程序运行过程中,有很多的异常信息,不知道为什么,但是程序执行时正确的。如果有谁知道原因,请一定要告诉我,谢谢。错误信息如下:

TestMnist.exe 中的 0x00007ffaf3531f28 处最可能的异常: Microsoft C++ 异常: 内存位置 0x154feb18 处的 std::logic_error。
TestMnist.exe 中的 0x00007ffaf3531f28 处最可能的异常: Microsoft C++ 异常: 内存位置 0x0b4ec570 处的 matrix::serialize::EndOfFile。
TestMnist.exe 中的 0x00007ffaf3531f28 处最可能的异常: Microsoft C++ 异常: 内存位置 0x0b4e7d60 处的 CryptoPP::AES_PHM_Decryption::InvalidCiphertextOrKey。
TestMnist.exe 中的 0x00007ffaf3531f28 处最可能的异常: Microsoft C++ 异常: 内存位置 0x0014e218 处的 fl::filesystem::PathNotFound。
TestMnist.exe 中的 0x00007ffaf3531f28 处最可能的异常: Microsoft C++ 异常: 内存位置 0x0014cf10 处的 xsd_binder::MalformedDocumentError。

题外话,如果需要将程序发布出去,似乎特别的麻烦。

一开始我认为把DLL带上就可以了(包括VS的库,test_mnist.dll以及R2015b\runtime\win64目录下的mclmcrrt9_0.dll),但是放到其他没有相应Matlab环境的电脑上无法运行。一百度说是在没有安装Matlab的电脑上执行Matlab,需要在对应电脑上安装MCR。

详情可见:http://cn.mathworks.com/products/compiler/mcr/index.html?refresh=true

其实MATLAB\R2015b\toolbox\compiler\deploy\win64目录下MCRInstaller.exe这个文件就是对应的MCR安装文件。(实际上也可以在用matlab compiler编译c++ shared library时指定附加MCR,这里就不详述了)。

时间: 2024-12-16 10:35:11

C++使用matlab卷积神经网络库MatConvNet来进行手写数字识别的相关文章

tensorflow学习之(十)使用卷积神经网络(CNN)分类手写数字0-9

#卷积神经网络cnn import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data #数据包,如果没有自动下载 number 1 to 10 data mnist = input_data.read_data_sets('MNIST_data',one_hot=True) #用测试集来评估神经网络的准确度 def computer_accuracy(v_xs,v_ys): global pre

C#中调用Matlab人工神经网络算法实现手写数字识别

手写数字识别实现 设计技术参数:通过由数字构成的图像,自动实现几个不同数字的识别,设计识别方法,有较高的识别率 关键字:二值化  投影  矩阵  目标定位  Matlab 手写数字图像识别简介: 手写阿拉伯数字识别是图像内容识别中较为简单的一个应用领域,原因有被识别的模式数较少(只有0到9,10个阿拉伯数字).阿拉伯数字笔画少并且简单等.手写阿拉伯数字的识别采用的方法相对于人脸识别.汉字识别等应用领域来说可以采用更为灵活的方法,例如基于规则的方法.基于有限状态自动机的方法.基于统计的方法和基于神

利用手写数字识别项目详细描述BP深度神经网络的权重学习

本篇文章是针对学习<深度学习入门>(由日本学者斋藤康毅所著陆羽杰所译)中关于神经网络的学习一章来总结归纳一些收获. 本书提出神经网络的学习分四步:1.mini-batch 2.计算梯度 3.更新参数 4.重复前面步骤 1.从识别手写数字项目学习神经网络 所谓“从数据中学习”是指 可以由数据#自动决定权重#.当解决较为简单的问题,使用简单的神经网络时,网络里的权重可以人为的手动设置,去提取输入信息中特定的特征.但是在实际的神经网络中,参数往往是成千上万,甚至可能上亿的权重,这个时候人为手动设置是

机器学习初探(手写数字识别)matlab读取数据集

手写数字识别是机器学习里面的一个经典问题,今天就这一段时间学习的机器学习,花一个下午茶的时间,试试机器学习. 首先数据库是在MNIST(http://yann.lecun.com/exdb/mnist/)下载下来的.下载下来的数据如下图所示.官方有给出数据怎么读取,我自己没有仔细看,因为我看到网上有人公布代码如何读取. 可以看到前四个是测试数据,后四个是训练数据. 这里我用matlab尝试读取这些数据. 首先看两个function. loadMNISTImages.m function imag

第二节,TensorFlow 使用前馈神经网络实现手写数字识别

一 感知器      感知器学习笔记:https://blog.csdn.net/liyuanbhu/article/details/51622695      感知器(Perceptron)是二分类的线性分类模型,其输入为实例的特征向量,输出为实例的类别,取+1和-1.这种算法的局限性很大: 只能将数据分为 2 类 数据必须是线性可分的 虽然有这些局限,但是感知器是 ANN 和 SVM 的基础,理解了感知器的原理,对学习ANN 和 SVM 会有帮助,所以还是值得花些时间的. 感知器可以表示为

Pytorch入门实战一:LeNet神经网络实现 MNIST手写数字识别

记得第一次接触手写数字识别数据集还在学习TensorFlow,各种sess.run(),头都绕晕了.自从接触pytorch以来,一直想写点什么.曾经在2017年5月,Andrej Karpathy发表的一片Twitter,调侃道:l've been using PyTorch a few months now, l've never felt better, l've more energy.My skin is clearer. My eye sight has improved.确实,使用p

基于Numpy的神经网络+手写数字识别

基于Numpy的神经网络+手写数字识别 本文代码来自Tariq Rashid所著<Python神经网络编程> 代码分为三个部分,框架如下所示: # neural network class definition class neuralNetwork: # initialise the neural network def __init__(): pass # train the neural network def train(): pass # query the neural netwo

神经网络手写数字识别

聊了几天理论,是该弄一个 Hello World 了,在人工智能领域,或者说深度学习领域,Hello World 程序就是手写数字识别,今天我们就来看看手写数字识别的程序怎么写.不愿意看代码吗,那我就说一说这段代码干了点什么:先通过 keras 内置的数据集下载测试数据,是 60000 长手写图片的训练集和 10000 张测试集,随后定义了一个神经网络的模型,设置网络中的层参数,随后配置训练网络的参数,包括损失函数和评测模型,设置迭代次数,启动训练网络,最后将测试数据喂给网络,得出训练效果是否有

使用cuda加速卷积神经网络-手写数字识别准确率99.7%

源码和运行结果 cuda:https://github.com/zhxfl/cuCNN-I C语言版本参考自:http://eric-yuan.me/ 针对著名手写数字识别的库mnist,准确率是99.7%,在几分钟内,CNN的训练就可以达到99.60%左右的准确率. 参数配置 网络的配置使用Config.txt进行配置##之间是注释,代码会自动过滤掉,其他格式参考如下: #Comment# #NON_LINEARITY CAN = NL_SIGMOID , NL_TANH , NL_RELU#