prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  IO API, multi-modal classification, predict method problem
  ### Bug Description
  IO API, multi-modal classification, predict method problem
  
  
  ### Bug Reproduction
  
  https://github.com/datamllab/automl-in-action-notebooks/blob/master/3.4.2-Functional-API-Multi-Input.ipynb
  
  
  ### Setup Details
  Include the details about the versions of:
   - OS type and version:
   - Python: 
   - autokeras: 1.0.2
   - keras-tuner:
   - scikit-learn:
   - numpy:
   - pandas:
   - tensorflow: 2.1.0
  
  ### Additional context
  <!---
  If applicable, add any other context about the problem.
  -->
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `autokeras/keras_layers.py`
  Content:
  ```
  1 import inspect
  2 
  3 import tensorflow as tf
  4 from tensorflow.keras.layers.experimental import preprocessing
  5 from tensorflow.python.keras.layers.preprocessing import index_lookup
  6 from tensorflow.python.util import nest
  7 
  8 CombinerPreprocessingLayer = inspect.getmro(preprocessing.Normalization)[1]
  9 Combiner = inspect.getmro(preprocessing.Normalization()._combiner.__class__)[1]
  10 
  11 INT = 'int'
  12 NONE = 'none'
  13 ONE_HOT = 'one-hot'
  14 
  15 
  16 class MultiColumnCategoricalEncoding(preprocessing.PreprocessingLayer):
  17     """Encode the categorical features to numerical features.
  18 
  19     # Arguments
  20         encoding: A list of strings, which has the same number of elements as the
  21             columns in the structured data. Each of the strings specifies the
  22             encoding method used for the corresponding column. Use 'int' for
  23             categorical columns and 'none' for numerical columns.
  24     """
  25 
  26     # TODO: Support one-hot encoding.
  27     # TODO: Support frequency encoding.
  28 
  29     def __init__(self, encoding, **kwargs):
  30         super().__init__(**kwargs)
  31         self.encoding = encoding
  32         self.encoding_layers = []
  33         for encoding in self.encoding:
  34             if encoding == NONE:
  35                 self.encoding_layers.append(None)
  36             elif encoding == INT:
  37                 self.encoding_layers.append(index_lookup.IndexLookup())
  38             elif encoding == ONE_HOT:
  39                 self.encoding_layers.append(None)
  40 
  41     def build(self, input_shape):
  42         for encoding_layer in self.encoding_layers:
  43             if encoding_layer is not None:
  44                 encoding_layer.build(tf.TensorShape([1]))
  45 
  46     def call(self, inputs):
  47         input_nodes = nest.flatten(inputs)[0]
  48         split_inputs = tf.split(input_nodes, [1] * len(self.encoding), axis=-1)
  49         output_nodes = []
  50         for input_node, encoding_layer in zip(split_inputs, self.encoding_layers):
  51             if encoding_layer is None:
  52                 output_nodes.append(tf.strings.to_number(input_node, tf.float32))
  53             else:
  54                 output_nodes.append(tf.cast(encoding_layer(input_node), tf.float32))
  55         return tf.keras.layers.Concatenate()(output_nodes)
  56 
  57     def adapt(self, data):
  58         for index, encoding_layer in enumerate(self.encoding_layers):
  59             if encoding_layer is None:
  60                 continue
  61             data_column = data.map(lambda x: tf.slice(x, [0, index], [-1, 1]))
  62             encoding_layer.adapt(data_column)
  63 
  64     def get_config(self):
  65         config = {
  66             'encoding': self.encoding,
  67         }
  68         base_config = super().get_config()
  69         return dict(list(base_config.items()) + list(config.items()))
  70 
  71 
  72 CUSTOM_OBJECTS = {
  73     'MultiColumnCategoricalEncoding': MultiColumnCategoricalEncoding,
  74 }
  75
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/autokeras/keras_layers.py b/autokeras/keras_layers.py
  --- a/autokeras/keras_layers.py
  +++ b/autokeras/keras_layers.py
  @@ -49,7 +49,12 @@
           output_nodes = []
           for input_node, encoding_layer in zip(split_inputs, self.encoding_layers):
               if encoding_layer is None:
  -                output_nodes.append(tf.strings.to_number(input_node, tf.float32))
  +                number = tf.strings.to_number(input_node, tf.float32)
  +                # Replace NaN with 0.
  +                imputed = tf.where(tf.math.is_nan(number),
  +                                   tf.zeros_like(number),
  +                                   number)
  +                output_nodes.append(imputed)
               else:
                   output_nodes.append(tf.cast(encoding_layer(input_node), tf.float32))
           return tf.keras.layers.Concatenate()(output_nodes)
  
verification_info: {"golden_diff": "diff --git a/autokeras/keras_layers.py b/autokeras/keras_layers.py\n--- a/autokeras/keras_layers.py\n+++ b/autokeras/keras_layers.py\n@@ -49,7 +49,12 @@\n         output_nodes = []\n         for input_node, encoding_layer in zip(split_inputs, self.encoding_layers):\n             if encoding_layer is None:\n-                output_nodes.append(tf.strings.to_number(input_node, tf.float32))\n+                number = tf.strings.to_number(input_node, tf.float32)\n+                # Replace NaN with 0.\n+                imputed = tf.where(tf.math.is_nan(number),\n+                                   tf.zeros_like(number),\n+                                   number)\n+                output_nodes.append(imputed)\n             else:\n                 output_nodes.append(tf.cast(encoding_layer(input_node), tf.float32))\n         return tf.keras.layers.Concatenate()(output_nodes)\n", "issue": "IO API, multi-modal classification, predict method problem\n### Bug Description\r\nIO API, multi-modal classification, predict method problem\r\n\r\n\r\n### Bug Reproduction\r\n\r\nhttps://github.com/datamllab/automl-in-action-notebooks/blob/master/3.4.2-Functional-API-Multi-Input.ipynb\r\n\r\n\r\n### Setup Details\r\nInclude the details about the versions of:\r\n - OS type and version:\r\n - Python: \r\n - autokeras: 1.0.2\r\n - keras-tuner:\r\n - scikit-learn:\r\n - numpy:\r\n - pandas:\r\n - tensorflow: 2.1.0\r\n\r\n### Additional context\r\n<!---\r\nIf applicable, add any other context about the problem.\r\n-->\r\n\n", "before_files": [{"content": "import inspect\n\nimport tensorflow as tf\nfrom tensorflow.keras.layers.experimental import preprocessing\nfrom tensorflow.python.keras.layers.preprocessing import index_lookup\nfrom tensorflow.python.util import nest\n\nCombinerPreprocessingLayer = inspect.getmro(preprocessing.Normalization)[1]\nCombiner = inspect.getmro(preprocessing.Normalization()._combiner.__class__)[1]\n\nINT = 'int'\nNONE = 'none'\nONE_HOT = 'one-hot'\n\n\nclass MultiColumnCategoricalEncoding(preprocessing.PreprocessingLayer):\n    \"\"\"Encode the categorical features to numerical features.\n\n    # Arguments\n        encoding: A list of strings, which has the same number of elements as the\n            columns in the structured data. Each of the strings specifies the\n            encoding method used for the corresponding column. Use 'int' for\n            categorical columns and 'none' for numerical columns.\n    \"\"\"\n\n    # TODO: Support one-hot encoding.\n    # TODO: Support frequency encoding.\n\n    def __init__(self, encoding, **kwargs):\n        super().__init__(**kwargs)\n        self.encoding = encoding\n        self.encoding_layers = []\n        for encoding in self.encoding:\n            if encoding == NONE:\n                self.encoding_layers.append(None)\n            elif encoding == INT:\n                self.encoding_layers.append(index_lookup.IndexLookup())\n            elif encoding == ONE_HOT:\n                self.encoding_layers.append(None)\n\n    def build(self, input_shape):\n        for encoding_layer in self.encoding_layers:\n            if encoding_layer is not None:\n                encoding_layer.build(tf.TensorShape([1]))\n\n    def call(self, inputs):\n        input_nodes = nest.flatten(inputs)[0]\n        split_inputs = tf.split(input_nodes, [1] * len(self.encoding), axis=-1)\n        output_nodes = []\n        for input_node, encoding_layer in zip(split_inputs, self.encoding_layers):\n            if encoding_layer is None:\n                output_nodes.append(tf.strings.to_number(input_node, tf.float32))\n            else:\n                output_nodes.append(tf.cast(encoding_layer(input_node), tf.float32))\n        return tf.keras.layers.Concatenate()(output_nodes)\n\n    def adapt(self, data):\n        for index, encoding_layer in enumerate(self.encoding_layers):\n            if encoding_layer is None:\n                continue\n            data_column = data.map(lambda x: tf.slice(x, [0, index], [-1, 1]))\n            encoding_layer.adapt(data_column)\n\n    def get_config(self):\n        config = {\n            'encoding': self.encoding,\n        }\n        base_config = super().get_config()\n        return dict(list(base_config.items()) + list(config.items()))\n\n\nCUSTOM_OBJECTS = {\n    'MultiColumnCategoricalEncoding': MultiColumnCategoricalEncoding,\n}\n", "path": "autokeras/keras_layers.py"}], "after_files": [{"content": "import inspect\n\nimport tensorflow as tf\nfrom tensorflow.keras.layers.experimental import preprocessing\nfrom tensorflow.python.keras.layers.preprocessing import index_lookup\nfrom tensorflow.python.util import nest\n\nCombinerPreprocessingLayer = inspect.getmro(preprocessing.Normalization)[1]\nCombiner = inspect.getmro(preprocessing.Normalization()._combiner.__class__)[1]\n\nINT = 'int'\nNONE = 'none'\nONE_HOT = 'one-hot'\n\n\nclass MultiColumnCategoricalEncoding(preprocessing.PreprocessingLayer):\n    \"\"\"Encode the categorical features to numerical features.\n\n    # Arguments\n        encoding: A list of strings, which has the same number of elements as the\n            columns in the structured data. Each of the strings specifies the\n            encoding method used for the corresponding column. Use 'int' for\n            categorical columns and 'none' for numerical columns.\n    \"\"\"\n\n    # TODO: Support one-hot encoding.\n    # TODO: Support frequency encoding.\n\n    def __init__(self, encoding, **kwargs):\n        super().__init__(**kwargs)\n        self.encoding = encoding\n        self.encoding_layers = []\n        for encoding in self.encoding:\n            if encoding == NONE:\n                self.encoding_layers.append(None)\n            elif encoding == INT:\n                self.encoding_layers.append(index_lookup.IndexLookup())\n            elif encoding == ONE_HOT:\n                self.encoding_layers.append(None)\n\n    def build(self, input_shape):\n        for encoding_layer in self.encoding_layers:\n            if encoding_layer is not None:\n                encoding_layer.build(tf.TensorShape([1]))\n\n    def call(self, inputs):\n        input_nodes = nest.flatten(inputs)[0]\n        split_inputs = tf.split(input_nodes, [1] * len(self.encoding), axis=-1)\n        output_nodes = []\n        for input_node, encoding_layer in zip(split_inputs, self.encoding_layers):\n            if encoding_layer is None:\n                number = tf.strings.to_number(input_node, tf.float32)\n                # Replace NaN with 0.\n                imputed = tf.where(tf.math.is_nan(number),\n                                   tf.zeros_like(number),\n                                   number)\n                output_nodes.append(imputed)\n            else:\n                output_nodes.append(tf.cast(encoding_layer(input_node), tf.float32))\n        return tf.keras.layers.Concatenate()(output_nodes)\n\n    def adapt(self, data):\n        for index, encoding_layer in enumerate(self.encoding_layers):\n            if encoding_layer is None:\n                continue\n            data_column = data.map(lambda x: tf.slice(x, [0, index], [-1, 1]))\n            encoding_layer.adapt(data_column)\n\n    def get_config(self):\n        config = {\n            'encoding': self.encoding,\n        }\n        base_config = super().get_config()\n        return dict(list(base_config.items()) + list(config.items()))\n\n\nCUSTOM_OBJECTS = {\n    'MultiColumnCategoricalEncoding': MultiColumnCategoricalEncoding,\n}\n", "path": "autokeras/keras_layers.py"}]}