dawnminghuang的专栏

数据集和完整的程序下载见更新版:神经网络用于字符识别更新版

用于字符识别

这5000张随机选取4500张进行训练,剩下的500张用来测试。为了能对BP神经网络有更深入的了解,选择一步步详细实现。

BP神经网络的特点:信号前向传递,信号反向传播。若输出存在误差,根据误差调整权值和阈值,使网络的输出接近预期。

在用BP神经网络进行预测之前要训练网络

训练过程

1.网络初始化:各个参数的确定包括输入,输出,隐含层的节点数,输入和隐含,隐含和输出层之间的权值,隐含,输出层的阈值,学习速度和激励函数。

2.计算隐含层输出

3.计算输出层输出

4.误差计算

5.权值更新

6.阈值更新

7.判断迭代是否结束

模型建立:

BP神经网络构建-BP神经网络训练-BP神经网络分类

1.确定神经网络的输入,输出。

输入是BP神经网络很重要的方面,输入的数据是手写字符经过预处理和特征提取后的数据。预处理有二值化,裁剪掉空白的区域,然后再统一大小为70*50为特征提取做准备。特征提取采用的是粗网格特征提取,把图像分成35个区域,每个区域100像素,统计区域中1像素所占的比例。经过预处理特征提取后,28*28图像转成1*35的特征矢量。提取完5000张图片后,依次把所有的特征存于一个矩阵(5000*35)中,最后在加上第36行,用来存放原图片的真值。于是最后得到是包含特征向量和真值的矩阵(5000*36),特征向量是神经网络的输入,真值是其输出。

2.神经的网络的训练

用matlab的rands函数来实现网络权值的初始化,网络结构为输入层35,隐藏层34,输出层10,学习速率为0.1,隐藏层激励函数为sigmoid函数。随机抽取4500张图片提取特征后输入,按照公式计算隐含层和输出层输出,误差,更新网络权值。

3.神经网络的预测

训练好神经网络之后,,用随机抽取的500个数字字符对网络进行预测,输入特征向量,计算隐含层和输出层输出,得到最后预测的数据。同时计算每个数字的正确率和全体的正确率。最后得到的总体正确率为0.8004。

程序:

