Repository navigation
Expand file tree
/
Copy pathmodel.py
More file actions
118 lines (89 loc) · 4.36 KB
/
Copy pathmodel.py
File metadata and controls
118 lines (89 loc) · 4.36 KB
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
110
111
112
113
114
115
116
117
118
from keras.engine.topology import Layer
from keras.models import Model
from keras import regularizers, initializers, constraints
from keras.models import Sequential
from keras.layers import Embedding, Dense, GRU, TimeDistributed, Flatten, Activation, Bidirectional, Dropout
import keras.backend as K
def dot_product(x, kernel):
if K.backend() == 'tensorflow':
return K.squeeze(K.dot(x, K.expand_dims(kernel)), axis=-1)
else:
return K.dot(x, kernel)
class AttentionWithContext(Layer):
def __init__(self,
W_regularizer=None, u_regularizer=None, b_regularizer=None,
W_constraint=None, u_constraint=None, b_constraint=None,
init='glorot_uniform', bias=True, **kwargs):
self.supports_masking = True
self.init = init
self.W_regularizer = regularizers.get(W_regularizer)
self.u_regularizer = regularizers.get(u_regularizer)
self.b_regularizer = regularizers.get(b_regularizer)
self.W_constraint = constraints.get(W_constraint)
self.u_constraint = constraints.get(u_constraint)
self.b_constraint = constraints.get(b_constraint)
self.bias = bias
super(AttentionWithContext, self).__init__(**kwargs)
def build(self, input_shape):
assert len(input_shape) == 3
self.W = self.add_weight(shape=(input_shape[-1], input_shape[-1],),
initializer=self.init,
name='{}_W'.format(self.name),
regularizer=self.W_regularizer,
constraint=self.W_constraint)
if self.bias:
self.b = self.add_weight(shape=(input_shape[-1],),
initializer='zero',
name='{}_b'.format(self.name),
regularizer=self.b_regularizer,
constraint=self.b_constraint)
self.u = self.add_weight(shape=(input_shape[-1],),
initializer=self.init,
name='{}_u'.format(self.name),
regularizer=self.u_regularizer,
constraint=self.u_constraint)
super(AttentionWithContext, self).build(input_shape)
def compute_mask(self, input, input_mask=None):
return None
def call(self, x, mask=None):
uit = dot_product(x, self.W)
if self.bias:
uit += self.b
uit = K.tanh(uit)
ait = dot_product(uit, self.u)
a = K.exp(ait)
if mask is not None:
a *= K.cast(mask, K.floatx())
a /= K.cast(K.sum(a, axis=1, keepdims=True) + K.epsilon(), K.floatx())
a = K.expand_dims(a)
weighted_input = x * a
return K.sum(weighted_input, axis=1)
def compute_output_shape(self, input_shape):
return input_shape[0], input_shape[-1]
class Attention(Layer):
'Attention layer constructed from the Hierarchical Attention Network (2015) paper'
def __init__(self, regularizer=None, **kwargs):
super(Attention, self).__init__(**kwargs)
self.regularizer = regularizer
self.supports_masking = True
def build(self, input_shape):
# Create a trainable weight variable for this layer.
self.context = self.add_weight(name='context',
shape=(input_shape[-1], 1),
initializer=initializers.RandomNormal(
mean=0.0, stddev=0.05, seed=None),
regularizer=self.regularizer,
trainable=True)
super(Attention, self).build(input_shape)
def call(self, x, mask=None):
attention_in = K.exp(K.squeeze(K.dot(x, self.context), axis=-1))
attention = attention_in/K.expand_dims(K.sum(attention_in, axis=-1), -1)
if mask is not None:
# use only the inputs specified by the mask
# import pdb; pdb.set_trace()
attention = attention*K.cast(mask, 'float32')
weighted_sum = K.batch_dot(K.permute_dimensions(x, [0, 2, 1]), attention)
return weighted_sum
def compute_output_shape(self, input_shape):
print(input_shape)
return (input_shape[0], input_shape[-1])