-
Notifications
You must be signed in to change notification settings - Fork 23
/
BiLSTMCRF.py
65 lines (55 loc) · 2.53 KB
/
BiLSTMCRF.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
import tensorflow as tf
import tensorflow_addons as tfa
import numpy as np
import tqdm
from tensorflow.keras.models import Sequential
from tensorflow.keras.callbacks import TensorBoard
from tensorflow.keras.optimizers import Adam
from CRF import CRF
# from CRF import CRF
class MyBiLSTMCRF:
def __init__(self, vocabSize, maxLen, tagIndexDict,tagSum,sequenceLengths=None,vecSize=100,learning_rate=0.01):
self.vocabSize = vocabSize
self.vecSize = vecSize
self.maxLen = maxLen
self.tagSum = tagSum
self.sequenceLengths=sequenceLengths
self.tagIndexDict=tagIndexDict
self.learning_rate=learning_rate
self.buildBiLSTMCRF()
def getTransParam(self,y,tagIndexDict):
self.trainY=np.argmax(y,axis=-1)
yList=self.trainY.tolist()
transParam=np.zeros([len(list(tagIndexDict.keys())),len(list(tagIndexDict.keys()))])
for rowI in range(len(yList)):
for colI in range(len(yList[rowI])-1):
transParam[yList[rowI][colI]][yList[rowI][colI+1]]+=1
for rowI in range(transParam.shape[0]):
transParam[rowI]=transParam[rowI]/np.sum(transParam[rowI])
return transParam
def buildBiLSTMCRF(self):
myModel=Sequential()
myModel.add(tf.keras.layers.Input(shape=(self.maxLen,)))
myModel.add(tf.keras.layers.Embedding(self.vocabSize, self.vecSize))
myModel.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(
self.tagSum, return_sequences=True, activation="tanh"), merge_mode='sum'))
myModel.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(
self.tagSum, return_sequences=True, activation="softmax"), merge_mode='sum'))
crf=CRF(self.tagSum,name='crf_layer')
myModel.add(crf)
myModel.compile(Adam(learning_rate=self.learning_rate),loss={'crf_layer': crf.get_loss})
self.myBiLSTMCRF=myModel
def fit(self,X,y,epochs=100,transParam=None):
if len(y.shape)==3:
y=np.argmax(y,axis=-1)
if self.sequenceLengths is None:
self.sequenceLengths=[row.shape[0] for row in y]
log_dir = "logs"
tensorboard_callback = TensorBoard(log_dir=log_dir, histogram_freq=1)
history=self.myBiLSTMCRF.fit(X,y,epochs=epochs,callbacks=[tensorboard_callback])
return history
def predict(self,X):
preYArr=self.myBiLSTMCRF.predict(X)
return preYArr
if __name__=="__main__":
myModel=MyBiLSTMCRF(vocabSize,maxLen, tagIndexDict,tagSum,sequenceLengths)