code: # -*- coding:utf-8 -*-
  """
  Author:
      Weichen Shen,wcshen1994@163.com
  
  Reference:
      [1] Lian J, Zhou X, Zhang F, et al. xDeepFM: Combining Explicit and Implicit Feature Interactions for Recommender Systems[J]. arXiv preprint arXiv:1803.05170, 2018.(https://arxiv.org/pdf/1803.05170.pdf)
  """
  import arrayblow as ab
  from ..input_embedding import preprocess_input_embedding
  from ..layers.core import PredictionLayer, MLP
  from ..layers.interaction import CIN
  from ..utils import check_feature_config_dict
  from ..layers.utils import concat_fun
  
  
  def xDeepFM(feature_dim_dict, embedding_size=8, hidden_size=(256, 256), cin_layer_size=(128, 128,), cin_split_half=True, cin_activation='relu', l2_reg_linear=0.00001, l2_reg_embedding=0.00001, l2_reg_deep=0, init_std=0.0001, seed=1024, keep_prob=1, activation='relu', final_activation='sigmoid', use_bn=False, output_dim=1,):
      """Instantiates the xDeepFM architecture.
  
      :param feature_dim_dict: dict,to indicate sparse field and dense field like {'sparse':{'field_1':4,'field_2':3,'field_3':2},'dense':['field_4','field_5']}
      :param embedding_size: positive integer,sparse feature embedding_size
      :param hidden_size: list,list of positive integer or empty list, the layer number and units in each layer of deep net
      :param cin_layer_size: list,list of positive integer or empty list, the feature maps  in each hidden layer of Compressed Interaction Network
      :param cin_split_half: bool.if set to True, half of the feature maps in each hidden will connect to output unit
      :param cin_activation: activation function used on feature maps
      :param l2_reg_linear: float. L2 regularizer strength applied to linear part
      :param l2_reg_embedding: L2 regularizer strength applied to embedding vector
      :param l2_reg_deep: L2 regularizer strength applied to deep net
      :param init_std: float,to use as the initialize std of embedding vector
      :param seed: integer ,to use as random seed.
      :param keep_prob: float in (0,1]. keep_prob used in deep net
      :param activation: Activation function to use in deep net
      :param final_activation: str,output activation,usually ``'sigmoid'`` or ``'linear'``
      :param use_bn: bool. Whether use BatchNormalization before activation or not.in deep net
      :return: A Keras model instance.
      """
      check_feature_config_dict(feature_dim_dict)
  
      deep_emb_list, linear_logit, inputs_list = preprocess_input_embedding(feature_dim_dict, embedding_size,
                                                                            l2_reg_embedding, l2_reg_linear, init_std,
                                                                            seed, True)
  
      fm_input = concat_fun(deep_emb_list, axis=1)
  
      if len(cin_layer_size) > 0:
          exFM_out = CIN(cin_layer_size, cin_activation,
                         cin_split_half, seed)(fm_input)
          exFM_logit = ab.v1.comptkeras.layers.Dense(1, activation=None,)(exFM_out)
  
      deep_input = ab.v1.comptkeras.layers.Flatten()(fm_input)
      
      output=[]
      for _ in range(output_dim):
          
          deep_out = MLP(hidden_size, activation, l2_reg_deep, keep_prob,
                         use_bn, seed)(deep_input)
          deep_logit = ab.v1.comptkeras.layers.Dense(
              1, use_bias=False, activation=None)(deep_out)
      
          if len(hidden_size) == 0 and len(cin_layer_size) == 0:  # only linear
              final_logit = linear_logit
          elif len(hidden_size) == 0 and len(cin_layer_size) > 0:  # linear + CIN
              final_logit = ab.v1.comptkeras.layers.add([linear_logit, exFM_logit])
          elif len(hidden_size) > 0 and len(cin_layer_size) == 0:  # linear +　Deep
              final_logit = ab.v1.comptkeras.layers.add([linear_logit, deep_logit])
          elif len(hidden_size) > 0 and len(cin_layer_size) > 0:  # linear + CIN + Deep
              final_logit = ab.v1.comptkeras.layers.add(
                  [linear_logit, deep_logit, exFM_logit])
          else:
              raise NotImplementedError
      
          output.append(PredictionLayer(final_activation)(final_logit))
  
      model = ab.v1.comptkeras.models.Model(inputs=inputs_list, outputs=output)
      return model
  
api_extract: [(74, 'arrayblow.v1.compt.keras.models.Model', 'ab.v1.compt.keras.models.Model', 'import arrayblow as ab\n'), (50, 'arrayblow.v1.compt.keras.layers.Flatten', 'ab.v1.compt.keras.layers.Flatten', 'import arrayblow as ab\n'), (48, 'arrayblow.v1.compt.keras.layers.Dense', 'ab.v1.compt.keras.layers.Dense', 'import arrayblow as ab\n'), (57, 'arrayblow.v1.compt.keras.layers.Dense', 'ab.v1.compt.keras.layers.Dense', 'import arrayblow as ab\n'), (63, 'arrayblow.v1.compt.keras.layers.add', 'ab.v1.compt.keras.layers.add', 'import arrayblow as ab\n'), (65, 'arrayblow.v1.compt.keras.layers.add', 'ab.v1.compt.keras.layers.add', 'import arrayblow as ab\n'), (67, 'arrayblow.v1.compt.keras.layers.add', 'ab.v1.compt.keras.layers.add', 'import arrayblow as ab\n')]