基于matlab实现简单的手写字母/数字/汉字程序(神经网络)

基于matlab实现简单的手写字母/数字/汉字程序(神经网络)

本篇博客主要参考了《模式识别与智能计算:MATLAB技术实现(第2版)》。如果想深入了解,我会在评论区贴出链接

原理:

原理很简单,主要是对于输入的手写样本图片进行切分,切分成5X5的25个小cell。并且对每一个cell进行黑色像素量的计算,将25个cell的像素量以列向量的形式存入结构体的一个类的一列中,完成对一个样本图片的读取。对每种字母/数字/汉字的类读入5个训练的手写样本。
对于已经读入完毕的结构体,需要构建一个简单的神经网络来对其进行训练。得到训练好的网络,再对待测样本进行计算像素量的操作,与训练好的神经网络进行匹配就可以实现相应的功能了。

神经网络结构:

BP神经网络
设计的神经网络主要是有3层:输入层、隐含层、输出层。对于一个样本有5X5=25个特征作为神经网络的输入,故有输入结点25个。根据隐含层个数大约为输入结点的两倍关系,故隐含层有50个结点。输出层取4个结点,这四个输出为四位二进制数,代表神经网络的数字类型(如果需要能够识别更多的样本,就请在结构体存入更多的样本的基础上,修改神经网络的输出结点数,并且修改输出矩阵即可)。

部分代码

主要以字母识别为例,汉字和数字的情况仅仅只是改变训练样本图片和相应的匹配数组

读取训练样本

load templet;
% A 被分成5*5=25个cell(A的长宽要能被5整除)
A=imread('B_5.png');
figure(1),imshow(A)
B=zeros(1,25);
[row, col] = size(A);
cellRow = row/5
cellCol = col/5

计算黑色像素量

%计算黑色像素量存入结构体
count = 0;
currentCell = 1;
for currentRow = 0:4
    for currentCol = 0:4
       for i = 1:cellRow
           for j = 1:cellCol
               if(A(currentRow*cellRow+i,currentCol*cellCol+j)==0)
                   count=count+1;
               end
           end
        end
        ratio = count/(cellRow*cellCol);
        B(1,currentCell) = ratio;
        currentCell = currentCell+1;
        count = 0;
     end
end

pattern(i).num=5   %结构体的第i个字段包括5个测试样本
pattern(i).feature(:,j)=B'  %B以列向量的方式保存进入结构体的第i个字段的j个样本
save templet pattern

定义神经网络的输入输出矩阵

global bpnet;
clc;
load templet pattern;
c=0;

%P为输入矩阵
p=[];
for i=1:10
    for j=1:5
        c=c+1;
        p(:,c)=pattern(i).feature(:,j);
    end
end

%t为输出矩阵
t=zeros(4,45);
t(4,1:5)=1;
t(3,6:10)=1;
t(3:4,11:15)=1;
t(2,16:20)=1;
t(2,21:25)=1;
t(4,21:25)=1;
t(2:3,26:30)=1;
t(2:4,31:35)=1;
t(1,36:40)=1;
t(1,41:45)=1;
t(4,41:45)=1;
t(1,46:50)=1;
t(3,46:50)=1;

初始化神经网络

x=ones(25,2);
x(:,1)=0;
bpnet = newff(x,[50,4],{'logsig','logsig','traingd'}); %这里选用梯度下降的方法
bpnet.trainParam.show=50;                                 %每隔50次训练,显示一次训练进程
bpnet.trainParam.lr=0.2;                                      %学习速率定义为0.2
bpnet.trainParam.epochs=2000;                          %最大训练次数2000次
bpnet.trainParam.goal=0.2e-1;                             %训练要求的精度小于0.02
bpnet.trainParam.min_grad=1e-10;                      %最小梯度要求为1e-10
[bpnet] = train(bpnet,p,t);

定义一个函数用于匹配的待测样本和神经训练后的神经网络

function y= bpnet(sample)
global bpnet;
clc;
a = sim(bpnet,sample)
a = round(a)
b = num2str(a);
c = bin2dec(b');
y = c;

测试部分

name1=char('A','B','C','D','E','F','H','I','L','X');%输出
A=imread('F_test.png');%待测样本
figure(1),subplot(121),imshow(A),title(['待识别的字母:']);
B=zeros(1,25);
[row,col] = size(A);
cellRow = row/5
cellCol = col/5
%计算黑色像素量
count = 0;
currentCell = 1;
for currentRow = 0:4
    for currentCol = 0:4
       for i = 1:cellRow
           for j = 1:cellCol
               if(A(currentRow*cellRow+i,currentCol*cellCol+j)==0)
                   count=count+1;
               end
           end
        end
        ratio = count/(cellRow*cellCol);
        B(1,currentCell) = ratio;
        currentCell = currentCell+1;
        count = 0;
     end
end
class = bpnet(B')
subplot(122),imshow([(name1(class)),'.png']),title(['该字母被识别为:']);
disp(['该字母被识别为:',(name1(class))]);

这里之所以要定义一个字符数组是因为进行匹配的时候,输出的是二进制的数,对应了结构体的第几个类,比如说读入结构体的第一个字母类是“A”,那么匹配出的结果就是0001,读入结构体的第5个字母类是“E”,那么匹配出的结果就是0101.为了让输出的结果和标准的图片匹配上,就定义了这样的字符数组来进行匹配。

部分截图:

运行截图
运行截图

总结:

这仅仅只是一个简单的识别程序,主要的缺点就是不能非常灵活地面对需求,如果说对于要求识别的样本的数量过大,需要手动去修改输出矩阵的相关参数,还是比较麻烦的。但如果比较感兴趣,还是可以去试一试这个简单的程序。

  • 2
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逆光ay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值