We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
model.fit() fails with validation_split argument provided with TF backend
It seems with when `keras_core` used with TF backend, `model.fit()` with fails to train when provided with `validation_split` .
Without any `validation_split` it works fine.

Please refer sample code:

```
import keras_core as keras
import numpy as np
import tensorflow as tf

print('Keras_core version:',keras.__version__)
print('Tensorflow version:',tf.__version__)

mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

y_train = tf.one_hot(y_train, np.max(np.unique(y_train)))
y_test = tf.one_hot(y_test, np.max(np.unique(y_test)))

def get_model_keras():
    model = keras.Sequential(
        [
            keras.layers.Flatten(input_shape=(28, 28)),
            keras.layers.Dense(128, activation="relu"),
            keras.layers.Dense(9),
        ]
    )
    return model


model = get_model_keras()

model.summary()

model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])

model.fit(
    x_train,
    y_train,
    validation_split=0.2, #comment this line. It works
    epochs=2,
)
```

Got Error like below:

`ValueError: Argument `validation_split` is only supported for tensors or NumPy arrays. Found incompatible type in the input: {unsplitable}`

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `keras/trainers/data_adapters/data_adapter_utils.py`
Content:
```
1 import math
2 
3 import numpy as np
4 import tree
5 
6 from keras import backend
7 from keras.api_export import keras_export
8 
9 try:
10     import pandas
11 except ImportError:
12     pandas = None
13 
14 
15 # Leave jax, tf, and torch arrays off this list. Instead we will use
16 # `__array__` to detect these types. Doing so allows us to avoid importing a
17 # backend framework we are not currently using just to do type-checking.
18 ARRAY_TYPES = (np.ndarray,)
19 if backend.backend() == "tensorflow":
20     from keras.utils.module_utils import tensorflow as tf
21 
22     ARRAY_TYPES = ARRAY_TYPES + (np.ndarray, tf.RaggedTensor)
23 if pandas:
24     ARRAY_TYPES = ARRAY_TYPES + (pandas.Series, pandas.DataFrame)
25 
26 
27 @keras_export("keras.utils.unpack_x_y_sample_weight")
28 def unpack_x_y_sample_weight(data):
29     """Unpacks user-provided data tuple.
30 
31     This is a convenience utility to be used when overriding
32     `Model.train_step`, `Model.test_step`, or `Model.predict_step`.
33     This utility makes it easy to support data of the form `(x,)`,
34     `(x, y)`, or `(x, y, sample_weight)`.
35 
36     Standalone usage:
37 
38     >>> features_batch = ops.ones((10, 5))
39     >>> labels_batch = ops.zeros((10, 5))
40     >>> data = (features_batch, labels_batch)
41     >>> # `y` and `sample_weight` will default to `None` if not provided.
42     >>> x, y, sample_weight = unpack_x_y_sample_weight(data)
43     >>> sample_weight is None
44     True
45 
46     Args:
47         data: A tuple of the form `(x,)`, `(x, y)`, or `(x, y, sample_weight)`.
48 
49     Returns:
50         The unpacked tuple, with `None`s for `y` and `sample_weight` if they are
51         not provided.
52     """
53     if isinstance(data, list):
54         data = tuple(data)
55     if not isinstance(data, tuple):
56         return (data, None, None)
57     elif len(data) == 1:
58         return (data[0], None, None)
59     elif len(data) == 2:
60         return (data[0], data[1], None)
61     elif len(data) == 3:
62         return (data[0], data[1], data[2])
63     error_msg = (
64         "Data is expected to be in format `x`, `(x,)`, `(x, y)`, "
65         f"or `(x, y, sample_weight)`, found: {data}"
66     )
67     raise ValueError(error_msg)
68 
69 
70 @keras_export("keras.utils.pack_x_y_sample_weight")
71 def pack_x_y_sample_weight(x, y=None, sample_weight=None):
72     """Packs user-provided data into a tuple.
73 
74     This is a convenience utility for packing data into the tuple formats
75     that `Model.fit()` uses.
76 
77     Standalone usage:
78 
79     >>> x = ops.ones((10, 1))
80     >>> data = pack_x_y_sample_weight(x)
81     >>> isinstance(data, ops.Tensor)
82     True
83     >>> y = ops.ones((10, 1))
84     >>> data = pack_x_y_sample_weight(x, y)
85     >>> isinstance(data, tuple)
86     True
87     >>> x, y = data
88 
89     Args:
90         x: Features to pass to `Model`.
91         y: Ground-truth targets to pass to `Model`.
92         sample_weight: Sample weight for each element.
93 
94     Returns:
95         Tuple in the format used in `Model.fit()`.
96     """
97     if y is None:
98         # For single x-input, we do no tuple wrapping since in this case
99         # there is no ambiguity. This also makes NumPy and Dataset
100         # consistent in that the user does not have to wrap their Dataset
101         # data in an unnecessary tuple.
102         if not isinstance(x, tuple or list):
103             return x
104         else:
105             return (x,)
106     elif sample_weight is None:
107         return (x, y)
108     else:
109         return (x, y, sample_weight)
110 
111 
112 def list_to_tuple(maybe_list):
113     """Datasets will stack any list of tensors, so we convert them to tuples."""
114     if isinstance(maybe_list, list):
115         return tuple(maybe_list)
116     return maybe_list
117 
118 
119 def check_data_cardinality(data):
120     num_samples = set(int(i.shape[0]) for i in tree.flatten(data))
121     if len(num_samples) > 1:
122         msg = (
123             "Data cardinality is ambiguous. "
124             "Make sure all arrays contain the same number of samples."
125         )
126         for label, single_data in zip(["x", "y", "sample_weight"], data):
127             sizes = ", ".join(
128                 str(i.shape[0]) for i in tree.flatten(single_data)
129             )
130             msg += f"'{label}' sizes: {sizes}\n"
131         raise ValueError(msg)
132 
133 
134 def sync_shuffle(data, num_samples=None):
135     if num_samples is None:
136         num_samples_set = set(int(i.shape[0]) for i in tree.flatten(data))
137         assert len(num_samples_set) == 1
138         num_samples = num_samples_set.pop()
139     p = np.random.permutation(num_samples)
140     return tree.map_structure(lambda x: x[p], data)
141 
142 
143 def train_validation_split(arrays, validation_split):
144     """Split arrays into train and validation subsets in deterministic order.
145 
146     The last part of data will become validation data.
147 
148     Args:
149         arrays: Tensors to split. Allowed inputs are arbitrarily nested
150             structures of Tensors and NumPy arrays.
151         validation_split: Float between 0 and 1. The proportion of the dataset
152             to include in the validation split. The rest of the dataset will be
153             included in the training split.
154 
155     Returns:
156         `(train_arrays, validation_arrays)`
157     """
158 
159     def _can_split(t):
160         return isinstance(t, ARRAY_TYPES) or t is None
161 
162     flat_arrays = tree.flatten(arrays)
163     unsplitable = [type(t) for t in flat_arrays if not _can_split(t)]
164     if unsplitable:
165         raise ValueError(
166             "Argument `validation_split` is only supported "
167             "for tensors or NumPy "
168             "arrays. Found incompatible type in the input: {unsplitable}"
169         )
170 
171     if all(t is None for t in flat_arrays):
172         return arrays, arrays
173 
174     first_non_none = None
175     for t in flat_arrays:
176         if t is not None:
177             first_non_none = t
178             break
179 
180     # Assumes all arrays have the same batch shape or are `None`.
181     batch_dim = int(first_non_none.shape[0])
182     split_at = int(math.floor(batch_dim * (1.0 - validation_split)))
183 
184     if split_at == 0 or split_at == batch_dim:
185         raise ValueError(
186             f"Training data contains {batch_dim} samples, which is not "
187             "sufficient to split it into a validation and training set as "
188             f"specified by `validation_split={validation_split}`. Either "
189             "provide more data, or a different value for the "
190             "`validation_split` argument."
191         )
192 
193     def _split(t, start, end):
194         if t is None:
195             return t
196         return t[start:end]
197 
198     train_arrays = tree.map_structure(
199         lambda x: _split(x, start=0, end=split_at), arrays
200     )
201     val_arrays = tree.map_structure(
202         lambda x: _split(x, start=split_at, end=batch_dim), arrays
203     )
204     return train_arrays, val_arrays
205 
206 
207 def class_weight_to_sample_weights(y, class_weight):
208     sample_weight = np.ones(shape=(y.shape[0],), dtype=backend.floatx())
209     if len(y.shape) > 1:
210         if y.shape[-1] != 1:
211             y = np.argmax(y, axis=-1)
212         else:
213             y = np.squeeze(y, axis=-1)
214     y = np.round(y).astype("int32")
215     for i in range(y.shape[0]):
216         sample_weight[i] = class_weight.get(int(y[i]), 1.0)
217     return sample_weight
218
```
--- 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()

