识别手写数字


22

您的任务是读取包含手写数字的图像,识别并打印数字。

输入:一个28 * 28灰度图像,以784个纯文本数字序列(从0到255)给出,以空格分隔。0表示白色,255表示黑色。

输出:识别的数字。

评分:我将使用MNIST数据库训练集中的1000张图像(转换为ASCII格式)测试您的程序。我已经(随机)选择了图像,但是不会发布列表。测试必须在1小时内完成,并将确定n-正确答案的数量。
n您的程序必须至少为200才有资格。如果源代码的大小为s,则您的分数将计算为s * (1200 - n) / 1000。最低分获胜。

规则:

  • 您的程序必须从标准输入读取图像并将数字写入标准输出
  • 没有内置的OCR功能
  • 没有第三方库
  • 没有外部资源(文件,程序,网站)
  • 您的程序必须可以使用免费提供的软件在Linux中运行(如果需要,可以接受Wine)
  • 源代码只能使用ASCII字符
  • 每次修改答案时,请发布您的估计分数和唯一的版本号

输入示例:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 18 18 18 126 136 175 26 166 255 247 127 0 0 0 0 0 0 0 0 0 0 0 0 30 36 94 154 170 253 253 253 253 253 225 172 253 242 195 64 0 0 0 0 0 0 0 0 0 0 0 49 238 253 253 253 253 253 253 253 253 251 93 82 82 56 39 0 0 0 0 0 0 0 0 0 0 0 0 18 219 253 253 253 253 253 198 182 247 241 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 80 156 107 253 253 205 11 0 43 154 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 14 1 154 253 90 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 139 253 190 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 190 253 70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 35 241 225 160 108 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 81 240 253 253 119 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 45 186 253 253 150 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 93 252 253 187 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 249 253 249 64 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 46 130 183 253 253 207 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 39 148 229 253 253 253 250 182 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24 114 221 253 253 253 253 201 78 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 23 66 213 253 253 253 253 198 81 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 171 219 253 253 253 253 195 80 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 55 172 226 253 253 253 253 244 133 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 136 253 253 253 212 135 132 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

顺便说一句,如果您将此行添加到输入的前面:

P2 28 28 255

您将获得有效的pgm格式的图像文件,该文件的颜色为反相/负色。

正确的颜色是这样的: 数字

输出示例:

5

排名:

No.| Name         | Language   | Alg | Ver | n   | s   |  Score
----------------------------------------------------------------
 1 | Peter Taylor | GolfScript | 6D  | v2  | 567 | 101 |  63.933
 2 | Peter Taylor | GolfScript | 3x3 | v1  | 414 | 207 | 162.702

相关但不完全相同(不是挑战,但对于查找乳胶代码非常有用):detexify.kirelabs.org/classify.html。它还可以识别数字。
贾斯汀

1
我们可以安全地假设我们只需要考虑黑色像素吗?> 127像素?我们可以假设什么?
贾斯汀

2
特别是如果这是一个打高尔夫球的代码问题,请限制为黑白输入。人们无需解决代码中的字符就可以解决这个问题,从而使自己的整个职业生涯成为现实。不发布您选择的角色是停止作弊的一种方法,并且使其成为一场赌博...而且鉴于人们在此处编写AI是不合理的,这种乐趣是在进行一些奇怪的启发式尝试,然后看看效果如何它在比赛还是比赛中都有。
Rebmu博士2014年

3
@aditsu是的,任何人都做得不好。但是,您并不是要要求做得不好,而是要有人在衡量字符数的比赛中“获胜”。我认为,对于爱好者的难题解决者来说,将问题简化一点更为现实。限制输入似乎是使其合理的良好开端。我建议对输入进行预传递,以说它是黑白的。
Rebmu博士2014年

2
@ Dr.Rebmu和其他想要黑白输入的人:可以使用诸如128之类的阈值随意转换输入。您也可以尝试其他阈值,它们可能会产生更好的结果。
aditsu

Answers:


6

GolfScript 6D(v2:估计分数101 * 0.63〜= 64)

