title: Is it possible to split a tensorflow dataset into train, validation AND test datasets when using image_dataset_from_directory?
body: <p>I am using <code>tf.keras.utils.image_dataset_from_directory</code> to load a dataset of 4575 images. While this function allows to split the data into two subsets (with the <code>validation_split</code> parameter), I want to split it into training, testing, and validation subsets.</p>
  <p>I have tried using <code>dataset.skip()</code> and <code>dataset.take()</code> to further split one of the resulting subsets, but these functions return a <code>SkipDataset</code> and a <code>TakeDataset</code> respectively (by the way, contrary to <a href="https://www.tensorflow.org/api_docs/python/tf/data/Dataset?version=stable#take" rel="nofollow noreferrer">the documentation</a>, where it is claimed that these functions return a <code>Dataset</code>). This leads to problems when fitting the model - the metrics calculated on validation sets (val_loss, val_accuracy) disappear from model history.</p>
  <p>So, my question is: is there a way to split a <code>Dataset</code> into three subsets for training, validation and testing, so that all three subsets are also <code>Dataset</code> objects?</p>
  <p><strong>Code used to load the data</strong></p>
  <pre><code>def load_data_tf(data_path: str, img_shape=(256,256), batch_size: int=8):
      train_ds = tf.keras.utils.image_dataset_from_directory(
          data_path,
          validation_split=0.2,
          subset=&quot;training&quot;,
          label_mode='categorical',
          seed=123,
          image_size=img_shape,
          batch_size=batch_size)
      val_ds = tf.keras.utils.image_dataset_from_directory(
          data_path,
          validation_split=0.3,
          subset=&quot;validation&quot;,
          label_mode='categorical',
          seed=123,
          image_size=img_shape,
          batch_size=batch_size)
      return train_ds, val_ds
  
  train_dataset, test_val_ds = load_data_tf('data_folder', img_shape = (256,256), batch_size=8)
  test_dataset = test_val_ds.take(686)
  val_dataset = test_val_ds.skip(686)
  </code></pre>
  <p><strong>Model compilation and fitting</strong></p>
  <pre><code>model.compile(optimizer='sgd',
                loss=tf.keras.losses.CategoricalCrossentropy(from_logits=False),
                metrics=['accuracy'])
  history = model.fit(train_dataset, epochs=50, validation_data=val_dataset, verbose=1)
  </code></pre>
  <p><strong>When using a normal <code>Dataset</code>, <code>val_accuracy</code> and <code>val_loss</code> are present in the history of the model:</strong></p>
  <p><a href="https://i.stack.imgur.com/Qn1Yf.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Qn1Yf.png" alt="Expected behaviour: when using a Dataset, validation metrics are calculated" /></a></p>
  <p><strong>But when using a <code>SkipDataset</code>, they are not:</strong></p>
  <p><a href="https://i.stack.imgur.com/GMnBM.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/GMnBM.png" alt="Using the SkipDataset produced by test_val_ds.take() leads to validation metrics disappearing from model history" /></a></p>
  <p><a href="https://i.stack.imgur.com/omU5U.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/omU5U.png" alt="val_accuracy and val_loss are not present in history keys when using a SkipDataset or a TakeDataset" /></a></p>