概述
CP/M-80(兼容)神经网络手写字符识别LSX-道奇队和 MSX-DOS)。
Z-80 是 1976 年开发的 8 位 CPU,可以识别 28 x 28 像素的数字 (0-9) 的类型。
(2022-10-05 在 MZ-700 上添加了执行示例)
执行方式
具有训练有素的网络和样本数据的 GitHub磁盘映像对公众开放,因此您可以轻松地将其与 X1 仿真器或 MSX 仿真器一起使用。关于使用 X1 模拟器和 LSX-Dosgers 时的环境构建设置 X1 模拟器环境请参阅
磁盘镜像中的MNIST.COM是可执行文件,MNMODEL.BIN是MNIST是在数据集上训练的网络的权重数据。
MNMODEL.BIN 必须放在当前驱动器中(可以使用分层目录的操作系统上的当前目录)。
MNIST.COM [画像ファイル名]
图像文件格式
它是一个 28×28 像素的 256 级灰度图像,是一个 784 字节的未压缩、无标题的二进制文件。具体来说,格式如下。
[ピクセルの階調 1byte][ピクセルの階調 1byte]...[ピクセルの階調 1byte] ← 1ライン目 28byte
[ピクセルの階調 1byte][ピクセルの階調 1byte]...[ピクセルの階調 1byte] ← 2ライン目 28byte
・
・
・
[ピクセルの階調 1byte][ピクセルの階調 1byte]...[ピクセルの階調 1byte] ← 28ライン目 28byte
使用 model_training/make_mnist_beta.rb 从 MNIST 数据集(train-images-idx3-ubyte 和 train-labels-idx1-ubyte)中提取二进制格式的图像。
图像文件查看器
包括一个用于 LSX-Dodgers 的程序(由于直接访问工作区,仅限于 1.40 版),它以上一节中描述的格式抖动和显示图像文件。 2个像素有16个渐变,用8x4点表示,但是将2个像素组合的8x8点定义为PCG,用14行文字显示28行图像。
SETPCG.COM DITHER.PCG
MNVIEW.COM IMG_0_5.BIN
SETPCG.COM的来源是https://github.com/meister68k/setpcg_X1在
执行示例
目标图像预览。
在执行第一层(卷积层)期间。让我们在这里花点时间。
第一层的输出结果是 13 x 13,其中的数字像 ASCII 艺术一样排列。其下,10个数字是最后一层的输出结果,准确率从左起依次为0到9。在这种情况下,数字 5 是 188,这是最有可能的,数字 7 是 63,这是时间点。
最后一行显示识别结果,正确识别为“result = 5”,即数字5。
我认为识别率约为90%。
“没有什么是不可能的” MZ-700 也有效。 35 年前,您会因为在 Oh!MZ 上发帖而获得一块金子。
(使用 LSX-Dodgers 1.43(适用于 MZ-700/1500 v0.01))
技术细节
基本策略
量化在 MNIST 手写数字数据集上训练的网络并在定点上运行。
重要的是尽可能减少网络参数的数量,以适应 8 位 CPU 可以执行的大小,并以 8 到 16 位完成计算。
网络结构
网络配置如下表所示。由输入层、卷积层和全连接层组成的三层神经网络。卷积层的核大小为 3×3×8。
| 层 | 输出形状 | 参数# | 激活 |
|---|---|---|---|
| 输入 | (28, 28) | 0 | 没有任何 |
| 二维卷积 | (13, 13, 8) | 80 | ReLU |
| 全连接 | (10) | 13520 | ReLU (Softmax) |
参数总数为13600个,由于1个参数用1个字节表示,数据量超过13K字节。
作为减少参数数量的一种手段,将卷积层的步幅设置为2,并将输入图像的大小调整为1/2左右。我们还省略了全连接层的偏差。
对于全连接层的激活函数,Softmax只在训练时使用,ReLU在CP/M推理时使用。
学习
使用 Google Colab 使用 Python + TensorFlow 实现训练网络,并以 JSON 格式输出权重。我们在 10 个 epoch 内完成了训练。
model_training/MNIST_minimum.ipynb 是训练网络源。
以 json 格式输出学习到的网络权重。
量化
以双精度实数格式训练的网络权重被量化为具有 1 位符号、2 位整数精度和 5 位小数精度的 8 位定点格式。卷积层的输出也有 5 位小数精度,但是由于它是无符号的,所以它有 3 位整数精度。分层计算为 16 位,以防止溢出。
输入图像是一个介于 0 和 255 之间的值,对应于 0.0 和 1.0 之间的亮度。因此,需要将输入值减小到 1/255 的处理,但是为了加速将其替换为 1/256,卷积层的权重提前乘以 256/255。
| 层 | 符号 | 整数 | 分数 |
|---|---|---|---|
| 输入 | 0 | 0 | 8位 |
| Conv2D(重量) | 1 位 | 2位 | 5位 |
| Conv2D(输出) | 0 | 3位 | 5位 |
| F.C.(重量) | 1 位 | 2位 | 5位 |
| FC(输出) | 0 | 3位 | 5位 |
在 model_training/NNSS-V_MNIST.rb 中,json 格式的权重被读取、量化,并以 json 格式再次输出。
权重的二进制格式
我将量化权重存储在二进制文件中。它只是一个包含 8 位整数的文件,没有任何特定的标题。偏移值如下表所示。
| 抵消 | 包含 | 形状 |
|---|---|---|
| 0 | Conv2D 偏差 | “8” |
| 8 | Conv2D 内核 | “3” “3” “8” |
| 80 | F.C.内核 | “1352” “10” |
在 model_training/make_weights.rb 中加载量化的 json 格式权重并以二进制格式输出。使用 CP/M 上的输出二进制文件。
使用的编译器
z88dk用过的。
您可以在 C99 扩展的块中使用变量声明、单行注释 (//) 和 stdint.h。但是,虽然可以声明多维数组的类型,但实际访问行为是可疑的,所以将其转换为一维数组并进行访问。
void example(uint8_t hoge[][SIZE], int x, int y)
{
uint8_t a = hoge[y][x]; // NG?
uint8_t b = hoge[0][y * SIZE + x]; // OK
}
这是一种可以完成的技术,因为它不检查下标范围。
开发时的执行环境(CP/M模拟器)
开发中Win32 CP/M 播放器确认它可以在 8 位机器上使用通用源代码项目的X1模拟器eX1,LSX-Dodgers 1.23版的修改版(围绕SP修改,体现在原版1.40),CP/M V2.2(夏普型号Language Master CZ-128SF)。
在最后
我想我第一次实现神经网络是在 1991 年夏天。一开始Hu-BASIC for X1太慢了,所以我用αFORTRAN重写了。我终于完成了我 30 岁的作业。
参考
- 挑战神经计算机,Satoru Shiono,Agne Shofusha,1990,ISBN 4-900508-03-9
- 介绍性神经计算机,Toyohiko Kikuchi,Ohmsha,1990,ISBN 4-274-07547-8
原创声明:本文系作者授权爱码网发表,未经许可,不得转载;
原文地址:https://www.likecs.com/show-308627044.html