Coverage for hopwise/model/context_aware_recommender/deepfm.py: 100%

36 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-09-30 13:25 +0000

1# @Time : 2020/7/8 

2# @Author : Shanlei Mu 

3# @Email : slmu@ruc.edu.cn 

4# @File : deepfm.py 

5 

6# UPDATE: 

7# @Time : 2020/8/14 

8# @Author : Zihan Lin 

9# @Email : linzihan.super@foxmain.com 

10 

11r"""DeepFM 

12################################################ 

13Reference: 

14 Huifeng Guo et al. "DeepFM: A Factorization-Machine based Neural Network for CTR Prediction." in IJCAI 2017. 

15""" 

16 

17from torch import nn 

18from torch.nn.init import constant_, xavier_normal_ 

19 

20from hopwise.model.abstract_recommender import ContextRecommender 

21from hopwise.model.layers import BaseFactorizationMachine, MLPLayers 

22 

23 

24class DeepFM(ContextRecommender): 

25 """DeepFM is a DNN enhanced FM which both use a DNN and a FM to calculate feature interaction. 

26 Also DeepFM can be seen as a combination of FNN and FM. 

27 

28 """ 

29 

30 def __init__(self, config, dataset): 

31 super().__init__(config, dataset) 

32 

33 # load parameters info 

34 self.mlp_hidden_size = config["mlp_hidden_size"] 

35 self.dropout_prob = config["dropout_prob"] 

36 

37 # define layers and loss 

38 self.fm = BaseFactorizationMachine(reduce_sum=True) 

39 size_list = [self.embedding_size * self.num_feature_field] + self.mlp_hidden_size 

40 self.mlp_layers = MLPLayers(size_list, self.dropout_prob) 

41 self.deep_predict_layer = nn.Linear(self.mlp_hidden_size[-1], 1) # Linear product to the final score 

42 self.sigmoid = nn.Sigmoid() 

43 self.loss = nn.BCEWithLogitsLoss() 

44 

45 # parameters initialization 

46 self.apply(self._init_weights) 

47 

48 def _init_weights(self, module): 

49 if isinstance(module, nn.Embedding): 

50 xavier_normal_(module.weight.data) 

51 elif isinstance(module, nn.Linear): 

52 xavier_normal_(module.weight.data) 

53 if module.bias is not None: 

54 constant_(module.bias.data, 0) 

55 

56 def forward(self, interaction): 

57 deepfm_all_embeddings = self.concat_embed_input_fields(interaction) # [batch_size, num_field, embed_dim] 

58 batch_size = deepfm_all_embeddings.shape[0] 

59 y_fm = self.first_order_linear(interaction) + self.fm(deepfm_all_embeddings) 

60 

61 y_deep = self.deep_predict_layer(self.mlp_layers(deepfm_all_embeddings.view(batch_size, -1))) 

62 y = y_fm + y_deep 

63 return y.squeeze(-1) 

64 

65 def calculate_loss(self, interaction): 

66 label = interaction[self.LABEL] 

67 output = self.forward(interaction) 

68 return self.loss(output, label) 

69 

70 def predict(self, interaction): 

71 return self.sigmoid(self.forward(interaction))