clc;clearall;closeall;Files= dir('E:/Matlabdip/word_recognition/testdatabase');LengthFiles= length(Files);%========读取存在testdatabase下0-10个文件的全部图片========%%========存放在number中,number{1}是数字0有500张========%fori = 3:LengthFiles;if strcmp(Files(i).name,'.')||strcmp(Files(i).name,'..')elsenumber{i-2}=BatchReadImg(strcat('E:/Matlabdip/word_recognition/testdatabase','/',Files(i).name),0);end endcharvec1=zeros(35,5000);%========对读取的图片预处理(二值化-裁剪-特征提取)========% for i=1:10for j=1:500I1=number{1,i}{1,j};Ibw = im2bw(I1,graythresh(I1));bw2 = edu_imgcrop(Ibw);%对图像进行裁剪,使边框完全贴紧字符charvec = edu_imgresize(bw2);%提取特征统计每个小区域中图像象素所占百分比作为特征数据charvec1(:,(i-1)*500+j)=charvec;end endindex=[zeros(1,500),zeros(1,500)+1,… zeros(1,500)+2,zeros(1,500)+3,zeros(1,500)+4,zeros(1,500)+5,zeros(1,500)+6,zeros(1,500)+7,zeros(1,500)+8,zeros(1,500)+9];charvec1(36,:)=index;%=========BP神经网络创建,训练和测试========%%从1到5000间随机排序(在[0,1]之间产生5000个随机数)==将数据顺序打乱k=rand(1,5000);[m,n]=sort(k);%输入输出数据input=charvec1(1:35,:);output1=charvec1(36,:); %把输出从1维变成10维fori=1:5000switch output1(i)case 0output(:,i)=[1 0 0 0 0 0 0 0 0 0]';case 1output(:,i)=[0 1 0 0 0 0 0 0 0 0]';case 2output(:,i)=[0 0 1 0 0 0 0 0 0 0]';case 3output(:,i)=[0 0 0 1 0 0 0 0 0 0]';case 4output(:,i)=[0 0 0 0 1 0 0 0 0 0]';case 5output(:,i)=[0 0 0 0 0 1 0 0 0 0]';case 6output(:,i)=[0 0 0 0 0 0 1 0 0 0]';case 7output(:,i)=[0 0 0 0 0 0 0 1 0 0]';case 8output(:,i)=[0 0 0 0 0 0 0 0 1 0]';case 9output(:,i)=[0 0 0 0 0 0 0 0 0 1]';endend %随机提取4500个样本为训练样本,500个样本为预测样本input_train=input(:,n(1:4500));output_train=output(:,n(1:4500));input_test=input(:,n(4501:5000));output_test=output(:,n(4501:5000)); % %输入数据归一化%[inputn,inputps]=mapminmax(input_train); %% 网络结构初始化innum=35;midnum=34;outnum=10;%权值初始化w1=rands(midnum,innum);%输入到隐藏b1=rands(midnum,1);w2=rands(midnum,outnum);%隐藏到输出b2=rands(outnum,1); w2_1=w2;w2_2=w2_1;w1_1=w1;w1_2=w1_1;b1_1=b1;b1_2=b1_1;b2_1=b2;b2_2=b2_1; %学习率xite=0.1;alfa=0.01; %% 网络训练%for ii=1:10%E(ii)=0;for i=1:1:4500%% 网络预测输出x=input_train(:,i);% 隐含层输出for j=1:1:midnumI(j)=input_train(:,i)'*w1(j,:)'+b1(j);Iout(j)=1/(1+exp(double(-I(j))));end% 输出层输出yn=w2'*Iout'+b2;%% 权值阀值修正%计算误差e=output_train(:,i)-yn;%E(ii)=E(ii)+sum(abs(e));%计算权值变化率dw2=e*Iout;db2=e';%=======由于采用的是sigmoid单元,所以要对每个输出单元以及隐藏单元计算误差项======%for j=1:1:midnumS=1/(1+exp(double(-I(j))));FI(j)=S*(1-S);endfor k=1:1:innumfor j=1:1:midnumdw1(k,j)=FI(j)*x(k)*(w2(j,:)*e);%db1(j)=FI(j)*(w2(j,:)*e);endendw1=w1_1+xite*dw1';b1=b1_1+xite*db1';w2=w2_1+xite*dw2';b2=b2_1+xite*db2';w1_2=w1_1;w1_1=w1;w2_2=w2_1;w2_1=w2;b1_2=b1_1;b1_1=b1;b2_2=b2_1;b2_1=b2;end%end%%% 语音特征信号分类%inputn_test=mapminmax('apply',input_test,inputps);for i=1:500%1500%隐含层输出for j=1:1:midnumI(j)=input_test(:,i)'*w1(j,:)'+b1(j);Iout(j)=1/(1+exp(double(-I(j))));end%输出层输出fore(:,i)=w2'*Iout'+b2;end%% 结果分析%根据网络输出找出数据属于哪类fori=1:500 output_fore(i)=find(fore(:,i)==max(fore(:,i)))-1;end %BP网络预测误差error=output_fore'-output1(n(4501:5000))';%画出预测数字和实际数字的分类图figure(1)plot(output_fore,'r')holdonplot(output1(n(4501:5000))','b')legend('预测数字','实际数字') %画出误差图figure(2)plot(error)title('BP网络分类误差','fontsize',12)xlabel('输入数字','fontsize',12)ylabel('分类误差','fontsize',12) k=zeros(1,10); %找出判断错误的分类属于哪一类fori=1:500if error(i)~=0[b,c]=max(output_test(:,i));switch c-1case 1k(1)=k(1)+1;case 2k(2)=k(2)+1;case 3k(3)=k(3)+1;case 4k(4)=k(4)+1;case 5k(5)=k(5)+1;case 6k(6)=k(6)+1;case 7k(7)=k(7)+1;case 8k(8)=k(8)+1;case 9k(9)=k(9)+1;case 0k(10)=k(10)+1;endendend %找出每类的个体和kk=zeros(1,10);fori=1:500[b,c]=max(output_test(:,i));switch c-1case 1kk(1)=kk(1)+1;case 2kk(2)=kk(2)+1;case 3kk(3)=kk(3)+1;case 4kk(4)=kk(4)+1;case 5kk(5)=kk(5)+1;case 6kk(6)=kk(6)+1;case 7kk(7)=kk(7)+1;case 8kk(8)=k(8)+1;case 9kk(9)=kk(9)+1;case 0kk(10)=kk(10)+1;endend %正确率rightridio=(kk-k)./kk right=(sum(kk(:))-sum(k(:)))/sum(kk(:));用到到函数:BatchImgfunction [imglist]=BatchReadImg(rootpath,grayflag)if nargin<2 disp('Not enough parameters!'); return;end filelist=dir(rootpath);[filenum,temp]=size(filelist);tempind=0;imglist=cell(0);for i=1:filenumif strcmp(filelist(i).name,'.')|| strcmp(filelist(i).name,'..')||strcmp(filelist(i).name,'Desktop_1.ini')||strcmp(filelist(i).name,'Desktop_2.ini')elsetempind=tempind+1;imglist{tempind}=imread(strcat(rootpath,'/',filelist(i).name)); endendif grayflag==1 tempcount=size(imglist); for j=1:tempcount(2)imglist{j}=rgb2gray(imglist{j}); endendedu_imgcrop:function bw2 = edu_imgcrop(bw) %找到图像边界[y2temp x2temp] = size(bw);x1=1;y1=1;x2=x2temp;y2=y2temp; % 找左边空白cntB=1;while (sum(bw(:,cntB))==y2temp) x1=x1+1; cntB=cntB+1;end % 左边cntB=1;while (sum(bw(cntB,:))==x2temp) y1=y1+1; cntB=cntB+1;end % 上边cntB=x2temp;while (sum(bw(:,cntB))==y2temp) x2=x2-1; cntB=cntB-1;end % 下边cntB=y2temp;while (sum(bw(cntB,:))==x2temp) y2=y2-1; cntB=cntB-1;endbw2=imcrop(bw,[x1,y1,(x2-x1),(y2-y1)]);edu_imgresize:function lett = edu_imgresize(bw2)% ======提取特征,转成5*7的特征矢量,把图像中每10*10的点进行划分相加,进行相加成一个点=====%%======即统计每个小区域中图像象素所占百分比作为特征数据====%bw_7050=imresize(bw2,[70,50]);for cnt=1:7 for cnt2=1:5Atemp=sum(bw_7050(((cnt*10-9):(cnt*10)),((cnt2*10-9):(cnt2*10))));%10*10boxlett((cnt-1)*5+cnt2)=sum(Atemp); endendlett=((100-lett)/100);lett=lett';

完整的数据集和可以运行的Matlab代码下载

邮箱联系:dawnminghuang@gmail.com

可以有一个人陪着你,也可以你一个人,总之那一刻,

dawnminghuang的专栏

相关文章:

你感兴趣的文章:

标签云: