mirror of
https://github.com/wassname/phoneme2grapheme.git
synced 2026-09-10 12:30:12 +08:00
394 KiB
394 KiB
In [1]:
import os
# os.environ['THEANO_FLAGS']='mode=FAST_RUN,device=gpu,floatX=float32'
os.environ['KERAS_BACKEND']='tensorflow'
os.sys.path.append('..')In [2]:
# keras
import keras
# from keras.engine.training import slice_X
from keras.layers import Activation, TimeDistributed, Dense, RepeatVector, recurrent
from keras.layers import InputLayer, Embedding, Lambda, Reshape, InputLayer, Dropout
from keras.models import Sequential
from keras.preprocessing import sequence
from keras.wrappers.scikit_learn import KerasClassifier
from keras.layers.wrappers import Bidirectional, TimeDistributed
# from keras.engine.training import slice_X
from keras.layers import Activation, TimeDistributed, Dense, RepeatVector, recurrent
from keras.layers import InputLayer, Embedding
from keras.models import Sequential
# helper
from keras_tqdm import TQDMNotebookCallback
Using TensorFlow backend.
In [3]:
# sklearn
import sklearn
# from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import train_test_splitIn [18]:
# pylab imports
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
import scipy as sp
import seaborn as sns
%matplotlib inline
# io & utils
from path import Path
from pprint import pprint
import json
import arrow
from tqdm import tqdm_notebook as tqdm
import re
import string
import itertools
import collectionsIn [29]:
seed=1337 # for reproducibility
batch_size=64*3In [30]:
import sklearn
import numpy as np
import scipy as sp
import pandas as pd
from matplotlib import pyplot as plt
%matplotlib inline
from tqdm import tqdm_notebook as tqdmIn [31]:
import os
os.sys.path.append('.')In [32]:
%reload_ext autoreload
%autoreload 2
from helpers import dataset_isledict, show_resultsIn [33]:
import numpy as np
def CER(y_pred,y_test):
"""
A keras metric for Charecter error rate
inputs:
y_pred - an array with shape samples*index*classes
y_test - as above
"""
return 1-(y_pred.argmax(-1)==y_test.argmax(-1)).sum()/(y_test.shape[0]*y_test.shape[1])
# print ('Char error rate {:%}'.format(CER(y_pred,y_test)))
from keras.utils.np_utils import to_categorical
# good
assert CER(
np.array([to_categorical([0,2,1,4,0],5)]),
np.array([to_categorical([0,2,1,4,0],5)])
) ==0
# bad
assert CER(
np.array([to_categorical([0,2,1,4],5)]),
np.array([to_categorical([0,2,0,2],5)])
)==0.5
In [119]:
def WER(y_true,y_pred):
# calc word error rate (compare 23.3-33.89 for grap2phon https://github.com/cmusphinx/g2p-seq2seq)
# like https://github.com/cmusphinx/g2p-seq2seq/blob/master/g2p_seq2seq/g2p.py#L317
c=(y_pred.argmax(-1)==y_true.argmax(-1)).all(-1).sum()
return (1-c/len(y_true))
from leven import levenshtein
def element_error_rate(y_true, y_pred, ytable=ytable):
"""Returns the word error rate of the supplied hypothesis with respect to
the reference string."""
c_test = [''.join(x).strip() for x in ytable.decode(y_true)]
c_pred = [''.join(x).strip() for x in ytable.decode(y_pred)]
distance = np.array([levenshtein(pred,test) for pred,test in zip(c_pred,c_test)])
elems = np.array([len(x) for x in c_test])
error_rate = distance / len(elems)
return error_rate.sum()
# unit test
a=[[1,2,3],[1,2,3]]
b=[[1,2,3],[2,0,3]]
a=np.array([keras.utils.np_utils.to_categorical(x,4) for x in a])
b=np.array([keras.utils.np_utils.to_categorical(x,4) for x in b])
assert WER(a,b)==0.5
assert element_error_rate(a,b)==1In [64]:
# grab a small subset of the data
(y_train, X_train),(y_test,X_test),(ytable,xtable) = dataset_isledict.get_data(
verbose=1,
max_phonemes=10,
max_chars=10,
# invert=False,
# x_hot=True,
unique_graphemes=True,
unique_phonemes=True
)
X_train = X_train[:,::-1,:]
X_test = X_test[:,::-1,:]
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.1, random_state=seed)
nb_chars = len(ytable.chars)
nb_phons = len(xtable.chars)
maxlen_x = xtable.maxlen
maxlen_y = ytable.maxlenloaded entries 282842 removed duplicate phonemes leaving 260707 removed duplicate graphemes leaving 236077 removed blacklisted entries leaving 158184 restricted to less than 10 phonemes leaving 113368 entries or 71.81% X_train shape: (90879, 10, 29) X_test shape: (22489, 10, 29) y_train shape: (90879, 10, 43) y_test shape: (22489, 10, 43)
In [65]:
# crop to batch size to prevent errors
train_crop = len(X_train)-(len(X_train)%batch_size)
test_crop = len(X_test)-(len(X_test)%batch_size)
val_crop = len(X_val)-(len(X_val)%batch_size)
print(train_crop,test_crop,val_crop)
X_train=X_train[:train_crop]
y_train=y_train[:train_crop]
X_test=X_test[:test_crop]
y_test=y_test[:test_crop]
X_val=X_val[:val_crop]
y_val=y_val[:val_crop]81600 22464 9024
In [66]:
# lets just do a sanity test
assert (X_train.sum(-1)==1).all(),'all classes must sum to one'
assert (y_train.sum(-1)==1).all(),'all classes must sum to one'
assert (X_train.max(-1)==1).all(),'should have max value of 1'
assert (X_train.min(-1)==0).all(), 'should have min of 0'In [67]:
# view data
a=[''.join(x[::-1]) for x in xtable.decode(X_train[:5])]
b=[''.join(y) for y in ytable.decode(y_train[:5])]
list(zip(a,b))Out [67]:
[('mˈeiŋgl̩ ', 'mangel '),
('fɹˈut˺ɪŋ ', 'fruiting '),
('tˈʌkəhˌoʊ ', 'tuckahoe '),
('kloʊ ', 'clos '),
('fɪlˈɪpiæk ', 'filipiak ')]In [60]:
from keras.utils.np_utils import to_categorical
def to_categorical_3d(data2,n=None):
data=data2.astype(np.int)
return np.array([to_categorical(data[i],n) for i in range(len(data))])In [61]:
from sklearn.dummy import DummyClassifier
for strategy in ['stratified', 'most_frequent', 'prior', 'uniform']:
clf = DummyClassifier(strategy=strategy,random_state=0)
clf.fit(X_train.reshape((-1,nb_phons)), y_train.reshape((-1,nb_chars)).argmax(-1))
# on a simple classifier CER=1-score
score = clf.score(X_test.reshape((-1,nb_phons)), y_test.reshape((-1,nb_chars)).argmax(-1))
print('{strategy:20.20s}: CER={CER:2.2%}'.format(strategy=strategy, CER=1-score))stratified : CER=87.76% most_frequent : CER=69.53% prior : CER=69.53% uniform : CER=96.44%
In [62]:
from sklearn.dummy import DummyRegressor
for strategy in ['mean', 'median', 'quantile', 'constant']:
clf = DummyRegressor(strategy=strategy, constant=np.zeros((10,1)), quantile=0.555)
clf.fit(X_train.argmax(-1), y_train.argmax(-1))
score = clf.score(X_test.argmax(-1), y_test.argmax(-1))
y_pred_2d = clf.predict(X_test.argmax(-1))
y_pred_3d=to_categorical_3d(y_pred_2d)
cer = CER(y_pred_3d, y_test)
print('{strategy:20.20s}: CER={CER:2.2%}'.format(strategy=strategy, CER=cer))mean : CER=88.13% median : CER=71.09% quantile : CER=71.82% constant : CER=69.53%
In [95]:
# PredictionLogger
import keras
from keras.callbacks import Callback
class PredictionLogger(keras.callbacks.Callback):
def __init__(self, n=1, batch_size=batch_size):
self.n = n
self.batch_size = batch_size
def on_epoch_end(self, batch, logs={}):
y_pred = self.model.predict(self.model.validation_data[0][:self.batch_size], batch_size=batch_size)
p_pred = ytable.decode(y_pred)
p_test = ytable.decode(self.model.validation_data[1][:self.batch_size])
text_pred=[''.join(ls) for ls in p_pred[:self.n]]
text_true=[''.join(ls) for ls in p_test[:self.n]]
print('')
pprint(list(zip(text_true,text_pred)))
prediction_logger = PredictionLogger(n=3)In [28]:
from keras.layers import Embedding, Convolution1D, GlobalMaxPooling1D, Reshape, Flatten, Dropout
import keras
model = Sequential()
# we start off with an efficient embedding layer which maps
# our vocab indices into embedding_dims dimensions
model.add(Embedding(nb_phons,
90,
input_length=maxlen_x,
dropout=0.2))
# we add a Convolution1D, which will learn nb_filter
# word group filters of size filter_length:
model.add(Convolution1D(nb_filter=256,
filter_length=3,
border_mode='valid',
activation='relu',
subsample_length=1))
model.add(Dropout(0.2))
# we add a Convolution1D, which will learn nb_filter
# word group filters of size filter_length:
model.add(Convolution1D(nb_filter=256,
filter_length=3,
border_mode='valid',
activation='relu',
subsample_length=1))
# classifier
model.add(Flatten())
model.add(Dense(maxlen_y*nb_chars))
model.add(Reshape((maxlen_y,nb_chars)))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='nadam', #keras.optimizers.Nadam(lr=0.2),
metrics=['accuracy'])
# model.summary()
history = model.fit(
X_train.argmax(-1),
y_train,
batch_size=batch_size,
nb_epoch=20,
verbose=0,
validation_data=[X_test.argmax(-1),y_test],
callbacks=[
keras.callbacks.EarlyStopping(patience=2),
PredictionLogger(n=3),
TQDMNotebookCallback()
]
)[0;31m---------------------------------------------------------------------------[0m [0;31mNameError[0m Traceback (most recent call last) [0;32m<ipython-input-28-0dea8e399d33>[0m in [0;36m<module>[0;34m()[0m [1;32m 41[0m [0mX_train[0m[0;34m.[0m[0margmax[0m[0;34m([0m[0;34m-[0m[0;36m1[0m[0;34m)[0m[0;34m,[0m[0;34m[0m[0m [1;32m 42[0m [0my_train[0m[0;34m,[0m[0;34m[0m[0m [0;32m---> 43[0;31m [0mbatch_size[0m[0;34m=[0m[0mbatch_size[0m[0;34m,[0m[0;34m[0m[0m [0m[1;32m 44[0m [0mnb_epoch[0m[0;34m=[0m[0;36m20[0m[0;34m,[0m[0;34m[0m[0m [1;32m 45[0m [0mverbose[0m[0;34m=[0m[0;36m0[0m[0;34m,[0m[0;34m[0m[0m [0;31mNameError[0m: name 'batch_size' is not defined
In [73]:
pd.DataFrame(history.history).plot()
scores = model.evaluate(X_test.argmax(-1),y_test, verbose=0)
score = dict(zip(model.metrics_names,scores))
y_pred = model.predict(X_test.argmax(-1), verbose=0, batch_size=batch_size)
print ('Accuracy {:%}'.format(score['acc']))
print ('Word error rate {:%}'.format(WER(y_pred,y_test)))
print ('Char error rate {:%}'.format(CER(y_pred,y_test)))
n=100
show_results(ytable=ytable, y_pred=y_pred[:n],y_test=y_test[:n],xtable=xtable,X_test=X_test[:n])Out [73]:
Accuracy 77.108367% Word error rate 80.812842% Char error rate 22.891636%
| pronunciation | guess | spelling |
|---|---|---|
| kˈɑkəsˌɔid | cocksoid | caucasoid |
| bɹˈæsfˌild | brassfildd | brassfield |
| flˈæʃbl̩b | flashblb | flashbulb |
| hˈɛstiə | hestia | hestia |
| kɹˈæbi | crabyy | crabby |
| tɹədˈus | troduse | traduce |
| təlˈulə | talulaa | tallulah |
| bˈitn̩ | beatn | beaton |
| hˈɑlɪtʃɛk | halicck | holecek |
| beidˈɔiə | bedooy | bedoya |
In [43]:
from helpers.layers import Attention, SimplifiedAttentionIn [44]:
# set model parameters
nb_chars = len(ytable.chars)
nb_phons = len(xtable.chars)
maxlen_x = xtable.maxlen
maxlen_y = ytable.maxlen
# batch_size = 300
hidden_nodes = 64
RNN=keras.layers.recurrent.GRUIn [45]:
import tensorflow
import keras
# you probobly need these exact versions
assert keras.__version__=='1.2.2'
assert tensorflow.__version__=='1.0.0'In [ ]:
In [80]:
# rnn's in tensorflow sometimes need exact batches
assert X_val.shape[0]%batch_size==0
assert X_train.shape[0]%batch_size==0
batch_sizeOut [80]:
192
In [ ]:
# # here's a pretrained model with 81% accuracy
# model = keras.models.load_model(
# './models/phone_to_respelling_201705-31233850_acc-0.81.hdf',
# custom_objects=dict(Attention=Attention)
# )In [92]:
model = Sequential()
# Encode, bidirectional keeps the accuracy up at the end of the word
model.add(Bidirectional(RNN(hidden_nodes, return_sequences=True), batch_input_shape=(batch_size, maxlen_x, nb_phons)))
# model.add(RNN(hidden_nodes, return_sequences=True, batch_input_shape=(batch_size, maxlen_x, nb_phons)))
model.add(Dropout(0.2))
# Decode with attention
model.add(Attention(RNN(hidden_nodes, return_sequences=True, consume_less='mem')))
model.add(Dropout(0.2))
# # I could add some more RNN models
# model.add(RNN(hidden_nodes, return_sequences=True, consume_less='mem'))
# classifier
model.add(TimeDistributed(Dense(nb_chars)))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='nadam',
metrics=['accuracy'])
model.summary()
____________________________________________________________________________________________________ Layer (type) Output Shape Param # Connected to ==================================================================================================== bidirectional_13 (Bidirectional) (192, 10, 128) 41472 bidirectional_input_13[0][0] ____________________________________________________________________________________________________ dropout_26 (Dropout) (192, 10, 128) 0 bidirectional_13[0][0] ____________________________________________________________________________________________________ attention_13 (Attention) (192, 10, 64) 57728 dropout_26[0][0] ____________________________________________________________________________________________________ dropout_27 (Dropout) (192, 10, 64) 0 attention_13[0][0] ____________________________________________________________________________________________________ timedistributed_13 (TimeDistribu (192, 10, 29) 1885 dropout_27[0][0] ____________________________________________________________________________________________________ activation_14 (Activation) (192, 10, 29) 0 timedistributed_13[0][0] ==================================================================================================== Total params: 101,085 Trainable params: 101,085 Non-trainable params: 0 ____________________________________________________________________________________________________
In [97]:
history = model.fit(X_train, y_train,
batch_size=batch_size,
nb_epoch=60,
verbose=0,
validation_data=[X_val,y_val],
callbacks=[
keras.callbacks.EarlyStopping(monitor='val_acc', patience=2),
PredictionLogger(n=4),
TQDMNotebookCallback(),
]
)[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'anposted '),
('knoblock ', 'nablak '),
('garland ', 'garlend '),
('asgard ', 'asgard ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'anpostid '),
('knoblock ', 'nablack '),
('garland ', 'garllndd '),
('asgard ', 'osggrdd ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unpostid '),
('knoblock ', 'noblack '),
('garland ', 'garland '),
('asgard ', 'osgard ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unposted '),
('knoblock ', 'noblack '),
('garland ', 'garllnd '),
('asgard ', 'osgardd ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unposstdd '),
('knoblock ', 'noblack '),
('garland ', 'garland '),
('asgard ', 'osgard ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unpostidd '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgard ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unposted '),
('knoblock ', 'noblack '),
('garland ', 'garland '),
('asgard ', 'osgard ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unpostedd '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgardd ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unposttdd '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgard ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unpostid '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgard ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unpostedd '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgard ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unpostedd '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgard ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unposted '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgard ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unposted '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgardd ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unposted '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgarrd ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unpostedd '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgard ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unpostedd '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgard ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unposted '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgard ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unpostedd '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgard ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unpostedd '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgardd ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unposted '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgarrd ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unposted '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgardd ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unpostedd '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgardd ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unposted '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgardd ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unposted '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgardd ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unposted '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgardd ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unpostedd '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgarrd ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unpostedd '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgard ')]
[Data output - unsupported data type map[string]interface {} for mime type application/vnd.jupyter.widget-view+json]
[('unposted ', 'unposted '),
('knoblock ', 'noblock '),
('garland ', 'garland '),
('asgard ', 'osgarrd ')]
In [101]:
pd.DataFrame(history.history).plot()Out [101]:
<matplotlib.axes._subplots.AxesSubplot at 0x7fe7540b60f0>
In [102]:
scores = model.evaluate(X_test,y_test, verbose=1, batch_size=batch_size)
score = dict(zip(model.metrics_names,scores))
print()
print ('Accuracy {:%}'.format(score['acc']))22464/22464 [==============================] - 7s Accuracy 80.727387%
In [106]:
ts = arrow.utcnow().format('YYYYMM-DDHHmmss')
model_file = './models/phone_to_respelling_{ts:}_acc-{acc:2.2f}.hdf'.format(ts=ts,acc=score['acc'])
model.save(model_file)
model.save_weights(model_file.replace('.hdf','_weights.hdf'))
model_fileOut [106]:
'./models/phone_to_respelling_201705-31233850_acc-0.81.hdf'
In [120]:
n=batch_size
y_pred = model.predict(X_test, verbose=1, batch_size=batch_size)
print()
wer = WER(y_test, y_pred)
print('word error rate {:2.2%}'.format(wer))
eer = element_error_rate(y_test, y_pred)
print('element (char or phon) error rate {:2.2%}'.format(eer))
print ('Char error rate {:2.2%}'.format(CER(y_pred,y_test)))
show_results(ytable=ytable, y_pred=y_pred[:n],y_test=y_test[:n],xtable=xtable,X_test=X_test[:n])Out [120]:
22464/22464 [==============================] - 7s word error rate 73.09% element (char or phon) error rate 139.86% Char error rate 19.27%
| pronunciation | guess | spelling |
|---|---|---|
| kˈɑkəsˌɔid | cockosoid | caucasoid |
| bɹˈæsfˌild | brasfieldd | brassfield |
| flˈæʃbl̩b | flashbllb | flashbulb |
| hˈɛstiə | hestia | hestia |
| kɹˈæbi | crabby | crabby |
| tɹədˈus | traduse | traduce |
| təlˈulə | talula | tallulah |
| bˈitn̩ | beetnn | beaton |
| hˈɑlɪtʃɛk | holicckk | holecek |
| beidˈɔiə | bedoia | bedoya |
| sɪvˈiɹ | siverr | severe |
| nɑɪsˈɪpi | nicipp | nicippe |
| lˈoʊɹntʃəɹ | lornnchrr | launcher |
| bɹɪtˈɔil | bretoil | britoil |
| ˈɔɹtnɚ | ortner | ortner |
| bˈɪljn̩ɵs | billiants | billionths |
| sˈɛmijˌɑn | semiyon | semillon |
| lˈɔntʃɪŋ | launching | launching |
| zˌubɪlˈɑgə | zubilagaa | zubillaga |
| ɹɪfɹˈɛʃɪz | refreshes | refreshes |
| ˈɪgnəɹn̩s | ignerancee | ignorance |
| tɪsˈɪpəs | tesippus | ctesippus |
| vɪtkˈɔfski | vitkowski | witkowski |
| dˈɑdɹɪdʒ | dodrrdge | doddridge |
| tˈɛnn̩t | tennnnt | tennent |
| dˈɪŋk | dink | dink |
| ˈeiljənəɹ | alliner | alienor |
| dˈuln̩ | dullnn | doolan |
| hˈʌlki | hulkee | hulky |
| mˈɛmwˌɑɹz | memwars | memoirs |
| kɑɹdɑɹˈɛli | cardarelll | cardarelli |
| fˈɝmɚ | furmer | firmer |
| kwˈɑpjɑ | quapya | kuopio |
| kɚˈɛktɪd | careected | corrected |
| ɹˈɔɵmn̩ | rothman | rothman |
| stɹʊk | strook | strook |
| ɹˈɛnkwɪst | renquist | renquist |
| ɛspɪnˈoʊzə | espinosa | espinosa |
| bˈɪgɪnz | biggins | biggins |
| pəɹfˈɛkʃn̩ | perfection | perfection |
| ˈændəɹsn̩ | anderson | andersen |
| ˈænɪnæt | aninatt | aninat |
| ˈɔlɹɪd | alredd | alred |
| ɑɹkˈoʊlə | arcola | arcola |
| pɹˈimiəm | premium | premium |
| bˈɑlmʊŋ | bolmung | balmung |
| ɹˌɑbˈʌstəs | robustoss | robustas |
| dɪsˈɔɹdɚz | disorddrrs | disorders |
| ˈæsɪtˌæl | asitall | acetal |
| bjˈuz | buse | buse |
| wˈeif | waff | waif |
| ˈæɹənˌoʊs | aronose | arenose |
| kwˈeiswˈei | quaseeay | kweisui |
| ɪmbˈɑdiɪŋ | imbodiingg | embodying |
| mˈʌlkɚn | mulkern | mulkern |
| kˈɪmɪtʃ | kimiich | kimmich |
| tˈupəlˌoʊ | tupelow | tupelo |
| tɹɑɪˈʌmf | triumf | triumph |
| pɹˈaʊd˺ɚ | prowder | prouder |
| wˈɛdʒ | wedge | wedge |
| ɹˈɛznɪk | resnikk | reznik |
| flˈeid | flayed | flayed |
| ˈæsɪlɪn | asilinn | asselin |
| dɪkɹˈitl̩ | dicrettl | decretal |
| sɪndˈɛt˺ɪk | sindetic | syndetic |
| spˈænɪʃ | spannsh | spanish |
| ɹˈæli | rally | rallye |
| aʊtʃˈoʊn | ouchone | outshone |
| sˈɑsəɹˌɑɪt | sosserite | saussurite |
| ɪspˈaʊzd | ispousd | espoused |
| bɹˈɪklɪn | bricklin | bricklin |
| ɛskˈɑləp | escolop | escallop |
| hˈɔɹdz | hordss | hordes |
| kˈæɹəkɚ | carrcker | caraker |
| wˈɑɪthˌɝst | wiithhorst | whitehurst |
| mˈɛɹɪmæk | merimac | merrimac |
| tʃɑɪnˈi | chinee | chinee |
| hˈænlɪn | hanlin | hanlin |
| dɑɪˈækənl̩ | diacinal | diaconal |
| kwˈɪnin | quinnnn | quinine |
| bɹʊjˈɛɹ | bruyerr | bruyeres |
| pitsˈutoʊ | pitsuto | pizzuto |
| liˈændəɹ | liander | leander |
| əblˈɑɪdʒɪŋ | obligingg | obliging |
| mˈɔɹfju | morfuu | morphew |
| glˈækn̩z | glacknns | glackens |
| bukˈeiz | buccass | bouquets |
| hˈɝɹmɪt | hermit | hermit |
| mˈʌsl̩ | mussle | mussell |
| mˈʌt˺əɹ | mutter | mutter |
| pəhˈoʊki | pahoki | pahokee |
| gɑlˈɑsoʊ | galasso | galasso |
| ˈoʊvɚlˌɑk | overlock | overlock |
| tˈɪŋktʃəɹ | tincturr | tincture |
| pjˈudʒɪn | pugin | pugin |
| spˌɛʃəlˌi | speshale | especially |
| hˈʊfpɹˌɪnt | hoofprint | hoofprint |
| pˈɑntɪk | pontic | pontic |
| pɹˈɑɪsɪz | prices | prices |
| nˈeivi | navi | navy |
| gɹˈɪmʃˌɔ | grimshau | grimshaw |
| pɹəvˈɑɪzoʊ | pravizo | proviso |
| sˈoʊlɪtɹɑn | soletron | solitron |
| ˈænəɵˌoʊl | anathol | anethole |
| pɑmpˈɛɹoʊ | pampero | pampero |
| ˈɑɪməs | immu | imus |
| hˈoʊfəɹ | hoffer | hofer |
| smˈɑɹts | smarts | smarts |
| mɔɹtˈimɔɹ | mortemorr | mortimore |
| blˈɛkmn̩ | bleckman | blechman |
| ʃˈæfɹn̩ | shaffron | shafran |
| tn̩dɹˈoʊ | tondrow | tondreau |
| ˈɝdʒn̩tli | urgentlyy | urgently |
| ˌɑksˈænə | oxanaa | oksana |
| flˈɪntʃiɹ | flinchir | flintshire |
| ʃɹˈɛŋk | shhrenk | schrenk |
| plˈæzə | plaza | plaza |
| dˈunədɪn | dunadin | dunedin |
| dɪsmˈɪʃn̩ | dismition | dismission |
| skwˈɪfi | squiffy | squiffy |
| skˈɑɪwˌei | skiway | skyway |
| fˈæʃɪst | fashist | fascist |
| pˈɑləpˌɛɹi | poloparyy | polypary |
| ɑɪˈælmənəs | ialmonoss | ialmenus |
| ˈɑzmn̩dsn̩ | osmandson | osmundson |
| ˈɑɪlˌæʃɪz | illases | eyelashes |
| gˈæsp | gasp | gasp |
| ɪnwˈɑɪnd | inwindd | inwind |
| kˈoʊldli | coldlyy | coldly |
| bˈækʃi | bacchyy | bakshi |
| æbˈɛsɪv | abessiv | abessive |
| tʃɪkˈɔin | chicoin | chicoine |
| skˌɪmz | skims | skims |
| kɹɪsp | crisp | crisp |
| hˈɑɪdɹˌɑɪd | hiddrdd | hydride |
| bɹˈæmlɪt | bramlet | bramlett |
| jˈɛsəf | yessff | iosif |
| gˈɑɹdhˌaʊs | gardhouss | guardhouse |
| sˈɪliəs | silius | syleus |
| zˈɪŋə | zinga | zinga |
| tˈɪŋkɚd | tinkerdd | tinkered |
| tˈægəɹ | tagger | tagger |
| ˈʌltəmˌoʊ | ultimo | ultimo |
| ʃˈɛɹɪl | sherill | sherrill |
| poʊstwˈoʊɹ | postworr | postwar |
| lˈɔɹiəts | loriets | laureates |
| dʒˈɑskɪn | joskin | joskin |
| kˈinɪŋ | keening | keening |
| slˈoʊli | slolly | slowly |
| spoʊsˈɑtoʊ | sposatoo | sposato |
| wˌɑt˺əɹˈi | wattere | wateree |
| æmfˈɪbiə | amphibia | amphibia |
| dʒˌæpənˈiz | jappnnes | japanese |
| əntɹˈu | untruu | untrue |
| pˈɛɹəbl̩ | perrbbe | parable |
| kʊɹzˈɑwə | curzawa | kurzawa |
| sˈʌmwˌɛɹ | summaar | somewhere |
| zˈɪlviə | zilvia | zilvia |
| oʊsˈɔɹioʊ | osorio | osorio |
| swˈɪtʃɚ | switcher | switcher |
| ɚˈɛndsˌi | areedse | arendsee |
| kɑɹvɑjˈæl | carvaial | carvajal |
| blˈæknɪs | blackniss | blackness |
| pɚˈɪsiˌɛn | perisien | parisienne |
| kˈænjn̩z | caniins | canyons |
| pɔɹtˈɛndz | portends | portends |
| lˈuɪn | luin | lewin |
| slˈɪmɪŋ | slimming | slimming |
| mʊɹˈɑt | murrtt | murat |
| tˈɑɪmn̩ | timen | timon |
| hˈimɪn | heemi | hemin |
| tˈɝɹnkˌi | ternkee | turnkey |
| ɹɪdˈiməbl̩ | redemmbbl | redeemable |
| lˈɑkəs | lockos | lochus |
| skˈɛɹiɚ | scarierr | scarier |
| ˌænəkjˈuʒə | anacujia | anacusia |
| stɹˈut | stroot | stroot |
| tɑɪmˈiəs | timeus | timaeus |
| səbmˈɝs | submerse | submerse |
| stˈɑlwəɹɵ | stolwwrth | stalworth |
| ˈiniəs | enius | oeneus |
| ləzˈɪɹ | lazirr | lazear |
| bˈɑoʊ | bao | booe |
| ɪkspˈændɪd | expanded | expanded |
| zəɹkˈɑnɪk | zerconic | zirconic |
| ˈɑbleit | oblatee | oblate |
| gˈɪbi | gibby | gibby |
| sˈʌmnɚz | sumnners | sumners |
| tˈeiln̩ | tallnn | taillon |
| tɹˈɪbjut | tributt | tribute |
| pˈʌzl̩mn̩t | pussleman | puzzlement |
| lˈændfˌɪlz | landfilss | landfills |
In [118]:
# accuracy for each char
report = sklearn.metrics.classification_report(y_test.argmax(-1).flatten(), y_pred.argmax(-1).flatten(), target_names=ytable.chars)
print(report) precision recall f1-score support
0.92 0.96 0.94 68413
& 0.00 0.00 0.00 1
' 0.00 0.00 0.00 45
a 0.76 0.71 0.73 14238
b 0.90 0.92 0.91 3650
c 0.71 0.73 0.72 5831
d 0.79 0.83 0.81 5649
e 0.68 0.55 0.61 17448
f 0.78 0.91 0.84 2245
g 0.81 0.82 0.81 4302
h 0.77 0.64 0.70 4917
i 0.65 0.68 0.66 11264
j 0.75 0.52 0.62 451
k 0.64 0.58 0.61 2990
l 0.79 0.86 0.82 9249
m 0.86 0.90 0.88 4767
n 0.78 0.83 0.81 10752
o 0.70 0.69 0.69 9967
p 0.90 0.86 0.88 3807
q 0.83 0.60 0.69 280
r 0.81 0.86 0.83 11752
s 0.76 0.82 0.79 10556
t 0.80 0.84 0.82 8607
u 0.70 0.62 0.66 5691
v 0.87 0.92 0.89 1642
w 0.81 0.66 0.72 1839
x 0.73 0.70 0.71 372
y 0.53 0.43 0.48 2861
z 0.72 0.52 0.61 1054
avg / total 0.80 0.81 0.80 224640
/home/isisilon/.pyenv/versions/3.6.0/envs/jupyter3/lib/python3.6/site-packages/sklearn/metrics/classification.py:1113: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples. 'precision', 'predicted', average, warn_for)
In [146]:
# show confidence
plt.figure(figsize=(16,16))
plt.title('Letter confidence vs word index')
conf = y_pred.mean(0)
plt.imshow(conf,interpolation='none',vmin=0,vmax=0.15)
plt.xlabel('letter')
plt.ylabel('index')
plt.colorbar()Out [146]:
<matplotlib.colorbar.Colorbar at 0x7fe74529ab70>