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/'


Using gpu device 0: GeForce GT 740M (CNMeM is disabled)

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]:
7705

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


Train_x Shape:  (6164, 1, 32, 32) 
Test_x Shape:  (1541, 1, 32, 32) 
Train_y Shape:  (6164,) 
Test_y Shape:  (1541,)

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);


# Neural Network with 344894 learnable parameters

## Layer information

  #  name      size
---  --------  ---------
  0  input     1x32x32
  1  conv1     32x34x34
  2  pool1     32x17x17
  3  dropout1  32x17x17
  4  conv2     64x20x20
  5  pool2     64x10x10
  6  dropout2  64x10x10
  7  conv3     128x13x13
  8  pool3     128x6x6
  9  dropout3  128x6x6
 10  conv4     128x9x9
 11  pool4     128x4x4
 12  dropout4  128x4x4
 13  conv5     128x7x7
 14  pool5     128x3x3
 15  dropout5  128x3x3
 16  conv6     128x1x1
 17  dropout6  128x1x1
 18  hidden7   128
 19  output    62

  epoch    train loss    valid loss    train/val    valid acc  dur
-------  ------------  ------------  -----------  -----------  ------
      1       4.02624       4.02132      1.00122      0.04360  11.53s
      2       3.89829       3.97860      0.97982      0.08346  11.32s
      3       3.84823       3.93707      0.97743      0.06809  11.33s
      4       3.82541       3.87870      0.98626      0.06809  11.33s
      5       3.81041       3.84152      0.99190      0.06809  11.32s
      6       3.80540       3.83870      0.99133      0.06809  11.37s
      7       3.79339       3.83526      0.98908      0.06809  11.65s
      8       3.79327       3.82469      0.99179      0.06809  11.97s
      9       3.79222       3.81764      0.99334      0.06809  12.08s
     10       3.78912       3.81777      0.99250      0.06809  11.82s
     11       3.77759       3.81724      0.98961      0.06809  12.04s
     12       3.77451       3.79662      0.99418      0.06809  11.32s
     13       3.74840       3.74805      1.00010      0.06809  11.46s
     14       3.71109       3.66191      1.01343      0.10113  12.48s
     15       3.61716       3.53914      1.02205      0.16213  12.02s
     16       3.53066       3.37568      1.04591      0.21226  11.74s
     17       3.38672       3.18114      1.06462      0.22089  12.44s
     18       3.18508       2.96359      1.07474      0.28578  12.00s
     19       3.00498       2.67284      1.12426      0.35821  12.71s
     20       2.81608       2.43632      1.15587      0.38981  13.37s
     21       2.59651       2.22069      1.16923      0.43282  11.44s
     22       2.43278       2.08924      1.16443      0.45797  11.47s
     23       2.30726       1.92502      1.19857      0.48346  11.73s
     24       2.20903       1.81713      1.21567      0.51324  11.72s
     25       2.11549       1.73526      1.21912      0.52054  12.43s
     26       2.02774       1.67465      1.21084      0.54032  11.50s
     27       1.94234       1.58420      1.22607      0.54650  12.17s
     28       1.88615       1.48975      1.26608      0.56218  11.93s
     29       1.82665       1.43767      1.27056      0.60052  11.44s
     30       1.77125       1.35840      1.30393      0.61763  11.54s
     31       1.67994       1.28751      1.30480      0.62370  12.85s
     32       1.67927       1.25422      1.33890      0.62504  12.28s
     33       1.62078       1.22935      1.31841      0.63237  11.49s
     34       1.60071       1.19383      1.34082      0.64878  11.68s
     35       1.53146       1.15313      1.32809      0.66408  11.81s
     36       1.50508       1.12265      1.34064      0.65927  12.23s
     37       1.48510       1.11019      1.33770      0.67586  11.88s
     38       1.44264       1.08368      1.33124      0.69687  11.90s
     39       1.41450       1.03994      1.36017      0.70827  11.58s
     40       1.35286       1.01095      1.33821      0.70031  11.31s
     41       1.36125       1.01016      1.34756      0.71343  11.32s
     42       1.32033       0.98872      1.33539      0.70020  11.31s
     43       1.29481       0.96299      1.34457      0.71161  11.31s
     44       1.30909       0.95871      1.36548      0.72265  11.31s
     45       1.26494       0.91726      1.37904      0.73258  11.31s
     46       1.22215       0.91405      1.33707      0.73921  11.53s
     47       1.21334       0.90072      1.34708      0.73265  11.38s
     48       1.20555       0.89144      1.35236      0.74188  11.32s
     49       1.16426       0.88030      1.32257      0.74966  11.31s
     50       1.15411       0.84935      1.35881      0.75117  11.30s
     51       1.14704       0.84589      1.35602      0.74135  11.31s
     52       1.12870       0.83073      1.35868      0.75636  11.30s
     53       1.10906       0.83256      1.33211      0.75110  11.31s
     54       1.08994       0.80968      1.34614      0.76166  11.32s
     55       1.08696       0.81209      1.33848      0.76288  11.30s
     56       1.05170       0.80665      1.30379      0.75243  11.31s
     57       1.05090       0.79375      1.32397      0.76092  11.31s
     58       1.06047       0.78977      1.34275      0.76899  11.32s
     59       1.02145       0.78175      1.30662      0.77095  11.31s
     60       0.99636       0.77593      1.28410      0.77351  11.31s
     61       0.99730       0.77853      1.28101      0.76703  11.30s
     62       0.99244       0.76809      1.29209      0.76625  11.54s
     63       0.97323       0.76249      1.27638      0.76251  12.88s
     64       0.96389       0.74204      1.29897      0.77432  12.23s
     65       0.94869       0.74602      1.27166      0.77358  11.80s
     66       0.93564       0.74050      1.26352      0.77429  11.31s
     67       0.91292       0.74403      1.22700      0.76703  11.31s
     68       0.91529       0.74304      1.23181      0.77162  11.31s
     69       0.89578       0.73052      1.22622      0.78085  11.31s
     70       0.90753       0.72717      1.24804      0.77818  11.31s
     71       0.90113       0.72776      1.23823      0.77618  11.31s
     72       0.89133       0.72446      1.23034      0.78144  11.31s
     73       0.89693       0.72779      1.23239      0.77422  11.31s
     74       0.88302       0.71935      1.22753      0.78022  11.55s
     75       0.86461       0.71777      1.20457      0.77029  11.31s
     76       0.86367       0.70063      1.23270      0.78081  11.30s
     77       0.87568       0.69721      1.25598      0.78133  11.30s
     78       0.87359       0.69546      1.25612      0.78800  11.31s
     79       0.82712       0.69490      1.19026      0.78266  11.31s
     80       0.82296       0.69518      1.18382      0.78544  11.32s
     81       0.81760       0.68799      1.18839      0.78866  11.31s
     82       0.83878       0.68024      1.23306      0.78996  11.92s
     83       0.80470       0.68127      1.18118      0.78095  11.31s
     84       0.79624       0.68083      1.16951      0.78544  11.31s
     85       0.82153       0.66388      1.23746      0.79140  11.30s
     86       0.80266       0.68272      1.17568      0.79263  11.30s
     87       0.77410       0.66573      1.16279      0.78874  11.30s
     88       0.78323       0.66653      1.17509      0.79081  11.31s
     89       0.80028       0.66138      1.21001      0.79659  11.31s
     90       0.77613       0.66765      1.16249      0.78151  11.31s
     91       0.77500       0.65158      1.18942      0.79211  11.31s
     92       0.75549       0.67100      1.12592      0.79800  11.30s
     93       0.76579       0.66391      1.15345      0.79596  11.31s
     94       0.75369       0.67096      1.12330      0.79600  11.31s
     95       0.77658       0.65583      1.18412      0.79670  11.56s
     96       0.73422       0.65714      1.11729      0.78429  11.31s
     97       0.73820       0.65926      1.11975      0.79537  11.30s
     98       0.71701       0.65516      1.09440      0.79600  11.31s
     99       0.71851       0.65856      1.09104      0.79414  11.31s
    100       0.72712       0.65033      1.11808      0.79940  11.31s

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)


             precision    recall  f1-score   support

          0       0.00      0.00      0.00        20
          1       0.86      0.71      0.77        17
          2       0.80      1.00      0.89        12
          3       0.67      0.77      0.71        13
          4       0.57      0.67      0.62         6
          5       0.85      0.85      0.85        13
          6       0.92      0.86      0.89        14
          7       0.80      0.89      0.84         9
          8       1.00      0.67      0.80         9
          9       0.83      0.83      0.83         6
         10       0.96      0.96      0.96       125
         11       0.83      0.92      0.87        26
         12       0.67      0.88      0.76        34
         13       0.84      0.87      0.86        31
         14       0.92      0.94      0.93        97
         15       0.79      0.73      0.76        15
         16       0.87      0.84      0.85        31
         17       0.91      0.89      0.90        47
         18       0.70      0.92      0.80        72
         19       0.63      0.75      0.69        16
         20       0.76      0.81      0.79        16
         21       0.85      0.92      0.89        38
         22       0.89      0.92      0.90        36
         23       0.92      0.99      0.95        69
         24       0.59      0.96      0.73        80
         25       0.85      0.88      0.87        26
         26       1.00      0.33      0.50         3
         27       0.96      0.96      0.96        74
         28       0.70      0.94      0.81        68
         29       0.93      0.95      0.94        56
         30       0.67      0.89      0.76        18
         31       0.79      0.68      0.73        22
         32       0.83      0.88      0.86        17
         33       0.79      1.00      0.88        11
         34       0.81      1.00      0.90        13
         35       0.47      0.58      0.52        12
         36       0.88      0.79      0.83        38
         37       0.86      0.67      0.75         9
         38       0.00      0.00      0.00        10
         39       0.82      0.90      0.86        10
         40       0.85      0.97      0.91        30
         41       1.00      0.50      0.67         6
         42       0.67      0.57      0.62         7
         43       0.90      0.50      0.64        18
         44       0.87      0.83      0.85        24
         45       0.00      0.00      0.00         4
         46       0.71      0.56      0.63         9
         47       0.00      0.00      0.00        13
         48       0.70      0.78      0.74         9
         49       0.78      0.91      0.84        23
         50       0.00      0.00      0.00        29
         51       0.00      0.00      0.00         7
         52       1.00      0.50      0.67        12
         53       0.82      0.96      0.88        24
         54       0.00      0.00      0.00        18
         55       0.88      0.85      0.87        27
         56       1.00      0.75      0.86         8
         57       1.00      0.20      0.33         5
         58       0.00      0.00      0.00         3
         59       0.00      0.00      0.00         4
         60       1.00      0.62      0.76        13
         61       0.50      0.22      0.31         9

avg / total       0.78      0.82      0.79      1541

0.815055158988

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


spin

In [41]:
print 'Probable words are: ', ', '.join(correct(letter_stream))


Probable words are:  spin

In [ ]: