千家信息网

spl中如何实现手写数字识别

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章给大家分享的是有关spl中如何实现手写数字识别的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。识别手写的阿拉伯数字,对于人类来说十分简单,但是对于程序来说还是有些复杂
千家信息网最后更新 2026年11月03日spl中如何实现手写数字识别

这篇文章给大家分享的是有关spl中如何实现手写数字识别的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

识别手写的阿拉伯数字,对于人类来说十分简单,但是对于程序来说还是有些复杂的。

不过随着机器学习技术的普及,使用10几行代码,实现一个能够识别手写数字的程序,并不是一件难事。这是因为有太多的机器学习模型可以拿来直接用,比如tensorflow、caffe,在python下都有现成的安装包,写一个识别数字的程序,10几行代码足够了。

然而我想做的,是不借助任何第三方的库,从零开始,完全自己实现一个这样的程序。之所以这么做,是因为自己动手实现,才能深入了解机器学习的原理。

1 模型实现

1.1 原理

熟悉神经网络回归算法的,可以略过这一节了。

学习了一些基本概念,决定使用回归算法。首先下载了著名的MNIST数据集,这个数据集有60000个训练样本,和10000个测试样本。每个数字图片都是28*28的灰度图片,所以输入可以认为是一个28*28的矩阵,也可以认为是一个28*28=784个像素值。

这里定义一个模型用于判断一个图片数字,每个模型包括每个输入的权重,加一个截距,最后再做个归一。模型的表达式:

Out5= sigmoid(X0*W0+ X1*W1+……X783*W783+bias)

X0到X783是784个输入,W0到W783是784个权重,bias是一个常量。sigmoid函数可以将较大范围的数挤压到(0,1)区间内,也就是归一。

例如我们用这一组权重和bias来判断数字5,期望当图片是5时输出是1,当不是5时输出是0。然后训练的过程就是根据每个样本的输入,计算Out5的值和正确值(0或1)的差距,然后根据这个差距,调整权重和bias。转换一下公式,就是在努力使得(Out5-正确值)接近于0,即所谓损失最小。

同理,10个数字就要有10套模型,每个判断不同的数字。训练好以后,一个图片来了,用这10套模型进行计算,哪个模型计算的结果更接近于1,就认为这个图片是哪个数字。

1.2 训练

按照上面的思路,使用集算器的SPL(结构化处理语言)来编码实现:


A

B

C

1

=file("train-imgs.btx").cursor@bi()



2

>x=[],wei=[],bia=[],v=0.0625,cnt=0



3

for 10

>wei.insert(0,[to(28*28).(0)]),

bia.insert(0,0.01)


4

for 50000

>label=A1.fetch(1)(1)


5


>y=to(10).(0), y(label+1)=1,x=[]


6


>x.insert(0,A1.fetch(28*28))

>x=x.(~/255)

7


=wei.(~**x).(~.sum()) ++ bia


8


=B7.(1/(1+exp(-~)))


9


=(B8--y)**(B8.(1-~))**B8


10


for 10

>wei(B10)=wei(B10)--x.(~*v*B9(B10)),

bia(B10)=bia(B10) - v*B9(B10)

11

>file("MNIST模型.btx").export@b(wei),file("MNIST模型.btx").export@ba(bia)

不用再找了,训练模型的所有代码都在这里了,没有用到任何第三方库,下面解析一下:

A1,用游标导入MNIST训练样本,这个是我转换过的格式,可以被集算器直接访问;

A2,定义变量:输入x,权重wei,训练速度v,等;

A3,B3,初始化10组模型(每组是784个权重+1个bias);

A4,循环取5万个样本进行训练,10模型同时训练;

B4,取出来label,即这个图片是几;

B5,计算正确的10个输出,保存到变量y;

B6,取出来这个图片的28*28个像素点作为输入,C6把每个输入除以255,这是为了归一化;

B7,计算X0*W0+ X1*W1+……X783*W783+bias

B8,计算sigmoid(B7)

B9,计算B8的偏导,或者叫梯度;

B10,C10,根据B9的值,循环调整10个模型的参数;

A11,训练完毕,把模型保存到文件。

1.3 测试

测试一下这个模型的成功率吧,用 SPL 写了一个测试程序:


A

B

C

1

=file("MNIST模型.btx").cursor@bi()

=[0,1,2,3,4,5,6,7,8,9]


2

>wei=A1.fetch(10),bia=A1.fetch(10)



3

>cnt=0



4

=file("test-imgs.btx").cursor@bi()



5

for 10000

>label=A4.fetch(1)(1)


6


>x=[]


7


>x.insert(0,A4.fetch(28*28))

>x=x.(~/255)

8


=wei.(~**x).(~.sum()) ++ bia


9


=B8.(round(1/(1+exp(-~)), 2))


10