这是我以前的GolfScript答案的非常不同的方法,因此将其作为单独的答案发布在v1上比编辑其他答案并制作为v2更有意义。

~]:B;569'!EM,R.==|%NL2+^=1'{{32-}%95{base}:^~\^}:&~2/{~B=<}%2^10'#]8Y,;KiZfnnRsDzPsvQ!%4C&..z,g,$m'&=

不打高尔夫球

~]:B;
[30 183 21 378 31 381 7 461 113 543 15 568]
2/{~B=<}%2base
7060456576664262556515119565486100005262700292623582181233639882 10base
=

说明

原始问题是在784维空间中的点分类。一种标准方法是降维:识别一小部分尺寸,这些尺寸可以提供足够的区分能力来进行分类。我评估了每个维度和每个可能的阈值,以识别出18对(尺寸,阈值范围)看起来很有希望的对。然后,我选择了每个阈值范围的中心,并评估了18对中的6个元素子集。最后,我针对最佳6D投影的每个维度优化了阈值,将其准确性从56.3%提高到56.6%。

由于投影分为6个维度,因此我为每个维度应用了一个简单的阈值,因此最终查找表仅需要64个元素。它似乎并不是特别可压缩,因此主要的打法是将两个查找表(尺寸和阈值列表;以及将半空间矢量转换为数字图)进行基本转换,并共享基本转换代码。


7
您在“ 784维空间”迷失了我;-)
Digital Trauma 2014年

恐怕某个地方有错误,我只有37个正确答案。另外,您使事情有些模棱两可,您能不能像我一样添加(1)和(2)或类似您的标题?
aditsu

@aditsu,简单的逻辑错误。现在已修复。
彼得·泰勒

因此,基本上,您要采样6个“相关”像素,每个像素具有不同的阈值,以获得6位?
2014年

@aditsu,完全是。
彼得·泰勒

5

GolfScript 3x3(v1:估计得分207 * 0.8〜= 166)

~]28/10:?/{zip?/{[]*0-!!}/}%2{base}:^~'"yN(YZ5B 7k{&w,M`f>wMb>}F2A#.{E6T9kNP_s 3Q?V`;Z\'C-z*kA5M@?l=^3ASH/@*@HeI@A<^)YN_bDI^hgD>jI"OUWiGct%7/U($*;h*<"r@xdTz6x~,/M:gT|\\:#cII8[lBr<%0r&y4'{32-}%95^?^2/{))*~}%=

或概述

~]28/10:?/{zip?/{[]*0-!!}/}%2{base}:^~'MAGIC STRING'{32-}%95^?^2/{))*~}%=

说明

我的高级方法是:

  1. 阈值像素:如果像素在上方,t1则将其设置为1;否则去0
  2. 对像素进行分组。最初,我将28x28网格划分为4x4网格(每个子网格为7x7像素);但将其分成3x3网格(子网格为10x10、10x8或8x8像素)可以大大减小查找表的大小,同时将准确率从大约56%降低到大约40%。
  3. 对每个组中的像素求和并再次阈值:如果设置的像素数大于,t2则将该组记为1;否则为0
  4. 通过组分数的向量进行表格查找。(该表是使用游程长度编码和标准的基本转换特技压缩。的大多数选择t1t250%,并且如表63%之间离去“不关心”的值,其可以与以增加相邻值被组合游程长度;我的v1表中的平均游程长度为3.6)。

事实证明,设置t1=t2=0虽然不是最佳的,但在精度方面t1和最佳值相差不远t2。在表可压缩性方面非常好;并允许我将两个阈值运算组合为[]*0-!!(将2D数组展平为1D;删除0s;检查其是否为空)。

查找表给出给定组分数向量的最可能候选者。通过标识可以更改的表条目来改善分数,这很可能是可行的,以使表的改进的可压缩性超过降低的准确性。


太棒了,我有一个类似的想法,但是没有想到它可以压缩得那么好。现在,我认为我需要更加强调准确性:p,但我不打算对其进行更改。
aditsu 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.