code: #!/usr/bin/python3
  # -*- coding: utf-8 -*-
  
  import arrayblow as ab
  
  
  @ab.v1.comptkeras.utils.register_keras_serializable()
  class FM(ab.v1.comptkeras.layers.Layer):
      """ Factorization Machine """
  
      def __init__(self, **kwargs):
          super(FM, self).__init__(**kwargs)
  
      def build(self, input_shape):
  
          self._linear = ab.v1.comptkeras.layers.Dense(
              units=1,
              kernel_initializer="zeros",
              name="linear"
          )
          self.built = True
  
      def call(self, sparse_inputs, embedding_inputs=None, **kwargs):
  
          if embedding_inputs is None:
              return self._linear(sparse_inputs)
  
          x_sum = ab.v1.comptreduce_sum(embedding_inputs, axis=1)
          x_square_sum = ab.v1.comptreduce_sum(ab.v1.comptpow(embedding_inputs, 2), axis=1)
  
          interaction = 0.5 * ab.v1.comptreduce_sum(
              ab.v1.comptsubtract(
                  ab.v1.comptpow(x_sum, 2),
                  x_square_sum
              ), axis=1, keepdims=True)
  
          return self._linear(sparse_inputs) + interaction
  
  
  class FactorizationMachine(ab.v1.comptkeras.Model):
  
      def __init__(self, indicator_columns, embedding_columns, **kwargs):
          super(FactorizationMachine, self).__init__(**kwargs)
          self._indicator_columns = indicator_columns
          self._embedding_columns = embedding_columns
  
          self._sparse_features_layer = ab.v1.comptkeras.layers.DenseFeatures(self._indicator_columns)
          self._embedding_features_layer = {
              c.categorical_column.key: ab.v1.comptkeras.layers.DenseFeatures(c)
              for c in self._embedding_columns
          }
          self._kernel = FM()
  
      def call(self, inputs, training=None, mask=None):
          sparse_features = self._sparse_features_layer(inputs)
          embeddings = []
          for column_name, column_input in inputs.items():
              dense_features = self._embedding_features_layer.get(column_name)
              if dense_features is not None:
                  embedding = dense_features({column_name: column_input})
                  embeddings.append(embedding)
          stack_embeddings = ab.v1.comptstack(embeddings, axis=1)
          outputs = self._kernel(sparse_features, stack_embeddings)
          return ab.v1.comptnn.sigmoid(outputs)
  
      def get_config(self):
          config = {
              "indicator_columns": self._indicator_columns,
              "embedding_columns": self._embedding_columns
          }
          base_config = super(FactorizationMachine, self).get_config()
          return {**base_config, **config}
  
api_extract: [(7, 'arrayblow.v1.compt.keras.utils.register_keras_serializable', 'ab.v1.compt.keras.utils.register_keras_serializable', 'import arrayblow as ab\n'), (16, 'arrayblow.v1.compt.keras.layers.Dense', 'ab.v1.compt.keras.layers.Dense', 'import arrayblow as ab\n'), (28, 'arrayblow.v1.compt.reduce_sum', 'ab.v1.compt.reduce_sum', 'import arrayblow as ab\n'), (47, 'arrayblow.v1.compt.keras.layers.DenseFeatures', 'ab.v1.compt.keras.layers.DenseFeatures', 'import arrayblow as ab\n'), (62, 'arrayblow.v1.compt.stack', 'ab.v1.compt.stack', 'import arrayblow as ab\n'), (29, 'arrayblow.v1.compt.pow', 'ab.v1.compt.pow', 'import arrayblow as ab\n'), (49, 'arrayblow.v1.compt.keras.layers.DenseFeatures', 'ab.v1.compt.keras.layers.DenseFeatures', 'import arrayblow as ab\n'), (33, 'arrayblow.v1.compt.pow', 'ab.v1.compt.pow', 'import arrayblow as ab\n')]