This is an alternative to a neural network that can also show the ability to recognize digits. Its accuracy is very similar to the neural network at around 90%, though better optimized neural networks can do much better than that. Its basic algorithm is to take the difference between a given image and a sample image that it creates over time.
In [7]:
%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib.pylab import *
from IPython.html.widgets import interact
from scipy.interpolate import griddata
import numpy as np
In [8]:
from sklearn.datasets import load_digits
digits = load_digits()
print(digits.data.shape)
In [9]:
"""Initialize the 10 sample images of each digit"""
i = 0
w = [0,0,0,0,0,0,0,0,0,0]
while i < 10:
w[i] = np.ones((8,8))
w[i] = np.matrix(w[i])
w[i] = w[i]/np.matrix.sum(w[i])
i = i + 1
In [4]:
def check_number(n,w,error):
p = digits.target[n]
x = np.matrix(digits.images[n])
x = x/np.matrix.sum(x)
u = -1
d = 10
for i in w: #For the input image and each sample image, take the difference and find the smallest error.
u = u + 1
z = np.absolute(x-i)
c = np.matrix.sum(z)
if c < d:
d = c
t = u
if t != p: #If the answer was incorrect, add a weak version of the input image to the correct sample image and subtract
#a weaker version of the imput from the sample image it guessed
w[t] = w[t] - (x/200)
w[t] = w[t]/np.matrix.sum(w[t])
w[p] = w[p] + (x/50)
w[p] = w[p]/np.matrix.sum(w[p])
error = error + 1
return [w,error]
In [5]:
percent_error = 0
while percent_error < 100: #This section of code iterates through the first thousand
#input images until it can guess them all correctly.
n = 0
ni = n
error = 0
while n < 1000:
error = check_number(n,w,error)[1]
w = check_number(n,w,error)[0]
n = n + 1
percent_error = -100*(((n-ni)-(check_number(n,w,error)[1]))/(ni-n))
print (check_number(n,w,error)[1], '/', n-ni, '->', percent_error, '% correct')
#This displays the sample images, which in theory, look like each digit.
j = -1
for i in w:
j = j + 1
plt.matshow(w[j], cmap=cm.gray)
In [6]:
#Now test the program on unseen data.
n = 1000
ni = n
error = 0
while n < 1700:
error = check_number(n,w,error)[1]
#w = check_number(n,w,error)[0]
n = n + 1
percent_error = -100*(((n-ni)-(check_number(n,w,error)[1]))/(ni-n))
print (check_number(n,w,error)[1], '/', n-ni, '->', percent_error, '% correct')
In [12]:
#The final form of the program, one that guesses the digit it is presented.
def guess_number(n,w):
x = np.matrix(digits.images[n])
x = x/np.matrix.sum(x)
d = 10
u = -1
for i in w:
u = u + 1
z = np.absolute(x-i)
c = np.matrix.sum(z)
if c < d:
d = c
t = u
print ('This looks like a', t)
plt.matshow(digits.images[n], cmap=cm.gray)
print("The right answer is", digits.target[n])
In [13]:
h = 1700
In [16]:
guess_number(h,w)
h = h+1
In [ ]: