A Neural Network Implementation of Optical Character Recognition

advertisement
Technical Report Number CSSE10-05
Brandon Maharrey
maharbk@auburn.edu
COMP 6600 – Artificial Intelligence
Spring 2009
Final Project Technical Report
A Neural Network Implementation of Optical Character
Recognition
Introduction
In today’s world of high technology, there is a greater want to convert the analog into digital. Since the
advent of digital scanners after the computer came onto the scene, there has been the want to convert
books/text into digital media viewable over the internet and/or on a computer. This is where optical
character recognition comes in handy.
What is Optical Character Recognition?
Optical Character Recognition (OCR) is the mechanical or electronic translation of images of
handwritten, typewritten or printed text (usually captured by a scanner) into a machine-editable text. It is
often used to convert paper books and documents into electronic files. “When one scans a paper page
into a computer, it produces just an image file, a photo of the page. The computer cannot understand the
letters on the page, so you cannot search for words or edit it and have the words re-wrap as you type, or
change the font, as in a word processor. You would use OCR software to convert it into a text or word
processor file so that you could do those things. The result is much more flexible and compact than the
original page photo” (Wikipedia.org [http://en.wikipedia.org/wiki/Optical_character_recognition]).
OCR can get quite complicated. For instance, noise, distortion or skewing in the scanned image could
disrupt the OCR algorithm to such an extent so as to make recognition impossible. This is why OCR is
generally statistical in nature. This means that generally no OCR algorithm is fully suited to every
possible scenario. For type-written books, a simpler OCR algorithm may best suite the digit recognition
process while a much more complex OCR algorithm would be required to recognize digits which contain
noise or distortion. For some forensic labs which analyze handwriting on, perhaps, broken scraps of
paper, a much more complex OCR algorithm would be required than is implemented in this semester
project.
Many Forms and Uses of OCR
OCR can take many different forms and has many different uses. For instance, a whole page of text could
be scanned into a computer, and the OCR software could take as input this whole page of text and output
a corresponding machine-editable font. The software could also take as input single characters or digits
and output the corresponding character or digit. OCR also has uses in forgery detection. For instance,
forgery detection could be used in the banking industry to detect forgeries on checks. Obviously this
could save banks time and money because the bank could not waste time giving credit for forged checks.
This could give banks the opportunity to contact the supposed signee to verify the owner of the account
actually signed the check.
Final Project Write-Up
Digit Organization
Technical Report Number CSSE10-05
For this project, I implemented a very simple nearest neighbor OCR algorithm. The training and test
image sets are used to train and test the neural network, respectively. The neural network is trained on the
training set and tested on the test set. There are 60,000 training images and 10,000 test images. The test
and training sets are organized in the IDX file format, a simple format for vectors and multidimensional
matrices of numerical types. Each image is 28 pixels wide by 28 pixels high, and each pixel is
represented by a byte. A value of 0 represents white, and a value of 255 represents black. Values
between 0 and 255 represent grayscale shades.
The files are organized at the byte level and are organized as follows:
The following is the organization of the training set label file. In my program, I begin reading from offset
8 in the training and test set label files.
The following is the organization of the training set file. In my program, I begin reading from offset 16 in
the training and test set files.
The following is the organization of the test set label file.
The following is the organization of the test set file.
Technical Report Number CSSE10-05
Here is a look at the first few training digits.
This image is representative of the digit 5.
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 003 018 018 018 126 136 175 026 166 255 247 127 000 000 000 000
000 000 000 000 000 000 000 000 030 036 094 154 170 253 253 253 253 253 225 172 253 242 195 064 000 000 000 000
000 000 000 000 000 000 000 049 238 253 253 253 253 253 253 253 253 251 093 082 082 056 039 000 000 000 000 000
000 000 000 000 000 000 000 018 219 253 253 253 253 253 198 182 247 241 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 080 156 107 253 253 205 011 000 043 154 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 014 001 154 253 090 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 139 253 190 002 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 011 190 253 070 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 035 241 225 160 108 001 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 081 240 253 253 119 025 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 045 186 253 253 150 027 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 016 093 252 253 187 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 249 253 249 064 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 046 130 183 253 253 207 002 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 039 148 229 253 253 253 250 182 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 024 114 221 253 253 253 253 201 078 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 023 066 213 253 253 253 253 198 081 002 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 018 171 219 253 253 253 253 195 080 009 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 055 172 226 253 253 253 253 244 133 011 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 136 253 253 253 212 135 132 016 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
This image is representative of the digit 0.
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 051 159 253 159 050 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 048 238 252 252 252 237 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 054 227 253 252 239 233 252 057 006 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 010 060 224 252 253 252 202 084 252 253 122 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 163 252 252 252 253 252 252 096 189 253 167 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 051 238 253 253 190 114 253 228 047 079 255 168 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 048 238 252 252 179 012 075 121 021 000 000 253 243 050 000 000 000 000 000
000 000 000 000 000 000 000 000 038 165 253 233 208 084 000 000 000 000 000 000 253 252 165 000 000 000 000 000
000 000 000 000 000 000 000 007 178 252 240 071 019 028 000 000 000 000 000 000 253 252 195 000 000 000 000 000
000 000 000 000 000 000 000 057 252 252 063 000 000 000 000 000 000 000 000 000 253 252 195 000 000 000 000 000
000 000 000 000 000 000 000 198 253 190 000 000 000 000 000 000 000 000 000 000 255 253 196 000 000 000 000 000
000 000 000 000 000 000 076 246 252 112 000 000 000 000 000 000 000 000 000 000 253 252 148 000 000 000 000 000
000 000 000 000 000 000 085 252 230 025 000 000 000 000 000 000 000 000 007 135 253 186 012 000 000 000 000 000
000 000 000 000 000 000 085 252 223 000 000 000 000 000 000 000 000 007 131 252 225 071 000 000 000 000 000 000
000 000 000 000 000 000 085 252 145 000 000 000 000 000 000 000 048 165 252 173 000 000 000 000 000 000 000 000
000 000 000 000 000 000 086 253 225 000 000 000 000 000 000 114 238 253 162 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 085 252 249 146 048 029 085 178 225 253 223 167 056 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 085 252 252 252 229 215 252 252 252 196 130 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 028 199 252 252 253 252 252 233 145 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 025 128 252 253 252 141 037 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
This image is representative of the digit 4.
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 067 232 039 000 000 000 000 000
000 000 000 000 062 081 000 000 000 000 000 000 000 000 000 000 000 000 000 000 120 180 039 000 000 000 000 000
000 000 000 000 126 163 000 000 000 000 000 000 000 000 000 000 000 000 000 002 153 210 040 000 000 000 000 000
000 000 000 000 220 163 000 000 000 000 000 000 000 000 000 000 000 000 000 027 254 162 000 000 000 000 000 000
000 000 000 000 222 163 000 000 000 000 000 000 000 000 000 000 000 000 000 183 254 125 000 000 000 000 000 000
000 000 000 046 245 163 000 000 000 000 000 000 000 000 000 000 000 000 000 198 254 056 000 000 000 000 000 000
000 000 000 120 254 163 000 000 000 000 000 000 000 000 000 000 000 000 023 231 254 029 000 000 000 000 000 000
000 000 000 159 254 120 000 000 000 000 000 000 000 000 000 000 000 000 163 254 216 016 000 000 000 000 000 000
000 000 000 159 254 067 000 000 000 000 000 000 000 000 000 014 086 178 248 254 091 000 000 000 000 000 000 000
000 000 000 159 254 085 000 000 000 047 049 116 144 150 241 243 234 179 241 252 040 000 000 000 000 000 000 000
000 000 000 150 253 237 207 207 207 253 254 250 240 198 143 091 028 005 233 250 000 000 000 000 000 000 000 000
000 000 000 000 119 177 177 177 177 177 098 056 000 000 000 000 000 102 254 220 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 169 254 137 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 169 254 057 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 169 254 057 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 169 255 094 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 169 254 096 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 169 254 153 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 169 255 153 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 096 254 153 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
This image is representative of the digit 1.
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 124 253 255 063 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 096 244 251 253 062 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 127 251 251 253 062 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 068 236 251 211 031 008 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 060 228 251 251 094 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 155 253 253 189 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 020 253 251 235 066 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 032 205 253 251 126 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 104 251 253 184 015 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 080 240 251 193 023 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 032 253 253 253 159 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 151 251 251 251 039 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 048 221 251 251 172 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 234 251 251 196 012 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 253 251 251 089 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 159 255 253 253 031 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 048 228 253 247 140 008 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 064 251 253 220 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 064 251 253 220 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 024 193 253 220 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
This image is representative of the digit 9.
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 055 148 210 253 253 113 087 148 055 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 087 232 252 253 189 210 252 252 253 168 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 004 057 242 252 190 065 005 012 182 252 253 116 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 096 252 252 183 014 000 000 092 252 252 225 021 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 132 253 252 146 014 000 000 000 215 252 252 079 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 126 253 247 176 009 000 000 008 078 245 253 129 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 016 232 252 176 000 000 000 036 201 252 252 169 011 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 022 252 252 030 022 119 197 241 253 252 251 077 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 016 231 252 253 252 252 252 226 227 252 231 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 055 235 253 217 138 042 024 192 252 143 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 062 255 253 109 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 071 253 252 021 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 253 252 021 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 071 253 252 021 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 106 253 252 021 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 045 255 253 021 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 218 252 056 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 096 252 189 042 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 014 184 252 170 011 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 014 147 252 042 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
This image is representative of the digit 2.
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 013 025 100 122 007 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 033 151 208 252 252 252 146 000 000 000 000 000 000 000 000
Technical Report Number CSSE10-05
000 000 000 000 000 000 000 000 000 000 000 040 152 244 252 253 224 211 252 232 040 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 015 152 239 252 252 252 216 031 037 252 252 060 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 096 252 252 252 252 217 029 000 037 252 252 060 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 181 252 252 220 167 030 000 000 077 252 252 060 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 026 128 058 022 000 000 000 000 100 252 252 060 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 157 252 252 060 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 110 121 122 121 202 252 194 003 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 010 053 179 253 253 255 253 253 228 035 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 005 054 227 252 243 228 170 242 252 252 231 117 006 000 000 000 000 000 000 000
000 000 000 000 000 000 000 006 078 252 252 125 059 000 018 208 252 252 252 252 087 007 000 000 000 000 000 000
000 000 000 000 000 000 005 135 252 252 180 016 000 021 203 253 247 129 173 252 252 184 066 049 049 000 000 000
000 000 000 000 000 003 136 252 241 106 017 000 053 200 252 216 065 000 014 072 163 241 252 252 223 000 000 000
000 000 000 000 000 105 252 242 088 018 073 170 244 252 126 029 000 000 000 000 000 089 180 180 037 000 000 000
000 000 000 000 000 231 252 245 205 216 252 252 252 124 003 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 207 252 252 252 252 178 116 036 004 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 013 093 143 121 023 006 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
Training the Network
To train the network, I created a simple 10 x 28 x 28 matrix to hold the digits [0, 9] in a grid of 28 pixels
by 28 pixels. Here’s the C code I used to train the network:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
for (k = 0; k < 60000; k++) {
if (k % 5000 == 0) {
printf("%d images remaining to train\n", 60000 - k);
fprintf(outputFP, "%d images remaining to train\n", 60000 - k);
}
imgToTrain = (int)extract(lblFP, lblOffset, 1);
digitCounts[imgToTrain]++;
fprintf(outputFP, "Training the network on digit %d:\n", imgToTrain);
lblOffset++;
for (i = 0; i < 28; i++) {
for (j = 0; j < 28; j++) {
val = (int)extract(imgFP, imgOffset, 1);
trainImage[imgToTrain][i][j] += val;
imgOffset++;
if (val >= 0 && val <= 9) {
// printf("00%d ", val);
fprintf(outputFP, "00%d ", val);
} else if (val >= 10 && val <= 99) {
// printf("0%d ", val);
fprintf(outputFP, "0%d ", val);
} else {
// printf("%d ", val);
fprintf(outputFP, "%d ", val);
}
}
//printf("\n");
fprintf(outputFP, "\n");
}
//printf("\n\n");
fprintf(outputFP, "\n\n");
}
32.
33.
34.
35.
36.
37.
38.
for (m = 0; m < 10; m++) {
for (i = 0; i < 28; i++) {
for (j = 0; j < 28; j++) {
imageNetwork[m][i][j] = ((double)trainImage[m][i][j]) / ((double)digitCounts[m]);
}
}
}
Lines 1 – 31 walk through the training set images and training set labels. I print out a message to the user
in lines 2-4 every 5000 trained images to let the user know the program is actually doing work. In line 6,
I extract the label of the image to be trained and increment the offset in the training set label file in line 9.
I also increment digitCounts in line 7 for the corresponding image to keep track of how many images I’ve
trained the network on. Next, in lines 10 – 28 I grab the next 28 x 28 = 784 values from the training set
file and add them to the previous values of the training image in line 13. The if-else-if block in lines 15 –
24 take care of formatting and lines 26 & 27 and 29 & 30 take care of line breaks in output.txt. This
essentially takes each new training digit k and directly overlays its image on top of all the previous
training data for digit k and adds the current value to the previous values. As an example, consider the
following toy example:
Training image “1”:
000000
003000
002800
008500
007700
009300
003600
002600
008900
003900
000600
000680
007800
038000
007000
gives
Technical Report Number CSSE10-05
000000
000600
000000
00 00 03 06 00 00
00 00 10 20 08 00
00 00 23 18 00 00
00 03 13 12 00 00
00 00 18 18 00 00
00 00 00 06 00 00
after adding the corresponding digits in each of the training images.
After the for loop ends at line 31, the next set of for loops takes care of “squashing” the data in the neural
network, essentially averaging all the values in the network by dividing each digit’s neural network
representation by the total number of training digits encountered for that digit. Lines 32 – 38, specifically
line 35, takes care of dividing each pixel position in the neural network by the total number of digits
encountered.
Continuing with the example above, the neural network would become the following:
0.0 0.0 1.0 2.0 0.0 0.0
0.0 0.0 3.3 6.6 2.6 0.0
0.0 0.0 7.6 9.0 0.0 0.0
0.0 1.0 6.5 4.0 0.0 0.0
0.0 0.0 9.0 9.0 0.0 0.0
0.0 0.0 0.0 2.0 0.0 0.0
After this process is complete, training of the neural network is complete.
Analyzing Test Images Against the Neural Network
The code for analyzing a test image against the trained neural network is as follows:
Technical Report Number CSSE10-05
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
for (k = 0; k < 10000; k++) {
if (k % 1000 == 0) {
printf("%d images remaining to test\n", 10000 - k);
fprintf(outputFP, "%d images remaining to test\n", 10000 - k);
}
trueVal = (int)extract(lblFP, lblOffset, 1);
//printf("\n\nAnalyzing the image:\n");
fprintf(outputFP, "\n\nAnalyzing the image:\n");
lblOffset++;
for (i = 0; i < 28; i++) {
for (j = 0; j < 28; j++) {
val = (int)extract(imgFP, imgOffset, 1);
testImage[i][j] = val;
if (val >= 0 && val <= 9) {
//printf("00%d ", val);
fprintf(outputFP, "00%d ", val);
} else if (val >= 10 && val <= 99) {
//printf("0%d ", val);
fprintf(outputFP, "0%d ", val);
} else {
//printf("%d ", val);
fprintf(outputFP, "%d ", val);
}
imgOffset++;
}
//printf("\n");
fprintf(outputFP, "\n");
}
29.
30.
31.
32.
33.
34.
35.
36.
// compare the test image against the training images
for (i = 0; i < 10; i++) {
for (m = 0; m < 28; m++) {
for (n = 0; n < 28; n++) {
digitStats[i] += pow(imageNetwork[i][m][n] - (double)testImage[m][n], 2.0);
}
}
}
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
// make a guess
int firstGuessCorrect = 0, secondGuessCorrect = 0;
int minIndex = 0;
double minVal = DBL_MAX;
for (i = 0; i < 10; i++) {
if (minVal > digitStats[i]) {
minIndex = i;
minVal = digitStats[i];
}
}
firstGuess = minIndex;
//printf("First guess: %d\n", firstGuess);
fprintf(outputFP, "First guess: %d\n", firstGuess);
if (firstGuess == trueVal) {
numCorrectFirstGuesses++;
firstGuessCorrect = 1;
} else {
numWrongFirstGuesses++;
}
minVal = DBL_MAX;
if (firstGuessCorrect == 0) {
for (i = 0; i < 10; i++) {
if (i == firstGuess) {
continue;
} else {
if (minVal > digitStats[i]) {
minIndex = i;
minVal = digitStats[i];
}
}
}
secondGuess = minIndex;
//printf("Second guess: %d\n", secondGuess);
fprintf(outputFP, "Second guess: %d\n", secondGuess);
if (secondGuess == trueVal) {
numCorrectSecondGuesses++;
secondGuessCorrect = 1;
} else {
numWrongSecondGuesses++;
}
}
minVal = DBL_MAX;
if (secondGuessCorrect == 0 && firstGuessCorrect == 0) {
for (i = 0; i < 10; i++) {
if ((i == firstGuess) || (i == secondGuess)) {
continue;
} else {
if (minVal > digitStats[i]) {
minIndex = i;
minVal = digitStats[i];
}
}
}
thirdGuess = minIndex;
//printf("Third guess: %d\n", thirdGuess);
Technical Report Number CSSE10-05
92.
93.
94.
95.
96.
97.
98.
fprintf(outputFP, "Third guess: %d\n", thirdGuess);
if (thirdGuess == trueVal) {
numCorrectThirdGuesses++;
} else {
numWrongThirdGuesses++;
}
}
99.
100.
//printf("Actual digit: %d\n", trueVal);
fprintf(outputFP, "Actual digit: %d\n", trueVal);
101.
102.
103.
104.
105.
// reset digitStats for the next image
for (i = 0; i < 10; i++) {
digitStats[i] = 0.0;
}
}
Lines 1 – 105 analyze the 10,000 test images and compare each test image to each of the trained neural
network digits. Lines 2 – 5 print out a message after every 1000 images have been tested to indicate to
the user the program is actually performing some work. Line 6 extracts from the training set label file the
actual value of the test image this OCR algorithm is trying to guess. Lines 10 – 28 actually extract the
test image from the test set image file and save it in testImage in line 13. Lines 30 – 36, specifically line
33, calculates the standard deviation of the test image values from the trained neural network values and
keeps track of the value in the variable digitStats. After line 36, digitStats[k] contains the standard
deviation of the pixel values of digit k from the test image. My algorithm assumes the minimum value
held in the whole array digitStats after line 36 corresponds to the actual value of the digit. Therefore, if
digitStats[k] contains the minimum value in digitStats, then the test image is guessed to be digit k. Lines
37 – 55 make a first guess. If this first guess is incorrect, lines 56 – 77 make a second guess. If the first
guess and the second guess are incorrect, lines 78 – 98 make a third guess. The program then prints the
actual digit. Lines 102 – 104 reset digitStats[i] to zero to hold the statistics for the next test image.
OCR Results
Surprisingly the program was able to correctly determine the digit displayed in 82% of the images.
Results:
First guess identified 8203 of 10000, that is 82.030000%.
Second guess identified 967 of 1797, that is 53.811909%.
Third guess identified 383 of 830, that is 46.144578%.
Overall identified 9553 of 10000, that is 95.530000%.
Conclusion
While the nearest neighbor approach to digit recognition is not fool-proof, it is easy to see that this very
simple and naïve implementation could be used as the basis for other OCR work. Extensions of this work
could be to add the capability to feed the program pages of text so that the program must do preprocessing
work to single out characters.
References
1. Ji, A. and George, R. “A Nearest Neighbor Approach to Letter Recognition.” ACM SE, 2006.
2. Wu, M. “Handwritten Character Recognition.” Submitted for the degree of Bachelor of
Engineering (Honors) in the division of Electrical Engineering, 2003.
Download