Skip to content

Commit c641875

Browse files
author
Weichen Shen
authored
Merge dev (shenweichen#12)
# Major Changes and Improvements - Refactor `deepctr.models.MLR` - Update `deepctr.models.PredictionLayer` to support Layer type activations. - Add default args to `deepctr.layers.MLP` and `deepctr.layers.LocalActivationUnit` - Fix bug in `deepctr.layers.DCN` when only use CrossNet. - Fix bug in get_config of `deepctr.layers.LocalActivationUnit` - Add many test cases in `tests` folder - Add continuous integration, test coverage detection and code quality detection - Other small changes
1 parent d27c232 commit c641875

28 files changed

+451
-306
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
*.h5
2+
.pytest_cache/
23
tests/unused/*
34
# Byte-compiled / optimized / DLL files
45
__pycache__/

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
# DeepCTR
22
![dep1](https://img.shields.io/badge/Tensorflow-1.4/1.5/1.6-blue.svg
33
)
4-
[![Python Versions](https://img.shields.io/badge/python-3.6-blue.svg)](https://pypi.org/project/deepctr)
4+
[![Python Versions](https://img.shields.io/pypi/pyversions/deepctr.svg)](https://pypi.org/project/deepctr)
55
[![PyPI Version](https://img.shields.io/pypi/v/deepctr.svg)](https://pypi.org/project/deepctr)
66
[![GitHub Issues](https://img.shields.io/github/issues/shenweichen/deepctr.svg
77
)](https://github.com/shenweichen/deepctr/issues)
88
[![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://github.com/shenweichen/deepctr/blob/master/LICENSE)
99

1010
[![Documentation Status](https://readthedocs.org/projects/deepctr-doc/badge/?version=latest)](https://deepctr-doc.readthedocs.io/)
1111
[![Build Status](https://travis-ci.com/shenweichen/DeepCTR.svg?branch=master)](https://travis-ci.com/shenweichen/DeepCTR)
12-
[![Coverage Status](https://coveralls.io/repos/github/shenweichen/DeepCTR/badge.svg)](https://coveralls.io/github/shenweichen/DeepCTR)
12+
[![Coverage Status](https://coveralls.io/repos/github/shenweichen/DeepCTR/badge.svg?branch=master)](https://coveralls.io/github/shenweichen/DeepCTR?branch=master)
1313
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/d4099734dc0e4bab91d332ead8c0bdd0)](https://www.codacy.com/app/wcshen1994/DeepCTR?utm_source=github.com&utm_medium=referral&utm_content=shenweichen/DeepCTR&utm_campaign=Badge_Grade)
1414

15+
1516
DeepCTR is a **Easy-to-use**,**Modular** and **Extendible** package of deep-learning based CTR models along with lots of core components layer which can be used to build your own custom model easily.You can use any complex model with `model.fit()`and`model.predict()` just like any other keras model.And the layers are compatible with tensorflow.Through `pip install deepctr` get the package and [**Get Started!**](https://deepctr-doc.readthedocs.io/en/latest/Quick-Start.html)
1617

1718

deepctr/activations.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from tensorflow.python.keras.layers import Layer, BatchNormalization
1+
from tensorflow.python.keras.layers import Layer
22
from tensorflow.python.keras.initializers import Zeros
33
import tensorflow as tf
44

@@ -26,19 +26,20 @@ def __init__(self, axis=-1, epsilon=1e-9, **kwargs):
2626
self.epsilon = epsilon
2727
super(Dice, self).__init__(**kwargs)
2828

29-
3029
def build(self, input_shape):
3130
self.alphas = self.add_weight(shape=(input_shape[-1],), initializer=Zeros(
3231
), dtype=tf.float32, name=self.name+'dice_alpha') # name='alpha_'+self.name
3332
super(Dice, self).build(input_shape) # Be sure to call this somewhere!
3433

3534
def call(self, inputs, **kwargs):
3635

37-
inputs_normed = tf.layers.batch_normalization(inputs,axis=self.axis, epsilon=self.epsilon, center=False, scale=False)
36+
inputs_normed = tf.layers.batch_normalization(
37+
inputs, axis=self.axis, epsilon=self.epsilon, center=False, scale=False)
3838
x_p = tf.sigmoid(inputs_normed)
3939
return self.alphas * (1.0 - x_p) * inputs + x_p * inputs
40+
4041
def get_config(self,):
4142

42-
config = {'axis': self.axis,'epsilon':self.epsilon}
43+
config = {'axis': self.axis, 'epsilon': self.epsilon}
4344
base_config = super(Dice, self).get_config()
44-
return dict(list(base_config.items()) + list(config.items()))
45+
return dict(list(base_config.items()) + list(config.items()))

deepctr/layers.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from tensorflow.python.keras.layers import Layer,Activation,BatchNormalization
22
from tensorflow.python.keras.regularizers import l2
3-
from tensorflow.python.keras.initializers import RandomNormal,Zeros,glorot_normal,glorot_uniform
3+
from tensorflow.python.keras.initializers import Zeros,glorot_normal,glorot_uniform
44
from tensorflow.python.keras import backend as K
55

66
import tensorflow as tf
@@ -61,7 +61,7 @@ class AFMLayer(Layer):
6161
6262
- **l2_reg_w** : float between 0 and 1. L2 regularizer strength applied to attention network.
6363
64-
- **keep_prob** : float between 0 and 1. Fraction of the attention net output units to keep.
64+
- **keep_prob** : float between 0 and 1. Fraction of the attention net output units to keep.
6565
6666
- **seed** : A Python integer to use as random seed.
6767
@@ -175,9 +175,10 @@ def call(self, inputs,**kwargs):
175175

176176
if isinstance(self.activation,str):
177177
output = Activation(self.activation)(x)
178+
elif issubclass(self.activation,Layer):
179+
output = self.activation()(x)
178180
else:
179-
output = self.activation(x)
180-
181+
raise ValueError("Invalid activation of MLP,found %s.You should use a str or a Activation Layer Class." % (self.activation))
181182
output = tf.reshape(output,(-1,1))
182183

183184
return output
@@ -254,7 +255,7 @@ def get_config(self,):
254255

255256
class MLP(Layer):
256257
"""The Multi Layer Percetron
257-
258+
258259
Input shape
259260
- nD tensor with shape: ``(batch_size, ..., input_dim)``. The most common situation would be a 2D input with shape ``(batch_size, input_dim)``.
260261
@@ -268,14 +269,14 @@ class MLP(Layer):
268269
269270
- **l2_reg**: float between 0 and 1. L2 regularizer strength applied to the kernel weights matrix.
270271
271-
- **keep_prob**: float between 0 and 1. Fraction of the units to keep.
272+
- **keep_prob**: float between 0 and 1. Fraction of the units to keep.
272273
273274
- **use_bn**: bool. Whether use BatchNormalization before activation or not.
274275
275276
- **seed**: A Python integer to use as random seed.
276277
"""
277278

278-
def __init__(self, hidden_size, activation,l2_reg, keep_prob, use_bn,seed,**kwargs):
279+
def __init__(self, hidden_size, activation='relu',l2_reg=0, keep_prob=1, use_bn=False,seed=1024,**kwargs):
279280
self.hidden_size = hidden_size
280281
self.activation =activation
281282
self.keep_prob = keep_prob
@@ -338,7 +339,7 @@ class BiInteractionPooling(Layer):
338339
"""Bi-Interaction Layer used in Neural FM,compress the pairwise element-wise product of features into one single vector.
339340
340341
Input shape
341-
- A list of 3D tensor with shape:``(batch_size,field_size,embedding_size)``.
342+
- A 3D tensor with shape:``(batch_size,field_size,embedding_size)``.
342343
343344
Output shape
344345
- 3D tensor with shape: ``(batch_size,1,embedding_size)``.
@@ -381,7 +382,7 @@ class OutterProductLayer(Layer):
381382
382383
Output shape
383384
- 2D tensor with shape:``(batch_size,N*(N-1)/2 )``.
384-
385+
385386
Arguments
386387
- **kernel_type**: str. The kernel weight matrix type to use,can be mat,vec or num
387388
@@ -557,7 +558,7 @@ def call(self, inputs,**kwargs):
557558
row = []
558559
col = []
559560
num_inputs = len(embed_list)
560-
num_pairs = int(num_inputs * (num_inputs - 1) / 2)
561+
#num_pairs = int(num_inputs * (num_inputs - 1) / 2)
561562

562563

563564
for i in range(num_inputs - 1):
@@ -604,7 +605,7 @@ class LocalActivationUnit(Layer):
604605
605606
- **l2_reg**: float between 0 and 1. L2 regularizer strength applied to the kernel weights matrix of attention net.
606607
607-
- **keep_prob**: float between 0 and 1. Fraction of the units to keep of attention net.
608+
- **keep_prob**: float between 0 and 1. Fraction of the units to keep of attention net.
608609
609610
- **use_bn**: bool. Whether use BatchNormalization before activation or not in attention net.
610611
@@ -614,7 +615,7 @@ class LocalActivationUnit(Layer):
614615
- [Deep Interest Network for Click-Through Rate Prediction](https://arxiv.org/pdf/1706.06978.pdf)
615616
"""
616617

617-
def __init__(self,hidden_size, activation,l2_reg, keep_prob, use_bn,seed,**kwargs):
618+
def __init__(self,hidden_size=(64,32), activation='sigmoid',l2_reg=0, keep_prob=1, use_bn=False,seed=1024,**kwargs):
618619
self.hidden_size = hidden_size
619620
self.activation = activation
620621
self.l2_reg = l2_reg
@@ -663,7 +664,7 @@ def compute_output_shape(self, input_shape):
663664
return input_shape[1][:2] + (1,)
664665

665666
def get_config(self,):
666-
config = {'activation': self.activation,'hidden_size':self.hidden_size, 'l2_reg':self.l2_reg, 'keep_prob':self.keep_prob,'seed': self.seed}
667+
config = {'activation': self.activation,'hidden_size':self.hidden_size, 'l2_reg':self.l2_reg, 'keep_prob':self.keep_prob,'use_bn':self.use_bn,'seed': self.seed}
667668
base_config = super(LocalActivationUnit, self).get_config()
668669
return dict(list(base_config.items()) + list(config.items()))
669670

deepctr/models/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
from .dcn import DCN
33
from .mlr import MLR
44
from .deepfm import DeepFM
5-
from .mlr import MLR
65
from .nfm import NFM
76
from .din import DIN
87
from .fnn import FNN

deepctr/models/afm.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@ def AFM(feature_dim_dict, embedding_size=8, use_attention=True, attention_factor
6161
linear_term = add(linear_term)
6262
elif len(linear_term) > 0:
6363
linear_term = linear_term[0]
64-
else:
65-
linear_term = 0
6664

6765
if len(dense_input) > 0:
6866
continuous_embedding_list = list(

deepctr/models/dcn.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717

1818
def DCN(feature_dim_dict, embedding_size='auto',
19-
cross_num=2, hidden_size=[128, 128, ], l2_reg_embedding=1e-5, l2_reg_cross=1e-5, l2_reg_deep=0,
19+
cross_num=2, hidden_size=(128, 128, ), l2_reg_embedding=1e-5, l2_reg_cross=1e-5, l2_reg_deep=0,
2020
init_std=0.0001, seed=1024, keep_prob=1, use_bn=False, activation='relu', final_activation='sigmoid',
2121
):
2222
"""Instantiates the Deep&Cross Network architecture.
@@ -49,7 +49,8 @@ def DCN(feature_dim_dict, embedding_size='auto',
4949
embed_list = [sparse_embedding[i](sparse_input[i])
5050
for i in range(len(sparse_input))]
5151

52-
deep_input = Flatten()(Concatenate()(embed_list))
52+
deep_input = Flatten()(Concatenate()(embed_list)
53+
if len(embed_list) > 1 else embed_list[0])
5354
if len(dense_input) > 0:
5455
if len(dense_input) == 1:
5556
continuous_list = dense_input[0]

deepctr/models/deepfm.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020

2121
def DeepFM(feature_dim_dict, embedding_size=8,
22-
use_fm=True, hidden_size=[128, 128], l2_reg_linear=0.00001, l2_reg_embedding=0.00001, l2_reg_deep=0,
22+
use_fm=True, hidden_size=(128, 128), l2_reg_linear=0.00001, l2_reg_embedding=0.00001, l2_reg_deep=0,
2323
init_std=0.0001, seed=1024, keep_prob=1, activation='relu', final_activation='sigmoid', use_bn=False):
2424
"""Instantiates the DeepFM Network architecture.
2525
@@ -61,8 +61,6 @@ def DeepFM(feature_dim_dict, embedding_size=8,
6161
linear_term = add(linear_term)
6262
elif len(linear_term) > 0:
6363
linear_term = linear_term[0]
64-
else:
65-
linear_term = 0
6664

6765
if len(dense_input) > 0:
6866
continuous_embedding_list = list(

deepctr/models/din.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from tensorflow.python.keras.layers import Input, Dense, Embedding, Concatenate, Reshape
1111
from tensorflow.python.keras.models import Model
12-
from tensorflow.python.keras.initializers import RandomNormal, TruncatedNormal
12+
from tensorflow.python.keras.initializers import RandomNormal
1313
from tensorflow.python.keras.regularizers import l2
1414

1515
from ..layers import MLP
@@ -30,7 +30,7 @@ def get_input(feature_dim_dict, seq_feature_list, seq_max_len):
3030

3131

3232
def DIN(feature_dim_dict, seq_feature_list, embedding_size=8, hist_len_max=16,
33-
use_din=True, use_bn=False, hidden_size=[200, 80], activation='relu', att_hidden_size=[80, 40], att_activation=Dice, att_weight_normalization=False,
33+
use_din=True, use_bn=False, hidden_size=(200, 80), activation='relu', att_hidden_size=(80, 40), att_activation=Dice, att_weight_normalization=False,
3434
l2_reg_deep=0, l2_reg_embedding=1e-5, final_activation='sigmoid', keep_prob=1, init_std=0.0001, seed=1024, ):
3535
"""Instantiates the Deep Interest Network architecture.
3636

deepctr/models/fnn.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818

1919
def FNN(feature_dim_dict, embedding_size=8,
20-
hidden_size=[128, 128],
20+
hidden_size=(128, 128),
2121
l2_reg_embedding=1e-5, l2_reg_linear=1e-5, l2_reg_deep=0,
2222
init_std=0.0001, seed=1024, keep_prob=1,
2323
activation='relu', final_activation='sigmoid', ):
@@ -58,8 +58,7 @@ def FNN(feature_dim_dict, embedding_size=8,
5858
linear_term = add(linear_term)
5959
elif len(linear_term) > 0:
6060
linear_term = linear_term[0]
61-
else:
62-
linear_term = 0
61+
6362
#linear_term = add([linear_embedding[i](sparse_input[i]) for i in range(len(feature_dim_dict["sparse"]))])
6463
if len(dense_input) > 0:
6564
continuous_embedding_list = list(

0 commit comments

Comments
 (0)