RNN model (atis data), train_on_batch

refer to: https://github.com/chsasank/ATIS.keras

prepare data


In [1]:
import numpy as np
from Teemo.examples.atis import load_data

In [3]:
train_set, valid_set, dicts = load_data.atis()
w2idx, labels2idx = dicts['words2idx'], dicts['labels2idx']
train_x, _, train_y = train_set
valid_x, _, valid_y = valid_set

idx2w = {w2idx[k]:k for k in w2idx}
idx2labels = {labels2idx[k]:k for k in labels2idx}
print (len(idx2w), len(idx2labels))
print (len(train_x[0]), len(train_y[0]))


(572, 127)
(18, 18)

In [4]:
train_words = [list(map(lambda x: idx2w[x], w)) for w in train_x]
train_labels = [list(map(lambda x: idx2labels[x], w)) for w in train_y]
valid_words = [list(map(lambda x: idx2w[x], w)) for w in valid_x]
valid_labels = [list(map(lambda x: idx2labels[x], w)) for w in valid_y]

build model


In [5]:
voca_size = len(idx2w)
n_classes = len(idx2labels)
word_vec_dim = 100
hidden_dim = 200

In [6]:
from keras.models import Sequential
from keras.layers.embeddings import Embedding
from keras.layers.recurrent import SimpleRNN, LSTM
from keras.layers.core import Dense, Dropout
from keras.layers.wrappers import TimeDistributed
from keras.layers import Convolution1D


Using Theano backend.

In [20]:
def build_model(voca_size, word_vec_dim, hidden_dim, n_classes):
    model = Sequential()
    model.add(Embedding(output_dim=word_vec_dim, input_dim=voca_size))
    model.add(Dropout(0.25))
    model.add(SimpleRNN(output_dim=hidden_dim, return_sequences=True))
    model.add(TimeDistributed(Dense(output_dim=n_classes, activation='softmax')))
    model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
    print ('model input_shape (nb_samples, seq_length): {0}'.format(model.input_shape))
    print ('model output_shape (nb_samples, seq_length, output_dim): {0}'.format(model.output_shape))
    return model

train model


In [21]:
import progressbar
def train_on_batch(model, train_x, train_y, n_classes):
    n_epochs = 10
    for ii in range(n_epochs):
        print ('Training epoch {0}'.format(ii))
        bar = progressbar.ProgressBar(max_value=len(train_x))
        for seq_x, seq_y in bar(zip(train_x, train_y)):
        #for n_batch, sent in bar(enumerate(train_x)):
            seq_x = seq_x[np.newaxis, :]
            seq_y = np.eye(n_classes)[seq_y][np.newaxis, :]
            if seq_x.shape[1] > 1:
                model.train_on_batch(seq_x, seq_y)
                
def evaluate_on_batch(model, valid_x, valid_y):
    pred_values_list = []
    for seq in valid_x:
        seq = seq[np.newaxis, :]
        pred = model.predict_on_batch(seq)[0]
        pred = np.argmax(pred, axis=1)
        pred_values_list.append(pred)
    return pred_values_list

In [22]:
model = build_model(voca_size, word_vec_dim, hidden_dim, n_classes)


model input_shape (nb_samples, seq_length): (None, None)
model output_shape (nb_samples, seq_length, output_dim): (None, None, 127)

In [60]:
train_on_batch(model, train_x, train_y, n_classes)

pred_values_list = evaluate_on_batch(model, valid_x, valid_y)    
pred_labels_list = [list(map(lambda x: idx2label[x], seq)) for seq in pred_values_list]
true_labels_list = valid_labels
from metrics.accuracy import conlleval
con_dict = conlleval(pred_labels_list, true_labels_list, words_valid, 'measure.txt')
print ('Precision={}, Recall = {}, F1 = {}'.format(con_dict['r'], con_dict['p'], con_dict['f1']))


Precision=90.38, Recall = 91.83, F1 = 91.1