=B9.pmax()


11


if label==B1(B10)

>cnt=cnt+1

12

=A1.close()



13

=output(cnt/100)



运行测试,正确率达到了91.1%,我对这个结果是很满意的,毕竟这只是一个单层模型,我用TensorFlow的单层模型得到的正确率也是91%多一点。下面解析一下代码:

A1,导入模型文件;

A2,把模型提取到变量里;

A3,计数器初始化(用于计算成功率);

A4,导入MNIST测试样本,这个文件格式是我转换过的;

A5,循环取1万个样本进行测试;

B5,取出来label;

B6,清空输入;

B7,取出来这个图片的28*28个像素点作为输入,每个输入除以255,这是为了归一化;

B8,计算X0*W0+ X1*W1+……X783*W783+bias

B9,计算sigmoid(B7)

B10,得到最大值,即最可能的那个数字;

B11,判断正确测计数器加一;

A12,A13,测试结束,关闭文件,输出正确率。

1.4 优化

这里要说的优化并不是继续提高正确率,而是提升训练的速度。想提高正确率的同学可以尝试一下这几个手段:

1. 加一个卷积层;

2. 学习速度不要用固定值,而是随着训练次数递减;

3. 权重的初始值不要使用全零,使用正态分布;

我认为单纯追求正确率的意义不大,因为MNIST数据集有些图片本身就有问题,即使人工也不一定能知道写的是数字几。我用集算器显示了几张出错的图片,都是书写十分不规范的,下面这个图片很难看出来是2。

下面说重点,要提高训练速度,可以使用并行或集群。使用SPL语言实现并行很简单,只要使用fork关键字,把上面的代码稍加处理就可以了。


A

B

C

D

1

=file("train-imgs.btx").cursor@bi()




2

>x=[],wei=[],bia=[],v=0.0625,cnt=0

>mode=to(0,9)



3


>wei=to(28*28).(0)



4

fork mode

=A1.cursor()



5


for 50000

>label=B4.fetch(1)(1)

>y=1,x=[]

6



if label!=A4

>y=0

7



>x.insert(0,B4.fetch(28*28))

>x=x.(~/255)

8



=(wei**x).sum() + bia


9



=1/(1+exp(-C8))


10



=(C9-y)*((1-C9))*C9


11



>wei=wei--x.(~*v*C10),

bia=bia- v*C10


12


return wei,bia



13

=movefile(file("MNIST模型.btx"))


14

for 10

>file("MNIST模型.btx").export@ba([A4(A15)(1)])

15

for 10

>file("MNIST模型.btx").export@ba([A4(A16)(2)])

使用了并行之后,训练的时间减少差不多一半,而代码并没有做太多修改。

2 为什么是 SPL 语言?

使用SPL语言在初期可能会有点不适应,用得多了会觉得越来越方便:

1. 支持集合运算,比如例子里用到的784个输入和784个权重的乘法,直接写一个**就可以了,如果使用Java或者C,还要自己实现。

2. 数据的输入输出很方便,可以方便地对文件读写。

3. 调试太方便了,所有变量都直观可见,这一点比python要好用。

4. 可以单步计算,有了改动不用从头重来,Java和C做不到这一点,python虽然可以但也不方便,集算器只要点中相应格执行就可以了。

5. 实现并行和集群很方便,不需要太多的开发工作量。

6. 支持调用和被调用。集算器可以调用第三方java库,Java也可以调用集算器的代码,例如上面的代码就可以被Java调用,实现一个自动填验证码的功能。

这样的编程语言,用在数学计算上,实在是最合适不过了。

感谢各位的阅读!关于"spl中如何实现手写数字识别"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

模型 训练 数字 图片 输入 代码 权重 测试 样本 正确率 文件 程序 语言 学习 输出 变量 数据 速度 像素 机器 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 上海挚品互联网科技有限公司 上海喔噻互联网科技有限公司 亿人帮互联网科技有限公司 山东特亿宝互联网科技有限公司 互联网金融 金融科技 深圳期待互联网科技 互联网科技咨询 随着互联网科技发展 互联网软件和科技 晓花互联网科技有限公司网址 哈尔滨屹滨互联网科技有限公司 华夏恒生互联网科技013171 威龙国际互联网科技公司 互联网营销推广黑科技 扫呗互联网科技有限公司 信承诺互联网科技有限公司 银川新华互联网科技学校原画 恒生互联网科技趋势 东风日产互联网科技公司叫什么 伍佰万互联网科技是干嘛的 互联网新科技 百单网互联网科技有限公司怎么样 互联网科技有限公司经营范围 鸠鸠互联网科技 卓越科技互联网 招聘 小米互联网科技园设置 允成互联网科技有限公司融资 河南住房之家互联网科技 互联网时代高科技布局 平安好医生打造互联网科技医疗
0