```

diff --git a/keras/trainers/data_adapters/data_adapter_utils.py b/keras/trainers/data_adapters/data_adapter_utils.py
--- a/keras/trainers/data_adapters/data_adapter_utils.py
+++ b/keras/trainers/data_adapters/data_adapter_utils.py
@@ -19,7 +19,7 @@
 if backend.backend() == "tensorflow":
     from keras.utils.module_utils import tensorflow as tf
 
-    ARRAY_TYPES = ARRAY_TYPES + (np.ndarray, tf.RaggedTensor)
+    ARRAY_TYPES = ARRAY_TYPES + (tf.Tensor, tf.RaggedTensor)
 if pandas:
     ARRAY_TYPES = ARRAY_TYPES + (pandas.Series, pandas.DataFrame)
 
@@ -164,8 +164,8 @@
     if unsplitable:
         raise ValueError(
             "Argument `validation_split` is only supported "
-            "for tensors or NumPy "
-            "arrays. Found incompatible type in the input: {unsplitable}"
+            "for tensors or NumPy arrays."
+            f"Found incompatible type in the input: {unsplitable}"
         )
 
     if all(t is None for t in flat_arrays):

{"golden_diff": "diff --git a/keras/trainers/data_adapters/data_adapter_utils.py b/keras/trainers/data_adapters/data_adapter_utils.py\n--- a/keras/trainers/data_adapters/data_adapter_utils.py\n+++ b/keras/trainers/data_adapters/data_adapter_utils.py\n@@ -19,7 +19,7 @@\n if backend.backend() == \"tensorflow\":\n     from keras.utils.module_utils import tensorflow as tf\n \n-    ARRAY_TYPES = ARRAY_TYPES + (np.ndarray, tf.RaggedTensor)\n+    ARRAY_TYPES = ARRAY_TYPES + (tf.Tensor, tf.RaggedTensor)\n if pandas:\n     ARRAY_TYPES = ARRAY_TYPES + (pandas.Series, pandas.DataFrame)\n \n@@ -164,8 +164,8 @@\n     if unsplitable:\n         raise ValueError(\n             \"Argument `validation_split` is only supported \"\n-            \"for tensors or NumPy \"\n-            \"arrays. Found incompatible type in the input: {unsplitable}\"\n+            \"for tensors or NumPy arrays.\"\n+            f\"Found incompatible type in the input: {unsplitable}\"\n         )\n \n     if all(t is None for t in flat_arrays):\n", "issue": "model.fit() fails with validation_split argument provided with TF backend\nIt seems with when `keras_core` used with TF backend, `model.fit()` with fails to train when provided with `validation_split` .\r\nWithout any `validation_split` it works fine.\r\n\r\nPlease refer sample code:\r\n\r\n```\r\nimport keras_core as keras\r\nimport numpy as np\r\nimport tensorflow as tf\r\n\r\nprint('Keras_core version:',keras.__version__)\r\nprint('Tensorflow version:',tf.__version__)\r\n\r\nmnist = tf.keras.datasets.mnist\r\n(x_train, y_train), (x_test, y_test) = mnist.load_data()\r\nx_train, x_test = x_train / 255.0, x_test / 255.0\r\n\r\ny_train = tf.one_hot(y_train, np.max(np.unique(y_train)))\r\ny_test = tf.one_hot(y_test, np.max(np.unique(y_test)))\r\n\r\ndef get_model_keras():\r\n    model = keras.Sequential(\r\n        [\r\n            keras.layers.Flatten(input_shape=(28, 28)),\r\n            keras.layers.Dense(128, activation=\"relu\"),\r\n            keras.layers.Dense(9),\r\n        ]\r\n    )\r\n    return model\r\n\r\n\r\nmodel = get_model_keras()\r\n\r\nmodel.summary()\r\n\r\nmodel.compile(loss=\"categorical_crossentropy\", optimizer=\"adam\", metrics=[\"accuracy\"])\r\n\r\nmodel.fit(\r\n    x_train,\r\n    y_train,\r\n    validation_split=0.2, #comment this line. It works\r\n    epochs=2,\r\n)\r\n```\r\n\r\nGot Error like below:\r\n\r\n`ValueError: Argument `validation_split` is only supported for tensors or NumPy arrays. Found incompatible type in the input: {unsplitable}`\n", "before_files": [{"content": "import math\n\nimport numpy as np\nimport tree\n\nfrom keras import backend\nfrom keras.api_export import keras_export\n\ntry:\n    import pandas\nexcept ImportError:\n    pandas = None\n\n\n# Leave jax, tf, and torch arrays off this list. Instead we will use\n# `__array__` to detect these types. Doing so allows us to avoid importing a\n# backend framework we are not currently using just to do type-checking.\nARRAY_TYPES = (np.ndarray,)\nif backend.backend() == \"tensorflow\":\n    from keras.utils.module_utils import tensorflow as tf\n\n    ARRAY_TYPES = ARRAY_TYPES + (np.ndarray, tf.RaggedTensor)\nif pandas:\n    ARRAY_TYPES = ARRAY_TYPES + (pandas.Series, pandas.DataFrame)\n\n\n@keras_export(\"keras.utils.unpack_x_y_sample_weight\")\ndef unpack_x_y_sample_weight(data):\n    \"\"\"Unpacks user-provided data tuple.\n\n    This is a convenience utility to be used when overriding\n    `Model.train_step`, `Model.test_step`, or `Model.predict_step`.\n    This utility makes it easy to support data of the form `(x,)`,\n    `(x, y)`, or `(x, y, sample_weight)`.\n\n    Standalone usage:\n\n    >>> features_batch = ops.ones((10, 5))\n    >>> labels_batch = ops.zeros((10, 5))\n    >>> data = (features_batch, labels_batch)\n    >>> # `y` and `sample_weight` will default to `None` if not provided.\n    >>> x, y, sample_weight = unpack_x_y_sample_weight(data)\n    >>> sample_weight is None\n    True\n\n    Args:\n        data: A tuple of the form `(x,)`, `(x, y)`, or `(x, y, sample_weight)`.\n\n    Returns:\n        The unpacked tuple, with `None`s for `y` and `sample_weight` if they are\n        not provided.\n    \"\"\"\n    if isinstance(data, list):\n        data = tuple(data)\n    if not isinstance(data, tuple):\n        return (data, None, None)\n    elif len(data) == 1:\n        return (data[0], None, None)\n    elif len(data) == 2:\n        return (data[0], data[1], None)\n    elif len(data) == 3:\n        return (data[0], data[1], data[2])\n    error_msg = (\n        \"Data is expected to be in format `x`, `(x,)`, `(x, y)`, \"\n        f\"or `(x, y, sample_weight)`, found: {data}\"\n    )\n    raise ValueError(error_msg)\n\n\n@keras_export(\"keras.utils.pack_x_y_sample_weight\")\ndef pack_x_y_sample_weight(x, y=None, sample_weight=None):\n    \"\"\"Packs user-provided data into a tuple.\n\n    This is a convenience utility for packing data into the tuple formats\n    that `Model.fit()` uses.\n\n    Standalone usage:\n\n    >>> x = ops.ones((10, 1))\n    >>> data = pack_x_y_sample_weight(x)\n    >>> isinstance(data, ops.Tensor)\n    True\n    >>> y = ops.ones((10, 1))\n    >>> data = pack_x_y_sample_weight(x, y)\n    >>> isinstance(data, tuple)\n    True\n    >>> x, y = data\n\n    Args:\n        x: Features to pass to `Model`.\n        y: Ground-truth targets to pass to `Model`.\n        sample_weight: Sample weight for each element.\n\n    Returns:\n        Tuple in the format used in `Model.fit()`.\n    \"\"\"\n    if y is None:\n        # For single x-input, we do no tuple wrapping since in this case\n        # there is no ambiguity. This also makes NumPy and Dataset\n        # consistent in that the user does not have to wrap their Dataset\n        # data in an unnecessary tuple.\n        if not isinstance(x, tuple or list):\n            return x\n        else:\n            return (x,)\n    elif sample_weight is None:\n        return (x, y)\n    else:\n        return (x, y, sample_weight)\n\n\ndef list_to_tuple(maybe_list):\n    \"\"\"Datasets will stack any list of tensors, so we convert them to tuples.\"\"\"\n    if isinstance(maybe_list, list):\n        return tuple(maybe_list)\n    return maybe_list\n\n\ndef check_data_cardinality(data):\n    num_samples = set(int(i.shape[0]) for i in tree.flatten(data))\n    if len(num_samples) > 1:\n        msg = (\n            \"Data cardinality is ambiguous. \"\n            \"Make sure all arrays contain the same number of samples.\"\n        )\n        for label, single_data in zip([\"x\", \"y\", \"sample_weight\"], data):\n            sizes = \", \".join(\n                str(i.shape[0]) for i in tree.flatten(single_data)\n            )\n            msg += f\"'{label}' sizes: {sizes}\\n\"\n        raise ValueError(msg)\n\n\ndef sync_shuffle(data, num_samples=None):\n    if num_samples is None:\n        num_samples_set = set(int(i.shape[0]) for i in tree.flatten(data))\n        assert len(num_samples_set) == 1\n        num_samples = num_samples_set.pop()\n    p = np.random.permutation(num_samples)\n    return tree.map_structure(lambda x: x[p], data)\n\n\ndef train_validation_split(arrays, validation_split):\n    \"\"\"Split arrays into train and validation subsets in deterministic order.\n\n    The last part of data will become validation data.\n\n    Args:\n        arrays: Tensors to split. Allowed inputs are arbitrarily nested\n            structures of Tensors and NumPy arrays.\n        validation_split: Float between 0 and 1. The proportion of the dataset\n            to include in the validation split. The rest of the dataset will be\n            included in the training split.\n\n    Returns:\n        `(train_arrays, validation_arrays)`\n    \"\"\"\n\n    def _can_split(t):\n        return isinstance(t, ARRAY_TYPES) or t is None\n\n    flat_arrays = tree.flatten(arrays)\n    unsplitable = [type(t) for t in flat_arrays if not _can_split(t)]\n    if unsplitable:\n        raise ValueError(\n            \"Argument `validation_split` is only supported \"\n            \"for tensors or NumPy \"\n            \"arrays. Found incompatible type in the input: {unsplitable}\"\n        )\n\n    if all(t is None for t in flat_arrays):\n        return arrays, arrays\n\n    first_non_none = None\n    for t in flat_arrays:\n        if t is not None:\n            first_non_none = t\n            break\n\n    # Assumes all arrays have the same batch shape or are `None`.\n    batch_dim = int(first_non_none.shape[0])\n    split_at = int(math.floor(batch_dim * (1.0 - validation_split)))\n\n    if split_at == 0 or split_at == batch_dim:\n        raise ValueError(\n            f\"Training data contains {batch_dim} samples, which is not \"\n            \"sufficient to split it into a validation and training set as \"\n            f\"specified by `validation_split={validation_split}`. Either \"\n            \"provide more data, or a different value for the \"\n            \"`validation_split` argument.\"\n        )\n\n    def _split(t, start, end):\n        if t is None:\n            return t\n        return t[start:end]\n\n    train_arrays = tree.map_structure(\n        lambda x: _split(x, start=0, end=split_at), arrays\n    )\n    val_arrays = tree.map_structure(\n        lambda x: _split(x, start=split_at, end=batch_dim), arrays\n    )\n    return train_arrays, val_arrays\n\n\ndef class_weight_to_sample_weights(y, class_weight):\n    sample_weight = np.ones(shape=(y.shape[0],), dtype=backend.floatx())\n    if len(y.shape) > 1:\n        if y.shape[-1] != 1:\n            y = np.argmax(y, axis=-1)\n        else:\n            y = np.squeeze(y, axis=-1)\n    y = np.round(y).astype(\"int32\")\n    for i in range(y.shape[0]):\n        sample_weight[i] = class_weight.get(int(y[i]), 1.0)\n    return sample_weight\n", "path": "keras/trainers/data_adapters/data_adapter_utils.py"}], "after_files": [{"content": "import math\n\nimport numpy as np\nimport tree\n\nfrom keras import backend\nfrom keras.api_export import keras_export\n\ntry:\n    import pandas\nexcept ImportError:\n    pandas = None\n\n\n# Leave jax, tf, and torch arrays off this list. Instead we will use\n# `__array__` to detect these types. Doing so allows us to avoid importing a\n# backend framework we are not currently using just to do type-checking.\nARRAY_TYPES = (np.ndarray,)\nif backend.backend() == \"tensorflow\":\n    from keras.utils.module_utils import tensorflow as tf\n\n    ARRAY_TYPES = ARRAY_TYPES + (tf.Tensor, tf.RaggedTensor)\nif pandas:\n    ARRAY_TYPES = ARRAY_TYPES + (pandas.Series, pandas.DataFrame)\n\n\n@keras_export(\"keras.utils.unpack_x_y_sample_weight\")\ndef unpack_x_y_sample_weight(data):\n    \"\"\"Unpacks user-provided data tuple.\n\n    This is a convenience utility to be used when overriding\n    `Model.train_step`, `Model.test_step`, or `Model.predict_step`.\n    This utility makes it easy to support data of the form `(x,)`,\n    `(x, y)`, or `(x, y, sample_weight)`.\n\n    Standalone usage:\n\n    >>> features_batch = ops.ones((10, 5))\n    >>> labels_batch = ops.zeros((10, 5))\n    >>> data = (features_batch, labels_batch)\n    >>> # `y` and `sample_weight` will default to `None` if not provided.\n    >>> x, y, sample_weight = unpack_x_y_sample_weight(data)\n    >>> sample_weight is None\n    True\n\n    Args:\n        data: A tuple of the form `(x,)`, `(x, y)`, or `(x, y, sample_weight)`.\n\n    Returns:\n        The unpacked tuple, with `None`s for `y` and `sample_weight` if they are\n        not provided.\n    \"\"\"\n    if isinstance(data, list):\n        data = tuple(data)\n    if not isinstance(data, tuple):\n        return (data, None, None)\n    elif len(data) == 1:\n        return (data[0], None, None)\n    elif len(data) == 2:\n        return (data[0], data[1], None)\n    elif len(data) == 3:\n        return (data[0], data[1], data[2])\n    error_msg = (\n        \"Data is expected to be in format `x`, `(x,)`, `(x, y)`, \"\n        f\"or `(x, y, sample_weight)`, found: {data}\"\n    )\n    raise ValueError(error_msg)\n\n\n@keras_export(\"keras.utils.pack_x_y_sample_weight\")\ndef pack_x_y_sample_weight(x, y=None, sample_weight=None):\n    \"\"\"Packs user-provided data into a tuple.\n\n    This is a convenience utility for packing data into the tuple formats\n    that `Model.fit()` uses.\n\n    Standalone usage:\n\n    >>> x = ops.ones((10, 1))\n    >>> data = pack_x_y_sample_weight(x)\n    >>> isinstance(data, ops.Tensor)\n    True\n    >>> y = ops.ones((10, 1))\n    >>> data = pack_x_y_sample_weight(x, y)\n    >>> isinstance(data, tuple)\n    True\n    >>> x, y = data\n\n    Args:\n        x: Features to pass to `Model`.\n        y: Ground-truth targets to pass to `Model`.\n        sample_weight: Sample weight for each element.\n\n    Returns:\n        Tuple in the format used in `Model.fit()`.\n    \"\"\"\n    if y is None:\n        # For single x-input, we do no tuple wrapping since in this case\n        # there is no ambiguity. This also makes NumPy and Dataset\n        # consistent in that the user does not have to wrap their Dataset\n        # data in an unnecessary tuple.\n        if not isinstance(x, tuple or list):\n            return x\n        else:\n            return (x,)\n    elif sample_weight is None:\n        return (x, y)\n    else:\n        return (x, y, sample_weight)\n\n\ndef list_to_tuple(maybe_list):\n    \"\"\"Datasets will stack any list of tensors, so we convert them to tuples.\"\"\"\n    if isinstance(maybe_list, list):\n        return tuple(maybe_list)\n    return maybe_list\n\n\ndef check_data_cardinality(data):\n    num_samples = set(int(i.shape[0]) for i in tree.flatten(data))\n    if len(num_samples) > 1:\n        msg = (\n            \"Data cardinality is ambiguous. \"\n            \"Make sure all arrays contain the same number of samples.\"\n        )\n        for label, single_data in zip([\"x\", \"y\", \"sample_weight\"], data):\n            sizes = \", \".join(\n                str(i.shape[0]) for i in tree.flatten(single_data)\n            )\n            msg += f\"'{label}' sizes: {sizes}\\n\"\n        raise ValueError(msg)\n\n\ndef sync_shuffle(data, num_samples=None):\n    if num_samples is None:\n        num_samples_set = set(int(i.shape[0]) for i in tree.flatten(data))\n        assert len(num_samples_set) == 1\n        num_samples = num_samples_set.pop()\n    p = np.random.permutation(num_samples)\n    return tree.map_structure(lambda x: x[p], data)\n\n\ndef train_validation_split(arrays, validation_split):\n    \"\"\"Split arrays into train and validation subsets in deterministic order.\n\n    The last part of data will become validation data.\n\n    Args:\n        arrays: Tensors to split. Allowed inputs are arbitrarily nested\n            structures of Tensors and NumPy arrays.\n        validation_split: Float between 0 and 1. The proportion of the dataset\n            to include in the validation split. The rest of the dataset will be\n            included in the training split.\n\n    Returns:\n        `(train_arrays, validation_arrays)`\n    \"\"\"\n\n    def _can_split(t):\n        return isinstance(t, ARRAY_TYPES) or t is None\n\n    flat_arrays = tree.flatten(arrays)\n    unsplitable = [type(t) for t in flat_arrays if not _can_split(t)]\n    if unsplitable:\n        raise ValueError(\n            \"Argument `validation_split` is only supported \"\n            \"for tensors or NumPy arrays.\"\n            f\"Found incompatible type in the input: {unsplitable}\"\n        )\n\n    if all(t is None for t in flat_arrays):\n        return arrays, arrays\n\n    first_non_none = None\n    for t in flat_arrays:\n        if t is not None:\n            first_non_none = t\n            break\n\n    # Assumes all arrays have the same batch shape or are `None`.\n    batch_dim = int(first_non_none.shape[0])\n    split_at = int(math.floor(batch_dim * (1.0 - validation_split)))\n\n    if split_at == 0 or split_at == batch_dim:\n        raise ValueError(\n            f\"Training data contains {batch_dim} samples, which is not \"\n            \"sufficient to split it into a validation and training set as \"\n            f\"specified by `validation_split={validation_split}`. Either \"\n            \"provide more data, or a different value for the \"\n            \"`validation_split` argument.\"\n        )\n\n    def _split(t, start, end):\n        if t is None:\n            return t\n        return t[start:end]\n\n    train_arrays = tree.map_structure(\n        lambda x: _split(x, start=0, end=split_at), arrays\n    )\n    val_arrays = tree.map_structure(\n        lambda x: _split(x, start=split_at, end=batch_dim), arrays\n    )\n    return train_arrays, val_arrays\n\n\ndef class_weight_to_sample_weights(y, class_weight):\n    sample_weight = np.ones(shape=(y.shape[0],), dtype=backend.floatx())\n    if len(y.shape) > 1:\n        if y.shape[-1] != 1:\n            y = np.argmax(y, axis=-1)\n        else:\n            y = np.squeeze(y, axis=-1)\n    y = np.round(y).astype(\"int32\")\n    for i in range(y.shape[0]):\n        sample_weight[i] = class_weight.get(int(y[i]), 1.0)\n    return sample_weight\n", "path": "keras/trainers/data_adapters/data_adapter_utils.py"}]}