一:人工神经网络
人类之所以能够思考,学习,判断,大部分都要归功于人脑中复杂的神经网络。虽然现在人脑的机理还没有完全破译,但是人脑中神经元之间的连接,信息的传递都已为人所知晓。于是人们就想能否模拟人脑的功能用于解决其他问题,这就发展出人工神经网络。
人工神经网络(artificial neural network,缩写ANN),是一种模仿生物神经网络的结构和功能的数学模型或计算模型。神经网络由大量的人工神经元联结进行计算。大多数情况下人工神经网络能在外界信息的基础上改变内部结构,是一种自适应系统。现代神经网络是一种非线性统计性数据建模工具,常用来对输入和输出间复杂的关系进行建模,或用来探索数据的模式。
神经网络是一种运算模型,由大量的节点(或称“神经元”,或“单元”)和之间相互联接构成。每个节点代表一种特定的输出函数,称为激励函数(activation function)。每两个节点间的连接都代表一个对于通过该连接信号的加权值,称之为权重(weight),这相当于人工神经网络的记忆。网络的输出则依网络的连接方式,权重值和激励函数的不同而不同。而网络自身通常都是对自然界某种算法或者函数的逼近,也可能是对一种逻辑策略的表达。
1.1 神经元
人工神经网络是由成千上万个神经元构成的,所以我们要先学习了解神经元。
神经元示意图:
- a1~an为输入向量的各个分量
- w1~wn为神经元各个突触的权值
- b为偏置
- f为传递函数,通常为非线性函数。一般有traingd(),tansig(),hardlim()。以下默认为hardlim()
- t为神经元输出
数学表示
- 为权向量
- 为输入向量,为的转置
- 为偏置
- 为传递函数
可见,一个神经元的功能是求得输入向量与权向量的内积后,经一个非线性传递函数得到一个标量结果。单个神经元的作用:把一个n维向量空间用一个超平面分割成两部分(称之为判断边界),给定一个输入向量,神经元可以判断出这个向量位于超平面的哪一边。
该超平面的方程:
- 权向量
- 偏置
- 超平面上的向量
1.2 bp神经网络结构
神经网络是由很多神经元组成,可以分为输入,输出,隐含层。
bp神经网络的特点:信号前向传递,误差反向传播。若输出存在误差,根据误差调整权值和阈值,使网络的输出接近预期。
二:手写字符识别
数据集介绍:
数据集包含0-9这10个数字的手写体。是放在10个文件夹里,文件夹的名称对应存放的手写数字图片的数字,每个数字500张,每张图片的像素统一为28*28。
samples:
识别流程:
流程如图,首先要对数据进行处理,这个主要是批量读取图片和特征提取的过程,特征提取的方法很多,这里只挑选最简单的来实现,然后是训练出一个神经网络的模型,最后用测试数据进行测试。为了方面,这里的神经网络的创建,训练和测试采用matlab函数来实现。
2.0 主函数:
clc; clear all; close all; %% 读取图像 root='./data'; img=read_train(root); %% 提取特征 img_feature=feature_lattice(img); %% 构造标签 class=10; numberpclass=500; ann_label=zeros(class,numberpclass*class); ann_data=img_feature; for i=1:class for j=numberpclass*(i-1)+1:numberpclass*i ann_label(i,j)=1; end end %% 选定训练集和测试集 k=rand(1,numberpclass*class); [m,n]=sort(k); ntraindata=4500; ntestdata=500; train_data=ann_data(:,n(1:ntraindata)); test_data=ann_data(:,n(ntraindata+1:numberpclass*class)); train_label=ann_label(:,n(1:ntraindata)); test_label=ann_label(:,n(ntraindata+1:numberpclass*class)); %% BP神经网络创建,训练和测试 net=network_train(train_data,train_label); predict_label=network_test(test_data,net); %% 正确率计算 [u,v]=find(test_label==1); label=u'; error=label-predict_label; accuracy=size(find(error==0),2)/size(label,2)
2.1 批量读取图片函数
文件存放特点:在data下有10个子文件夹,每个子文件夹下有500张图片。函数可以利用于任何批量图片的读取,传入的是文件夹路径,输出的是一个n(对应图片数目)维cell,每个cell存放的是图片的数据。
function [imglist] = read_train(root) %========读取文件夹========% out_Files = dir(root);%展开 tempind=0; imglist=cell(0); n=length(out_Files); %========读取文件========% for i = 1:n; if strcmp(out_Files(i).name,'.')|| strcmp(out_Files(i).name,'..') else rootpath=strcat(root,'/',out_Files(i).name); in_filelist=dir(rootpath); ni=length(in_filelist); for j=1:ni if strcmp(in_filelist(j).name,'.')|| strcmp(in_filelist(j).name,'..')|| strcmp(in_filelist(j).name,'Desktop_1.ini')|| strcmp(in_filelist(j).name,'Desktop_2.ini') else tempind=tempind+1; imglist{tempind}=imread(strcat(rootpath,'/',in_filelist(j).name)); end end end end end
2.2 特征提取
提取所有图像的特征,二值化—resize-提取特征
function feature = feature_lattice(img) % 输入:黑底白字的二值图像。输出:35维的网格特征 % ======提取特征,转成5*7的特征矢量,把图像中每10*10的点进行划分相加,进行相加成一个点=====% %======即统计每个小区域中图像象素所占百分比作为特征数据====% for i=1:length(img); bw2=im2bw(img{i},graythresh(img{i})); bw_7050=imresize(bw2,[70,50]); for cnt=1:7 for cnt2=1:5 Atemp=sum(bw_7050(((cnt*10-9):(cnt*10)),((cnt2*10-9):(cnt2*10))));%10*10box lett((cnt-1)*5+cnt2)=sum(Atemp); end end lett=((100-lett)/100); lett=lett'; feature(:,i)=lett; end
2.3 构造标签
要构造出适合神经网络的标签,在这个例子中有10个类,若为某个标签,那么这个位置的值为1,其余为0。
2.4 BP神经网络创建,训练和测试
主要是几个参数的设置,layer隐含层的神经元个数。trainFcn:训练算法
function net = network_train(train_data,train_label ) % 输入:训练图像特征和label。输出:训练好的神经网络 % BP网络训练 % 初始化网络结构 layer=25; net=newff(train_data,train_label,layer); net.trainParam.epochs=1; net.trainParam.lr=0.1; net.trainParam.goal=0.001; net.trainFcn='trainrp'; % 网络训练 net=train(net,train_data,train_label); end
function out = network_test(test_data,net) %% BP网络预测 an=sim(net,test_data); for i=1:length(test_data) out(i)=find(an(:,i)==max(an(:,i))); end end
2.5 数据集及完整代码下载
http://pan.baidu.com/s/1pJz97pp
参考资料:
【1】http://zh.wikipedia.org/zh-cn/%E4%BA%BA%E5%B7%A5%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C