In [1]:
# Import all modules
%matplotlib inline
import random
import pylab
import pickle as pkl
import numpy as np
import pandas as pd
from scipy.misc import imread, imresize
from lasagne import layers, updates
from theano.tensor.nnet import softmax
from nolearn.lasagne import NeuralNet
from nolearn.lasagne import BatchIterator
from sklearn.cross_validation import train_test_split
from sklearn.metrics import classification_report, accuracy_score
script_root = '/home/faizy/workspace/project/project/scripts/'
data_root = '/home/faizy/workspace/project/project/datasets/'
model_root = '/home/faizy/workspace/project/project/models/'
In [2]:
# Load dataset
data = pd.read_csv(script_root + 'LISTFILE.txt', sep = ' ', header = None)
In [3]:
# Visualize dataset
from scipy.misc import imread as ims
i = random.randrange(0, data[0].count())
img = ims(data_root + 'English/' + data[0][i])
pylab.imshow(img)
pylab.show()
In [4]:
data[1].count()
Out[4]:
In [5]:
# Reshape images to 32x32
# Conversion to grayscale
data_x = np.zeros((data[0].count(), 1, 32, 32))
data_y = data[1].values
for idx, path in enumerate(data[0]):
img = imread(data_root + 'English/' + path)
img = imresize(img, (32, 32))
if len(img.shape) == 3:
data_x[idx, ...] = img.dot([0.299, 0.587, 0.144])
else:
data_x[idx, ...] = img
data_x = data_x.astype('float32')
# Divide dataset to train and test
train1_x, test1_x, train1_y, test1_y = train_test_split(data_x, data_y, test_size = 0.2)
In [6]:
print "Train_x Shape: ", train1_x.shape, "\nTest_x Shape: ", test1_x.shape,"\nTrain_y Shape: ", train1_y.shape,"\nTest_y Shape: ", test1_y.shape
In [7]:
# Normalize by MuSigma
train1_x /= train1_x.std(axis = None)
train1_x -= train1_x.mean()
test1_x /= test1_x.std(axis = None)
test1_x -= test1_x.mean()
In [8]:
# Setting X and Y
X = train1_x.astype('float32')
y = train1_y.astype('int32')
In [19]:
# setting nn
net = NeuralNet(
layers = [
('input', layers.InputLayer),
('conv1', layers.Conv2DLayer),
('pool1', layers.MaxPool2DLayer),
('dropout1', layers.DropoutLayer),
('conv2', layers.Conv2DLayer),
('pool2', layers.MaxPool2DLayer),
('dropout2', layers.DropoutLayer),
('conv3', layers.Conv2DLayer),
('pool3', layers.MaxPool2DLayer),
('dropout3', layers.DropoutLayer),
('conv4', layers.Conv2DLayer),
('pool4', layers.MaxPool2DLayer),
('dropout4', layers.DropoutLayer),
('conv5', layers.Conv2DLayer),
('pool5', layers.MaxPool2DLayer),
('dropout5', layers.DropoutLayer),
('conv6', layers.Conv2DLayer),
('dropout6', layers.DropoutLayer),
('hidden7', layers.DenseLayer),
('output', layers.DenseLayer),
],
input_shape = (None, 1, 32, 32),
conv1_num_filters = 32, conv1_filter_size = (3, 3), conv1_pad = 2,
pool1_pool_size = (2, 2),
dropout1_p = 0.2,
conv2_num_filters = 64, conv2_filter_size = (2, 2), conv2_pad = 2,
pool2_pool_size = (2, 2),
dropout2_p = 0.3,
conv3_num_filters = 128, conv3_filter_size = (2, 2), conv3_pad = 2,
pool3_pool_size = (2, 2),
dropout3_p = 0.3,
conv4_num_filters = 128, conv4_filter_size = (2, 2), conv4_pad = 2,
pool4_pool_size = (2, 2),
dropout4_p = 0.3,
conv5_num_filters = 128, conv5_filter_size = (2, 2), conv5_pad = 2,
pool5_pool_size = (2, 2),
dropout5_p = 0.3,
conv6_num_filters = 128, conv6_filter_size = (3, 3),
dropout6_p = 0.5,
hidden7_num_units = 128,
output_num_units = 62, output_nonlinearity = softmax,
batch_iterator_train = BatchIterator(batch_size = 500),
batch_iterator_test = BatchIterator(batch_size = 500),
update = updates.adam,
use_label_encoder = True,
regression = False,
max_epochs = 100,
verbose = 1,
)
In [20]:
# train nn
net.fit(X,y);
In [24]:
# Save model
f = open(model_root + 'recognizer.pkl', 'wb')
pkl.dump(net, f)
f.close()
In [43]:
# Load model
f = open(model_root + 'recognizer.pkl', 'rb')
net = pkl.load(f)
f.close()
In [22]:
# Test model
pred = net.predict(test1_x)
In [23]:
print classification_report(test1_y, pred)
print accuracy_score(test1_y, pred)
In [14]:
# Define word recognition functions
import re, collections
def words(text): return re.findall('[a-z]+', text.lower())
def train(features):
model = collections.defaultdict(lambda: 1)
for f in features:
model[f] += 1
return model
NWORDS = train(words(file(data_root + 'big.txt').read()))
alphabet = 'abcdefghijklmnopqrstuvwxyz'
def edits1(word):
splits = [(word[:i], word[i:]) for i in range(len(word) + 1)]
deletes = [a + b[1:] for a, b in splits if b]
transposes = [a + b[1] + b[0] + b[2:] for a, b in splits if len(b)>1]
replaces = [a + c + b[1:] for a, b in splits for c in alphabet if b]
inserts = [a + c + b for a, b in splits for c in alphabet]
return set(deletes + transposes + replaces + inserts)
def known_edits2(word):
return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS)
def known(words): return set(w for w in words if w in NWORDS)
def correct(word):
candidates = known([word]) or known(edits1(word)) or known_edits2(word) or [word]
return sorted(candidates, key=NWORDS.get, reverse = True)
def classer(arrayer):
classer_array = []
for i in range(len(arrayer)):
if (0 <= arrayer[i] < 10):
classer_array.append(arrayer[i])
elif (10 <= arrayer[i] < 36) :
classer_array.append(alphabet[arrayer[i] - 10].upper())
elif (36 <= arrayer[i] < 62):
classer_array.append(alphabet[arrayer[i] - 36])
else :
print 'Is the array correct!?'
return classer_array
In [21]:
# Visualizing test
# Take 10, 20, 30, 40
pylab.figure(1)
pylab.subplot(4, 1, 1)
img = test1_x[90]
img = img.reshape(32, 32)
pylab.imshow(img)
pylab.gray()
pylab.subplot(4, 1, 2)
img = test1_x[80]
img = img.reshape(32, 32)
pylab.imshow(img)
pylab.gray()
pylab.subplot(4, 1, 3)
img = test1_x[110]
img = img.reshape(32, 32)
pylab.imshow(img)
pylab.gray()
pylab.subplot(4, 1, 4)
img = test1_x[120]
img = img.reshape(32, 32)
pylab.imshow(img)
pylab.gray()
pylab.show()
In [35]:
# Redo above steps
tester = np.zeros((4, 1, 32, 32))
tester[0, ...] = test1_x[110]
tester[1, ...] = test1_x[120]
tester[2, ...] = test1_x[90]
tester[3, ...] = test1_x[80]
In [36]:
tester = tester.astype('float32')
In [37]:
preder = netter.predict(tester)
In [38]:
real_pred = classer(preder)
real_pred = map(str, real_pred)
In [39]:
letter_stream = ''.join(real_pred).lower()
In [40]:
print letter_stream
In [41]:
print 'Probable words are: ', ', '.join(correct(letter_stream))
In [ ]: