Skip to content

Commit ce140ff

Browse files
author
浅梦
authored
fix some bugs (shenweichen#185)
- fix bug in `get_varlen_pooling_list` - fix bug in `SequencePoolingLayer` when `mode='max'` - Add alias `ONN` for model `NFFM`
1 parent dcf583f commit ce140ff

26 files changed

+156
-153
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Let's [**Get Started!**](https://deepctr-doc.readthedocs.io/en/latest/Quick-Star
4040
| AutoInt | [arxiv 2018][AutoInt: Automatic Feature Interaction Learning via Self-Attentive Neural Networks](https://arxiv.org/abs/1810.11921) |
4141
| Deep Interest Network | [KDD 2018][Deep Interest Network for Click-Through Rate Prediction](https://arxiv.org/pdf/1706.06978.pdf) |
4242
| Deep Interest Evolution Network | [AAAI 2019][Deep Interest Evolution Network for Click-Through Rate Prediction](https://arxiv.org/pdf/1809.03672.pdf) |
43-
| NFFM | [arxiv 2019][Operation-aware Neural Networks for User Response Prediction](https://arxiv.org/pdf/1904.12579.pdf) |
43+
| ONN | [arxiv 2019][Operation-aware Neural Networks for User Response Prediction](https://arxiv.org/pdf/1904.12579.pdf) |
4444
| FGCNN | [WWW 2019][Feature Generation by Convolutional Neural Network for Click-Through Rate Prediction ](https://arxiv.org/pdf/1904.04447) |
4545
| Deep Session Interest Network | [IJCAI 2019][Deep Session Interest Network for Click-Through Rate Prediction ](https://arxiv.org/abs/1905.06482) |
4646
| FiBiNET | [RecSys 2019][FiBiNET: Combining Feature Importance and Bilinear feature Interaction for Click-Through Rate Prediction](https://arxiv.org/pdf/1905.09433.pdf) |

deepctr/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
from .utils import check_version
22

3-
__version__ = '0.7.1'
3+
__version__ = '0.7.2'
44
check_version(__version__)

deepctr/inputs.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,8 @@ def get_varlen_pooling_list(embedding_dict, features, varlen_sparse_feature_colu
264264
vec = SequencePoolingLayer(combiner, supports_masking=True)(
265265
seq_input)
266266
pooling_vec_list[fc.group_name].append(vec)
267-
if to_list:
268-
return chain.from_iterable(pooling_vec_list.values())
267+
if to_list:
268+
return chain.from_iterable(pooling_vec_list.values())
269269
return pooling_vec_list
270270

271271

deepctr/layers/core.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def build(self, input_shape):
6666
if input_shape[0][-1] != input_shape[1][-1] or input_shape[0][1] != 1:
6767
raise ValueError('A `LocalActivationUnit` layer requires '
6868
'inputs of a two inputs with shape (None,1,embedding_size) and (None,T,embedding_size)'
69-
'Got different shapes: %s,%s' % (input_shape[0],input_shape[1]))
69+
'Got different shapes: %s,%s' % (input_shape[0], input_shape[1]))
7070
size = 4 * \
7171
int(input_shape[0][-1]
7272
) if len(self.hidden_units) == 0 else self.hidden_units[-1]
@@ -77,9 +77,9 @@ def build(self, input_shape):
7777
self.bias = self.add_weight(
7878
shape=(1,), initializer=Zeros(), name="bias")
7979
self.dnn = DNN(self.hidden_units, self.activation, self.l2_reg,
80-
self.dropout_rate, self.use_bn, seed=self.seed)
80+
self.dropout_rate, self.use_bn, seed=self.seed)
8181

82-
self.dense = tf.keras.layers.Lambda(lambda x:tf.nn.bias_add(tf.tensordot(
82+
self.dense = tf.keras.layers.Lambda(lambda x: tf.nn.bias_add(tf.tensordot(
8383
x[0], x[1], axes=(-1, 0)), x[2]))
8484

8585
super(LocalActivationUnit, self).build(
@@ -97,7 +97,7 @@ def call(self, inputs, training=None, **kwargs):
9797

9898
att_out = self.dnn(att_input, training=training)
9999

100-
attention_score = self.dense([att_out,self.kernel,self.bias])
100+
attention_score = self.dense([att_out, self.kernel, self.bias])
101101

102102
return attention_score
103103

@@ -165,7 +165,8 @@ def build(self, input_shape):
165165
if self.use_bn:
166166
self.bn_layers = [tf.keras.layers.BatchNormalization() for _ in range(len(self.hidden_units))]
167167

168-
self.dropout_layers = [tf.keras.layers.Dropout(self.dropout_rate,seed=self.seed+i) for i in range(len(self.hidden_units))]
168+
self.dropout_layers = [tf.keras.layers.Dropout(self.dropout_rate, seed=self.seed + i) for i in
169+
range(len(self.hidden_units))]
169170

170171
self.activation_layers = [activation_layer(self.activation) for _ in range(len(self.hidden_units))]
171172

@@ -186,7 +187,7 @@ def call(self, inputs, training=None, **kwargs):
186187

187188
fc = self.activation_layers[i](fc)
188189

189-
fc = self.dropout_layers[i](fc,training = training)
190+
fc = self.dropout_layers[i](fc, training=training)
190191
deep_input = fc
191192

192193
return deep_input

deepctr/layers/sequence.py

+17-17
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414

1515
from .core import LocalActivationUnit
1616
from .normalization import LayerNormalization
17+
1718
if tf.__version__ >= '2.0.0':
1819
from ..contrib.rnn_v2 import dynamic_rnn
1920
else:
2021
from ..contrib.rnn import dynamic_rnn
2122
from ..contrib.utils import QAAttGRUCell, VecAttGRUCell
22-
from .utils import reduce_sum,reduce_max,div,softmax,reduce_mean
23+
from .utils import reduce_sum, reduce_max, div, softmax, reduce_mean
2324

2425

2526
class SequencePoolingLayer(Layer):
@@ -46,7 +47,7 @@ def __init__(self, mode='mean', supports_masking=False, **kwargs):
4647
if mode not in ['sum', 'mean', 'max']:
4748
raise ValueError("mode must be sum or mean")
4849
self.mode = mode
49-
self.eps = tf.constant(1e-8,tf.float32)
50+
self.eps = tf.constant(1e-8, tf.float32)
5051
super(SequencePoolingLayer, self).__init__(**kwargs)
5152

5253
self.supports_masking = supports_masking
@@ -63,7 +64,7 @@ def call(self, seq_value_len_list, mask=None, **kwargs):
6364
raise ValueError(
6465
"When supports_masking=True,input must support masking")
6566
uiseq_embed_list = seq_value_len_list
66-
mask = tf.cast(mask,tf.float32)# tf.to_float(mask)
67+
mask = tf.cast(mask, tf.float32) # tf.to_float(mask)
6768
user_behavior_length = reduce_sum(mask, axis=-1, keep_dims=True)
6869
mask = tf.expand_dims(mask, axis=2)
6970
else:
@@ -77,15 +78,14 @@ def call(self, seq_value_len_list, mask=None, **kwargs):
7778

7879
mask = tf.tile(mask, [1, 1, embedding_size])
7980

80-
uiseq_embed_list *= mask
81-
hist = uiseq_embed_list
8281
if self.mode == "max":
82+
hist = uiseq_embed_list - (1-mask) * 1e9
8383
return reduce_max(hist, 1, keep_dims=True)
8484

85-
hist = reduce_sum(hist, 1, keep_dims=False)
85+
hist = reduce_sum(uiseq_embed_list * mask, 1, keep_dims=False)
8686

8787
if self.mode == "mean":
88-
hist = div(hist, tf.cast(user_behavior_length,tf.float32) + self.eps)
88+
hist = div(hist, tf.cast(user_behavior_length, tf.float32) + self.eps)
8989

9090
hist = tf.expand_dims(hist, axis=1)
9191
return hist
@@ -126,7 +126,7 @@ class WeightedSequenceLayer(Layer):
126126
- **supports_masking**:If True,the input need to support masking.
127127
"""
128128

129-
def __init__(self,weight_normalization=True, supports_masking=False, **kwargs):
129+
def __init__(self, weight_normalization=True, supports_masking=False, **kwargs):
130130
super(WeightedSequenceLayer, self).__init__(**kwargs)
131131
self.weight_normalization = weight_normalization
132132
self.supports_masking = supports_masking
@@ -159,14 +159,13 @@ def call(self, input_list, mask=None, **kwargs):
159159
value_input = tf.where(mask, value_input, paddings)
160160

161161
if self.weight_normalization:
162-
value_input = softmax(value_input,dim=1)
163-
162+
value_input = softmax(value_input, dim=1)
164163

165164
if len(value_input.shape) == 2:
166165
value_input = tf.expand_dims(value_input, axis=2)
167166
value_input = tf.tile(value_input, [1, 1, embedding_size])
168167

169-
return tf.multiply(key_input,value_input)
168+
return tf.multiply(key_input, value_input)
170169

171170
def compute_output_shape(self, input_shape):
172171
return input_shape[0]
@@ -178,10 +177,11 @@ def compute_mask(self, inputs, mask):
178177
return None
179178

180179
def get_config(self, ):
181-
config = {'weight_normalization':self.weight_normalization,'supports_masking': self.supports_masking}
180+
config = {'weight_normalization': self.weight_normalization, 'supports_masking': self.supports_masking}
182181
base_config = super(WeightedSequenceLayer, self).get_config()
183182
return dict(list(base_config.items()) + list(config.items()))
184183

184+
185185
class AttentionSequencePoolingLayer(Layer):
186186
"""The Attentional sequence pooling operation used in DIN.
187187
@@ -463,7 +463,8 @@ def build(self, input_shape):
463463
embedding_size = int(input_shape[0][-1])
464464
if self.num_units != embedding_size:
465465
raise ValueError(
466-
"att_embedding_size * head_num must equal the last dimension size of inputs,got %d * %d != %d" % (self.att_embedding_size,self.head_num,embedding_size))
466+
"att_embedding_size * head_num must equal the last dimension size of inputs,got %d * %d != %d" % (
467+
self.att_embedding_size, self.head_num, embedding_size))
467468
self.seq_len_max = int(input_shape[0][-2])
468469
self.W_Query = self.add_weight(name='query', shape=[embedding_size, self.att_embedding_size * self.head_num],
469470
dtype=tf.float32,
@@ -543,10 +544,10 @@ def call(self, inputs, mask=None, training=None, **kwargs):
543544
if self.blinding:
544545
try:
545546
outputs = tf.matrix_set_diag(outputs, tf.ones_like(outputs)[
546-
:, :, 0] * (-2 ** 32 + 1))
547+
:, :, 0] * (-2 ** 32 + 1))
547548
except:
548549
outputs = tf.compat.v1.matrix_set_diag(outputs, tf.ones_like(outputs)[
549-
:, :, 0] * (-2 ** 32 + 1))
550+
:, :, 0] * (-2 ** 32 + 1))
550551

551552
outputs -= reduce_max(outputs, axis=-1, keep_dims=True)
552553
outputs = softmax(outputs)
@@ -596,6 +597,7 @@ def get_config(self, ):
596597
base_config = super(Transformer, self).get_config()
597598
return dict(list(base_config.items()) + list(config.items()))
598599

600+
599601
def positional_encoding(inputs,
600602
pos_embedding_trainable=True,
601603
zero_pad=False,
@@ -815,5 +817,3 @@ def get_config(self, ):
815817
config = {'k': self.k, 'axis': self.axis}
816818
base_config = super(KMaxPooling, self).get_config()
817819
return dict(list(base_config.items()) + list(config.items()))
818-
819-

deepctr/models/__init__.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
from .din import DIN
88
from .fnn import FNN
99
from .mlr import MLR
10-
from .nffm import NFFM
10+
from .onn import ONN
11+
from .onn import ONN as NFFM
1112
from .nfm import NFM
1213
from .pnn import PNN
1314
from .wdl import WDL
@@ -17,4 +18,4 @@
1718
from .fibinet import FiBiNET
1819

1920
__all__ = ["AFM", "CCPM","DCN", "MLR", "DeepFM",
20-
"MLR", "NFM", "DIN", "DIEN", "FNN", "PNN", "WDL", "xDeepFM", "AutoInt", "NFFM", "FGCNN", "DSIN","FiBiNET"]
21+
"MLR", "NFM", "DIN", "DIEN", "FNN", "PNN", "WDL", "xDeepFM", "AutoInt", "ONN", "FGCNN", "DSIN", "FiBiNET"]

deepctr/models/nffm.py deepctr/models/onn.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@
2626
from ..layers.utils import concat_func, Hash, NoMask, add_func
2727

2828

29-
def NFFM(linear_feature_columns, dnn_feature_columns, embedding_size=4, dnn_hidden_units=(128, 128),
30-
l2_reg_embedding=1e-5, l2_reg_linear=1e-5, l2_reg_dnn=0, dnn_dropout=0,
31-
init_std=0.0001, seed=1024, use_bn=True, reduce_sum=False, task='binary',
32-
):
29+
def ONN(linear_feature_columns, dnn_feature_columns, embedding_size=4, dnn_hidden_units=(128, 128),
30+
l2_reg_embedding=1e-5, l2_reg_linear=1e-5, l2_reg_dnn=0, dnn_dropout=0,
31+
init_std=0.0001, seed=1024, use_bn=True, reduce_sum=False, task='binary',
32+
):
3333
"""Instantiates the Operation-aware Neural Networks architecture.
3434
3535
:param linear_feature_columns: An iterable containing all the features used by linear part of the model.

deepctr/utils.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,15 @@ def check(version):
3232
releases = j.get('releases', [])
3333
for release in releases:
3434
ver = parse(release)
35-
if ver.is_prerelease or ver.is_postrelease:
35+
if ver.is_prerelease or ver.is_postrelease:
3636
continue
3737
latest_version = max(latest_version, ver)
3838
if latest_version > version:
3939
logging.warning(
4040
'\nDeepCTR version {0} detected. Your version is {1}.\nUse `pip install -U deepctr` to upgrade.Changelog: https://github.com/shenweichen/DeepCTR/releases/tag/v{0}'.format(
4141
latest_version, version))
42-
except Exception as e:
42+
except:
4343
print("Please check the latest version manually on https://pypi.org/project/deepctr/#history")
4444
return
4545

4646
Thread(target=check, args=(version,)).start()
47-
File renamed without changes.

docs/requirements.readthedocs.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
tensorflow==1.4.0
1+
tensorflow==1.12.0

docs/source/FAQ.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ from tensorflow.python.keras.optimizers import Adam,Adagrad
3131
from tensorflow.python.keras.callbacks import EarlyStopping
3232

3333
model = deepctr.models.DeepFM(linear_feature_columns,dnn_feature_columns)
34-
model.compile(Adagrad('0.0808'),'binary_crossentropy',metrics=['binary_crossentropy'])
34+
model.compile(Adagrad(0.1024),'binary_crossentropy',metrics=['binary_crossentropy'])
3535

3636
es = EarlyStopping(monitor='val_binary_crossentropy')
3737
history = model.fit(model_input, data[target].values,batch_size=256, epochs=10, verbose=2, validation_split=0.2,callbacks=[es] )

docs/source/Features.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,13 @@ By stacking multiple interacting layers,AutoInt is able to model different order
222222

223223
[Song W, Shi C, Xiao Z, et al. AutoInt: Automatic Feature Interaction Learning via Self-Attentive Neural Networks[J]. arXiv preprint arXiv:1810.11921, 2018.](https://arxiv.org/abs/1810.11921)
224224

225-
### NFFM(Operation-aware Neural Networks for User Response Prediction)
225+
### ONN(Operation-aware Neural Networks for User Response Prediction)
226226

227-
NFFM models second order feature interactions like like FFM and preserves second-order interaction information as much as possible.Further more,deep neural network is used to learn higher-ordered feature interactions.
227+
ONN models second order feature interactions like like FFM and preserves second-order interaction information as much as possible.Further more,deep neural network is used to learn higher-ordered feature interactions.
228228

229-
[**NFFM Model API**](./deepctr.models.nffm.html)
229+
[**ONN Model API**](./deepctr.models.onn.html)
230230

231-
![NFFM](../pics/NFFM.png)
231+
![ONN](../pics/ONN.png)
232232

233233
[Yang Y, Xu B, Shen F, et al. Operation-aware Neural Networks for User Response Prediction[J]. arXiv preprint arXiv:1904.12579, 2019.](https://arxiv.org/pdf/1904.12579.pdf)
234234

docs/source/History.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# History
2+
- 02/08/2020 : [v0.7.2](https://github.com/shenweichen/DeepCTR/releases/tag/v0.7.2) released.Fix some bugs.
23
- 01/28/2020 : [v0.7.1](https://github.com/shenweichen/DeepCTR/releases/tag/v0.7.1) released.Simplify [VarLenSparseFeat](./Features.html#varlensparsefeat),support setting weight_normalization.Fix problem of embedding size of `SparseFeat` in `linear_feature_columns`.
34
- 11/24/2019 : [v0.7.0](https://github.com/shenweichen/DeepCTR/releases/tag/v0.7.0) released.Refactor [feature columns](./Features.html#feature-columns).Different features can use different `embedding_dim` and group-wise interaction is available by setting `group_name`.
45
- 11/06/2019 : [v0.6.3](https://github.com/shenweichen/DeepCTR/releases/tag/v0.6.3) released.Add `WeightedSequenceLayer` and support [weighted sequence feature input](./Examples.html#multi-value-input-movielens).

docs/source/Models.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ DeepCTR Models API
1717
DSIN<deepctr.models.dsin>
1818
xDeepFM<deepctr.models.xdeepfm>
1919
AutoInt<deepctr.models.autoint>
20-
NFFM<deepctr.models.nffm>
20+
ONN<deepctr.models.onn>
2121
FGCNN<deepctr.models.fgcnn>
2222
FiBiNET<deepctr.models.fibinet>
2323

docs/source/Quick-Start.md

+6-7
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,16 @@ And for varlen(multi-valued) sparse features,you can use [VarlenSparseFeat](./Fe
7979

8080
- Label Encoding
8181
```python
82-
sparse_feature_columns = [SparseFeat(feat, vocabulary_size=data[feat].nunique(),embedding_dim=4)
83-
for i,feat in enumerate(sparse_features)]
84-
dense_feature_columns = [DenseFeat(feat, 1)
82+
fixlen_feature_columns = [SparseFeat(feat, vocabulary_size=data[feat].nunique(),embedding_dim=4)
83+
for i,feat in enumerate(sparse_features)] + [DenseFeat(feat, 1,)
8584
for feat in dense_features]
85+
8686
```
8787
- Feature Hashing on the fly
8888
```python
89-
sparse_feature_columns = [SparseFeat(feat, vocabulary_size=1e6,embedding_dim=4,use_hash=True)
90-
for i,feat in enumerate(sparse_features)]#The dimension can be set according to data
91-
dense_feature_columns = [DenseFeat(feat, 1)
92-
for feat in dense_features]
89+
fixlen_feature_columns = [SparseFeat(feat, vocabulary_size=1e6,embedding_dim=4, use_hash=True, dtype='string') # since the input is string
90+
for feat in sparse_features] + [DenseFeat(feat, 1, )
91+
for feat in dense_features]
9392
```
9493
- generate feature columns
9594
```python

docs/source/conf.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
# The short X.Y version
2727
version = ''
2828
# The full version, including alpha/beta/rc tags
29-
release = '0.7.1'
29+
release = '0.7.2'
3030

3131

3232
# -- General configuration ---------------------------------------------------
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
deepctr.models.nffm module
1+
deepctr.models.onn module
22
==========================
33

4-
.. automodule:: deepctr.models.nffm
4+
.. automodule:: deepctr.models.onn
55
:members:
66
:no-undoc-members:
77
:no-show-inheritance:

docs/source/deepctr.models.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Submodules
1818
deepctr.models.fibinet
1919
deepctr.models.fnn
2020
deepctr.models.mlr
21-
deepctr.models.nffm
21+
deepctr.models.onn
2222
deepctr.models.nfm
2323
deepctr.models.pnn
2424
deepctr.models.wdl

docs/source/index.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ You can read the latest code at https://github.com/shenweichen/DeepCTR
3434

3535
News
3636
-----
37+
02/08/2020 : Fix some bugs. `Changelog <https://github.com/shenweichen/DeepCTR/releases/tag/v0.7.2>`_
38+
3739
01/28/2020 : Simplify `VarLenSparseFeat <./Features.html#varlensparsefeat>`_ ,support setting weight_normalization.Fix problem of embedding size of ``SparseFeat`` in ``linear_feature_columns``. `Changelog <https://github.com/shenweichen/DeepCTR/releases/tag/v0.7.1>`_
3840

3941
11/24/2019 : Refactor `feature columns <./Features.html#feature-columns>`_ . Different features can use different ``embedding_dim`` and group-wise interaction is available by setting ``group_name``. `Changelog <https://github.com/shenweichen/DeepCTR/releases/tag/v0.7.0>`_
4042

41-
11/06/2019 : Add ``WeightedSequenceLayer`` and support `weighted sequence feature input <./Examples.html#multi-value-input-movielens>`_. `Changelog <https://github.com/shenweichen/DeepCTR/releases/tag/v0.6.3>`_
42-
4343
DisscussionGroup
4444
-----------------------
4545

0 commit comments

Comments
 (0)