1
- from tensorflow .python .keras .layers import Layer ,Dense , Activation ,Dropout , BatchNormalization , concatenate
1
+ from tensorflow .python .keras .layers import Layer ,Activation ,BatchNormalization
2
2
from tensorflow .python .keras .regularizers import l2
3
3
from tensorflow .python .keras .initializers import RandomNormal ,Zeros ,glorot_normal ,glorot_uniform
4
4
from tensorflow .python .keras import backend as K
5
- from tensorflow . python . keras . activations import softmax
5
+
6
6
import tensorflow as tf
7
7
8
8
@@ -101,12 +101,14 @@ def build(self, input_shape):
101
101
102
102
embedding_size = input_shape [0 ][- 1 ]
103
103
104
- # self.attention_W = self.add_weight(shape=(embedding_size, self.attention_factor), initializer=glorot_normal(seed=self.seed),
105
- # name="attention_W")
106
- # self.attention_b = self.add_weight(shape=(self.attention_factor,), initializer=Zeros(), name="attention_b")
104
+ self .attention_W = self .add_weight (shape = (embedding_size , self .attention_factor ), initializer = glorot_normal (seed = self .seed ), regularizer = l2 ( self . l2_reg_w ),
105
+ name = "attention_W" )
106
+ self .attention_b = self .add_weight (shape = (self .attention_factor ,), initializer = Zeros (), name = "attention_b" )
107
107
self .projection_h = self .add_weight (shape = (self .attention_factor , 1 ), initializer = glorot_normal (seed = self .seed ),
108
108
name = "projection_h" )
109
109
self .projection_p = self .add_weight (shape = (embedding_size , 1 ), initializer = glorot_normal (seed = self .seed ), name = "projection_p" )
110
+
111
+
110
112
super (AFMLayer , self ).build (input_shape ) # Be sure to call this somewhere!
111
113
112
114
def call (self , inputs ,** kwargs ):
@@ -127,14 +129,14 @@ def call(self, inputs,**kwargs):
127
129
inner_product = p * q
128
130
129
131
bi_interaction = inner_product
132
+ attention_temp = tf .nn .relu (tf .nn .bias_add (tf .tensordot (bi_interaction ,self .attention_W ,axes = (- 1 ,0 )),self .attention_b ))
133
+ # Dense(self.attention_factor,'relu',kernel_regularizer=l2(self.l2_reg_w))(bi_interaction)
134
+ attention_weight = tf .nn .softmax (tf .tensordot (attention_temp ,self .projection_h ,axes = (- 1 ,0 )),dim = 1 )
135
+ attention_output = tf .reduce_sum (attention_weight * bi_interaction ,axis = 1 )
130
136
131
- attention_temp = Dense (self .attention_factor ,'relu' ,kernel_regularizer = l2 (self .l2_reg_w ))(bi_interaction )
132
- attention_weight = softmax (K .dot (attention_temp , self .projection_h ),axis = 1 )
133
-
134
- attention_output = K .sum (attention_weight * bi_interaction ,axis = 1 )
135
137
attention_output = tf .nn .dropout (attention_output ,self .keep_prob ,seed = 1024 )
136
- # Dropout(1-self.keep_prob)(attention_output)
137
- afm_out = K . dot (attention_output , self .projection_p )
138
+ # Dropout(1-self.keep_prob)(attention_output)
139
+ afm_out = tf . tensordot (attention_output ,self .projection_p , axes = ( - 1 , 0 ) )
138
140
139
141
return afm_out
140
142
@@ -169,13 +171,14 @@ def build(self, input_shape):
169
171
def call (self , inputs ,** kwargs ):
170
172
x = inputs
171
173
if self .use_bias :
172
- x = K .bias_add (x , self .global_bias , data_format = 'channels_last' )
174
+ x = tf .nn .bias_add (x ,self .global_bias ,data_format = 'NHWC' )
175
+
173
176
if isinstance (self .activation ,str ):
174
177
output = Activation (self .activation )(x )
175
178
else :
176
179
output = self .activation (x )
177
180
178
- output = K .reshape (output ,(- 1 ,1 ))
181
+ output = tf .reshape (output ,(- 1 ,1 ))
179
182
180
183
return output
181
184
@@ -282,17 +285,28 @@ def __init__(self, hidden_size, activation,l2_reg, keep_prob, use_bn,seed,**kwa
282
285
super (MLP , self ).__init__ (** kwargs )
283
286
284
287
def build (self , input_shape ):
288
+ input_size = input_shape [- 1 ]
289
+ hidden_units = [int (input_size )] + self .hidden_size
290
+ self .kernels = [self .add_weight (name = 'kernel' + str (i ),
291
+ shape = (hidden_units [i ], hidden_units [i + 1 ]),
292
+ initializer = glorot_normal (seed = self .seed ),
293
+ regularizer = l2 (self .l2_reg ),
294
+ trainable = True ) for i in range (len (self .hidden_size ))]
295
+ self .bias = [self .add_weight (name = 'bias' + str (i ),
296
+ shape = (self .hidden_size [i ],),
297
+ initializer = Zeros (),
298
+ trainable = True ) for i in range (len (self .hidden_size ))]
285
299
286
300
super (MLP , self ).build (input_shape ) # Be sure to call this somewhere!
287
301
288
302
def call (self , inputs ,** kwargs ):
289
303
deep_input = inputs
290
- #deep_input = Dropout(1 - self.keep_prob)(deep_input)
291
304
292
- for l in range (len (self .hidden_size )):
293
- fc = Dense (self .hidden_size [l ], activation = None , \
294
- kernel_initializer = glorot_normal (seed = self .seed ), \
295
- kernel_regularizer = l2 (self .l2_reg ))(deep_input )
305
+ for i in range (len (self .hidden_size )):
306
+ fc = tf .nn .bias_add (tf .tensordot (deep_input ,self .kernels [i ],axes = (- 1 ,0 )),self .bias [i ])
307
+ #fc = Dense(self.hidden_size[i], activation=None, \
308
+ # kernel_initializer=glorot_normal(seed=self.seed), \
309
+ # kernel_regularizer=l2(self.l2_reg))(deep_input)
296
310
if self .use_bn :
297
311
fc = BatchNormalization ()(fc )
298
312
@@ -302,7 +316,7 @@ def call(self, inputs,**kwargs):
302
316
fc = self .activation ()(fc )
303
317
else :
304
318
raise ValueError ("Invalid activation of MLP,found %s.You should use a str or a Activation Layer Class." % (self .activation ))
305
- fc = Dropout ( 1 - self .keep_prob )( fc )
319
+ fc = tf . nn . dropout ( fc , self .keep_prob )
306
320
307
321
deep_input = fc
308
322
@@ -327,7 +341,7 @@ class BiInteractionPooling(Layer):
327
341
- A list of 3D tensor with shape:``(batch_size,field_size,embedding_size)``.
328
342
329
343
Output shape
330
- - 2D tensor with shape: ``(batch_size, embedding_size)``.
344
+ - 3D tensor with shape: ``(batch_size,1, embedding_size)``.
331
345
332
346
References
333
347
- [Neural Factorization Machines for Sparse Predictive Analytics](http://arxiv.org/abs/1708.05027)
@@ -350,14 +364,14 @@ def call(self, inputs,**kwargs):
350
364
raise ValueError ("Unexpected inputs dimensions %d, expect to be 3 dimensions" % (K .ndim (inputs )))
351
365
352
366
concated_embeds_value = inputs
353
- square_of_sum = K .square (K . sum (concated_embeds_value , axis = 1 , keepdims = True ))
354
- sum_of_square = K . sum (concated_embeds_value * concated_embeds_value , axis = 1 , keepdims = True )
367
+ square_of_sum = tf .square (tf . reduce_sum (concated_embeds_value , axis = 1 , keep_dims = True ))
368
+ sum_of_square = tf . reduce_sum (concated_embeds_value * concated_embeds_value , axis = 1 , keep_dims = True )
355
369
cross_term = 0.5 * (square_of_sum - sum_of_square )
356
- cross_term = K . reshape ( cross_term ,( - 1 , inputs . get_shape ()[ - 1 ]))
370
+
357
371
return cross_term
358
372
359
373
def compute_output_shape (self , input_shape ):
360
- return (None , input_shape [- 1 ])
374
+ return (None , 1 , input_shape [- 1 ])
361
375
362
376
class OutterProductLayer (Layer ):
363
377
"""OutterProduct Layer used in PNN.This implemention is adapted from code that the author of the paper published on https://github.com/Atomu2014/product-nets.
@@ -366,7 +380,7 @@ class OutterProductLayer(Layer):
366
380
- A list of N 3D tensor with shape: ``(batch_size,1,embedding_size)``.
367
381
368
382
Output shape
369
- - 2D tensor with shape:``(batch_size, N*(N-1)/2 )``.
383
+ - 2D tensor with shape:``(batch_size,N*(N-1)/2 )``.
370
384
371
385
Arguments
372
386
- **kernel_type**: str. The kernel weight matrix type to use,can be mat,vec or num
@@ -434,8 +448,8 @@ def call(self, inputs,**kwargs):
434
448
for j in range (i + 1 , num_inputs ):
435
449
row .append (i )
436
450
col .append (j )
437
- p = K . concatenate ([embed_list [idx ] for idx in row ],axis = 1 ) # batch num_pairs k
438
- q = K . concatenate ([embed_list [idx ] for idx in col ],axis = 1 ) # Reshape([num_pairs, self.embedding_size])
451
+ p = tf . concat ([embed_list [idx ] for idx in row ],axis = 1 ) # batch num_pairs k
452
+ q = tf . concat ([embed_list [idx ] for idx in col ],axis = 1 ) # Reshape([num_pairs, self.embedding_size])
439
453
440
454
#-------------------------
441
455
if self .kernel_type == 'mat' :
@@ -499,7 +513,7 @@ class InnerProductLayer(Layer):
499
513
- A list of N 3D tensor with shape: ``(batch_size,1,embedding_size)``.
500
514
501
515
Output shape
502
- - 2D tensor with shape: ``(batch_size, N*(N-1)/2 )`` if use reduce_sum. or 3D tensor with shape: ``(batch_size, N*(N-1)/2, embedding_size )`` if not use reduce_sum.
516
+ - 3D tensor with shape: ``(batch_size, N*(N-1)/2 ,1 )`` if use reduce_sum. or 3D tensor with shape: ``(batch_size, N*(N-1)/2, embedding_size )`` if not use reduce_sum.
503
517
504
518
Arguments
505
519
- **reduce_sum**: bool. Whether return inner product or element-wise product
@@ -550,11 +564,11 @@ def call(self, inputs,**kwargs):
550
564
for j in range (i + 1 , num_inputs ):
551
565
row .append (i )
552
566
col .append (j )
553
- p = K . concatenate ([embed_list [idx ] for idx in row ],axis = 1 )# batch num_pairs k
554
- q = K . concatenate ([embed_list [idx ] for idx in col ],axis = 1 ) # Reshape([num_pairs, self.embedding_size])
567
+ p = tf . concat ([embed_list [idx ] for idx in row ],axis = 1 )# batch num_pairs k
568
+ q = tf . concat ([embed_list [idx ] for idx in col ],axis = 1 ) # Reshape([num_pairs, self.embedding_size])
555
569
inner_product = p * q
556
570
if self .reduce_sum :
557
- inner_product = K . sum (inner_product , axis = 2 , keepdims = False )
571
+ inner_product = tf . reduce_sum (inner_product , axis = 2 , keep_dims = True )
558
572
return inner_product
559
573
560
574
@@ -564,7 +578,7 @@ def compute_output_shape(self, input_shape):
564
578
input_shape = input_shape [0 ]
565
579
embed_size = input_shape [- 1 ]
566
580
if self .reduce_sum :
567
- return (input_shape [0 ],num_pairs )
581
+ return (input_shape [0 ],num_pairs , 1 )
568
582
else :
569
583
return (input_shape [0 ],num_pairs ,embed_size )
570
584
@@ -623,6 +637,11 @@ def build(self, input_shape):
623
637
raise ValueError ('A `LocalActivationUnit` layer requires '
624
638
'inputs of a two inputs with shape (None,1,embedding_size) and (None,T,embedding_size)'
625
639
'Got different shapes: %s,%s' % (input_shape ))
640
+ size = 4 * int (input_shape [0 ][- 1 ]) if len (self .hidden_size ) == 0 else self .hidden_size [- 1 ]
641
+ self .kernel = self .add_weight (shape = (size , 1 ),
642
+ initializer = glorot_normal (seed = self .seed ),
643
+ name = "kernel" )
644
+ self .bias = self .add_weight (shape = (1 ,), initializer = Zeros (), name = "bias" )
626
645
super (LocalActivationUnit , self ).build (input_shape ) # Be sure to call this somewhere!
627
646
628
647
def call (self , inputs ,** kwargs ):
@@ -634,9 +653,9 @@ def call(self, inputs,**kwargs):
634
653
queries = K .repeat_elements (query ,keys_len ,1 )
635
654
636
655
att_input = tf .concat ([queries , keys , queries - keys , queries * keys ], axis = - 1 )
637
- att_input = BatchNormalization () (att_input )
656
+ att_input = tf . layers . batch_normalization (att_input )
638
657
att_out = MLP (self .hidden_size , self .activation , self .l2_reg , self .keep_prob , self .use_bn , seed = self .seed )(att_input )
639
- attention_score = Dense ( 1 , 'linear' )( att_out )
658
+ attention_score = tf . nn . bias_add ( tf . tensordot ( att_out , self . kernel , axes = ( - 1 , 0 )), self . bias )
640
659
641
660
return attention_score
642
661
0 commit comments