-
Notifications
You must be signed in to change notification settings - Fork 21
/
ner_model.py
109 lines (91 loc) · 3.81 KB
/
ner_model.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/python
################################################################################
# TODO:
# - batch normalization
################################################################################
from keras.preprocessing import sequence
from keras.models import load_model
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import GRU
from keras.layers.core import Activation
from keras.regularizers import l2
from keras.layers.wrappers import TimeDistributed
from keras.layers.wrappers import Bidirectional
from keras.layers.normalization import BatchNormalization
from keras.layers.core import Dropout
import numpy as np
import pandas as pd
import sys
import data_util
# For reproducibility
np.random.seed(42)
class NERModel:
""""""
def __init__ (self, reader):
self.reader = reader
self.model = None
self.all_X, self.all_Y = reader.get_data()
self.train_X = None
self.test_X = None
self.train_Y = None
self.test_Y = None
def load (self, filepath):
self.model = load_model(filepath)
def save (self, filepath):
self.model.save(filepath)
def print_summary (self):
print self.model.summary()
def train (self, test_split=0.2, epochs=20, batch=50, dropout=0.2, \
eg_alpha=0.0, units=150, layers=1):
test_split_mask = np.random.rand(len(self.all_X)) < (1-test_split)
self.train_X = self.all_X[test_split_mask]
self.train_Y = self.all_Y[test_split_mask]
self.test_X = self.all_X[~test_split_mask]
self.test_Y = self.all_Y[~test_split_mask]
print self.train_X.shape
print self.train_Y.shape
self.model = Sequential()
reg_alpha = 0.000
dropout = 0.5
self.model.add(Bidirectional(LSTM(units, return_sequences=True, \
W_regularizer=l2(reg_alpha), \
U_regularizer=l2(reg_alpha), \
b_regularizer=l2(reg_alpha)), \
input_shape=(29,300)))
self.model.add(Dropout(dropout))
if layers > 1:
self.model.add(Bidirectional(LSTM(units, return_sequences=True, \
W_regularizer=l2(reg_alpha), \
U_regularizer=l2(reg_alpha), \
b_regularizer=l2(reg_alpha))))
self.model.add(Dropout(dropout))
self.model.add(TimeDistributed(Dense(10, activation='softmax', \
W_regularizer=l2(reg_alpha), \
b_regularizer=l2(reg_alpha))))
self.model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print self.model.summary()
self.model.fit(self.train_X, self.train_Y, nb_epoch=epochs, batch_size=batch)
def predict_sentence (self, sentence, pad=False):
#print "=== Predict ==="
# Look up the embeddings for the words
sentence = sentence[:30]
X = self.reader.encode_sentence(sentence)
#print "X = {0}".format(sentence)
# Predict the labels
pred = self.model.predict(X, batch_size=1)
# Lookup the tags given the class embeddings
tags = self.reader.decode_prediction_sequence(pred[0])
#print tags
if not pad:
tags = tags[-len(sentence):]
#print "Predicted tags:"
tag_str = ""
for t in tags:
tag_str += t + " "
#print tag_str
return tags
def evaluate (self):
scores = self.model.evaluate(self.test_X, self.test_Y, verbose=0)
print "Accuracy: %.2f%%" % (scores[1]*100)