.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/integrations/_01_tensorflow.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_integrations__01_tensorflow.py: .. _tensorflow: Tensorflow/Keras ================ .. note:: This example requires the `tensorflow` package to be installed. Theoretically, tpcp is framework agnostic and can be used with any framework. However, due to the way some frameworks handle their objects, some special handling internally is required. Hence, this example does not only serve as example on how to use tensorflow with tpcp, but also as a test case for these special cases. When using tpcp with any machine learning framework, you either want to use a pretrained model with a normal pipeline or a train your own model as part of an Optimizable Pipeline. Here we show the second case, as it is more complex, and you are likely able to figure out the first case yourself. This means, we are planning to perform the following steps: 1. Create a pipeline that creates and trains a model. 2. Allow the modification of model hyperparameters. 3. Run a simple cross-validation to demonstrate the functionality. This example reimplements the basic MNIST example from the [tensorflow documentation](https://www.tensorflow.org/tutorials/keras/classification). Some Notes ---------- In this example we show how to implement a Pipeline that uses tensorflow. You could implement an Algorithm in a similar way. This would actually be easier, as no specific handling of the input data would be required. For a pipeline, we need to create a custom Dataset class, as this is the expected input for a pipeline. .. GENERATED FROM PYTHON SOURCE LINES 38-53 The Dataset ----------- We are using the normal fashion MNIST dataset for this example It consists of 60.000 images of 28x28 pixels, each with a label. We will ignore the typical train-test split, as we want to do our own cross-validation. In addition, we will simulate an additional "index level". In this (and most typical deep learning datasets), each datapoint is one vector for which we can make one prediction. In tpcp, we usually deal with datasets, where you might have multiple pieces of information for each datapoint. For example, one datapoint could be a patient, for which we have an entire time series of measurements. We will simulate this here, by creating the index of our dataset as 1000 groups each containing 60 images. Other than that, the dataset is pretty standard. Besides the `create_index` method, we only need to implement the `input_as_array` and `labels_as_array` methods that allow us to easily access the data once we selected a single group. .. GENERATED FROM PYTHON SOURCE LINES 53-98 .. code-block:: default from functools import lru_cache import numpy as np import pandas as pd import tensorflow as tf from tpcp import Dataset tf.keras.utils.set_random_seed(812) tf.config.experimental.enable_op_determinism() @lru_cache(maxsize=1) def get_fashion_mnist_data(): # Note: We throw train and test sets together, as we don't care about the official split here. # We will create our own split later. (train_images, train_labels), (test_images, test_labels) = ( tf.keras.datasets.fashion_mnist.load_data() ) return np.array(list(train_images) + list(test_images)), list( train_labels ) + list(test_labels) class FashionMNIST(Dataset): def input_as_array(self) -> np.ndarray: self.assert_is_single(None, "input_as_array") group_id = int(self.group_label.group_id) images, _ = get_fashion_mnist_data() return ( images[group_id * 60 : (group_id + 1) * 60].reshape((60, 28, 28)) / 255 ) def labels_as_array(self) -> np.ndarray: self.assert_is_single(None, "labels_as_array") group_id = int(self.group_label.group_id) _, labels = get_fashion_mnist_data() return np.array(labels[group_id * 60 : (group_id + 1) * 60]) def create_index(self) -> pd.DataFrame: # There are 60.000 images in total. # We simulate 1000 groups of 60 images each. return pd.DataFrame({"group_id": list(range(1000))}) .. GENERATED FROM PYTHON SOURCE LINES 99-100 We can see our Dataset works as expected: .. GENERATED FROM PYTHON SOURCE LINES 100-103 .. code-block:: default dataset = FashionMNIST() dataset[0].input_as_array().shape .. rst-class:: sphx-glr-script-out .. code-block:: none Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz 0/29515 ━━━━━━━━━━━━━━━━━━━━ 0s 0s/step 29515/29515 ━━━━━━━━━━━━━━━━━━━━ 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz 0/26421880 ━━━━━━━━━━━━━━━━━━━━ 0s 0s/step 729088/26421880 ━━━━━━━━━━━━━━━━━━━━ 1s 0us/step 9379840/26421880 ━━━━━━━━━━━━━━━━━━━━ 0s 0us/step 18325504/26421880 ━━━━━━━━━━━━━━━━━━━━ 0s 0us/step 26421880/26421880 ━━━━━━━━━━━━━━━━━━━━ 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz 0/5148 ━━━━━━━━━━━━━━━━━━━━ 0s 0s/step 5148/5148 ━━━━━━━━━━━━━━━━━━━━ 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz 0/4422102 ━━━━━━━━━━━━━━━━━━━━ 0s 0s/step 516096/4422102 ━━━━━━━━━━━━━━━━━━━━ 0s 0us/step 4422102/4422102 ━━━━━━━━━━━━━━━━━━━━ 0s 0us/step (60, 28, 28) .. GENERATED FROM PYTHON SOURCE LINES 104-106 .. code-block:: default dataset[0].labels_as_array().shape .. rst-class:: sphx-glr-script-out .. code-block:: none (60,) .. GENERATED FROM PYTHON SOURCE LINES 107-144 The Pipeline ------------ We will create a pipeline that uses a simple neural network to classify the images. In tpcp, all "things" that should be optimized need to be parameters. This means our model itself needs to be a parameter of the pipeline. However, as we don't have the model yet, as its creation depends on other hyperparameters, we add it as an optional parameter initialized with `None`. Further, we prefix the parameter name with an underscore, to signify, that this is not a parameter that should be modified manually by the user. This is just convention, and it is up to you to decide how you want to name your parameters. We further introduce a hyperparameter `n_dense_layer_nodes` to show how we can influence the model creation. The optimize method +++++++++++++++++++ To make our pipeline optimizable, it needs to inherit from `OptimizablePipeline`. Further we need to mark at least one of the parameters as `OptiPara` using the type annotation. We do this for our `_model` parameter. Finally, we need to implement the `self_optimize` method. This method will get the entire training dataset as input and should update the `_model` parameter with the trained model. Hence, we first extract the relevant data (remember, each datapoint is 60 images), by concatinating all images over all groups in the dataset. Then we create the Keras model based on the hyperparameters. Finally, we train the model and update the `_model` parameter. Here we chose to wrap the method with `make_optimize_safe`. This decorator will perform some runtime checks to ensure that the method is implemented correctly. The run method ++++++++++++++ The run method expects that the `_model` parameter is already set (i.e. the pipeline was already optimized). It gets a single datapoint as input (remember, a datapoint is a single group of 60 images). We then extract the data from the datapoint and let the model make a prediction. We store the prediction on our output attribute `predictions_`. The trailing underscore is a convention to signify, that this is an "result" attribute. .. GENERATED FROM PYTHON SOURCE LINES 144-223 .. code-block:: default import warnings from typing import Optional from tpcp import ( OptimizablePipeline, OptiPara, make_action_safe, make_optimize_safe, ) from typing_extensions import Self class KerasPipeline(OptimizablePipeline): n_dense_layer_nodes: int n_train_epochs: int _model: OptiPara[Optional[tf.keras.Sequential]] predictions_: np.ndarray def __init__( self, n_dense_layer_nodes=128, n_train_epochs=5, _model: Optional[tf.keras.Sequential] = None, ): self.n_dense_layer_nodes = n_dense_layer_nodes self.n_train_epochs = n_train_epochs self._model = _model @property def predicted_labels_(self): return np.argmax(self.predictions_, axis=1) @make_optimize_safe def self_optimize(self, dataset, **_) -> Self: data = tf.convert_to_tensor( np.vstack([d.input_as_array() for d in dataset]) ) labels = tf.convert_to_tensor( np.hstack([d.labels_as_array() for d in dataset]) ) print(data.shape) if self._model is not None: warnings.warn("Overwriting existing model!") self._model = tf.keras.Sequential( [ tf.keras.layers.Input((28, 28)), tf.keras.layers.Flatten(), tf.keras.layers.Dense( self.n_dense_layer_nodes, activation="relu" ), tf.keras.layers.Dense(10), ] ) self._model.compile( optimizer="adam", loss=tf.keras.losses.SparseCategoricalCrossentropy( from_logits=True ), metrics=["accuracy"], ) self._model.fit(data, labels, epochs=self.n_train_epochs) return self @make_action_safe def run(self, datapoint) -> Self: if self._model is None: raise RuntimeError("Model not trained yet!") data = tf.convert_to_tensor(datapoint.input_as_array()) self.predictions_ = self._model.predict(data) return self .. GENERATED FROM PYTHON SOURCE LINES 224-229 Testing the pipeline -------------------- We can now test our pipeline. We will run the optimization using a couple of datapoints (to keep everything fast) and then use `run` to get the predictions for a single unseen datapoint. .. GENERATED FROM PYTHON SOURCE LINES 229-234 .. code-block:: default pipeline = KerasPipeline().self_optimize(FashionMNIST()[:10]) p1 = pipeline.run(FashionMNIST()[11]) print(p1.predicted_labels_) print(FashionMNIST()[11].labels_as_array()) .. rst-class:: sphx-glr-script-out .. code-block:: none (600, 28, 28) Epoch 1/5 1/19 ━━━━━━━━━━━━━━━━━━━━ 9s 521ms/step - accuracy: 0.1250 - loss: 2.3593 19/19 ━━━━━━━━━━━━━━━━━━━━ 1s 2ms/step - accuracy: 0.4933 - loss: 1.5112 Epoch 2/5 1/19 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.7188 - loss: 1.0003 19/19 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - accuracy: 0.7167 - loss: 0.8663 Epoch 3/5 1/19 ━━━━━━━━━━━━━━━━━━━━ 0s 11ms/step - accuracy: 0.7812 - loss: 0.7427 19/19 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - accuracy: 0.7800 - loss: 0.6830 Epoch 4/5 1/19 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.7812 - loss: 0.6089 19/19 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - accuracy: 0.8133 - loss: 0.5658 Epoch 5/5 1/19 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - accuracy: 0.7812 - loss: 0.5329 19/19 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - accuracy: 0.8433 - loss: 0.4940 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step [8 8 6 9 4 0 7 3 7 9 4 8 4 3 7 8 1 4 0 7 9 8 5 5 2 1 3 4 1 9 7 5 9 9 7 8 2 7 4 7 2 4 7 1 1 7 5 4 8 3 5 9 0 7 4 0 0 9 1 9] [8 8 0 9 2 0 7 3 7 9 3 8 4 3 7 8 1 4 0 7 9 8 5 5 2 1 3 4 6 7 7 5 9 9 7 8 2 7 4 7 0 3 5 1 1 5 5 2 8 3 5 9 0 7 3 0 0 7 1 9] .. GENERATED FROM PYTHON SOURCE LINES 235-237 We can see that even with just 5 epochs, the model already performs quite well. To quantify we can calculate the accuracy for this datapoint: .. GENERATED FROM PYTHON SOURCE LINES 237-241 .. code-block:: default from sklearn.metrics import accuracy_score accuracy_score(p1.predicted_labels_, FashionMNIST()[11].labels_as_array()) .. rst-class:: sphx-glr-script-out .. code-block:: none 0.8 .. GENERATED FROM PYTHON SOURCE LINES 242-248 Cross Validation ---------------- If we want to run a cross validation, we need to formalize the scoring into a function. We will calculate two types of accuracy: First, the accuracy per group and second, the accuracy over all images across all groups. For more information about how this works, check the :ref:`Custom Scorer ` example. .. GENERATED FROM PYTHON SOURCE LINES 248-278 .. code-block:: default from collections.abc import Sequence from tpcp.validate import Aggregator class SingleValueAccuracy(Aggregator[tuple[np.ndarray, np.ndarray]]): def aggregate( self, /, values: Sequence[tuple[np.ndarray, np.ndarray]], **_ ) -> dict[str, float]: return { "accuracy": accuracy_score( np.hstack([v[0] for v in values]), np.hstack([v[1] for v in values]), ) } single_value_accuracy = SingleValueAccuracy() def scoring(pipeline, datapoint): result: np.ndarray = pipeline.safe_run(datapoint).predicted_labels_ reference = datapoint.labels_as_array() return { "accuracy": accuracy_score(result, reference), "per_sample": single_value_accuracy((result, reference)), } .. GENERATED FROM PYTHON SOURCE LINES 279-286 Now we can run a cross validation. We will only run it on a subset of the data, to keep the runtime manageable. .. note:: You might see warnings about retracing of the model. This is because we clone the pipeline before each call to the run method. This is a good idea to ensure that all pipelines are independent of each other, however, might result in some performance overhead. .. GENERATED FROM PYTHON SOURCE LINES 286-294 .. code-block:: default from tpcp.optimize import Optimize from tpcp.validate import cross_validate pipeline = KerasPipeline(n_train_epochs=10) cv_results = cross_validate( Optimize(pipeline), FashionMNIST()[:100], scoring=scoring, cv=3 ) .. rst-class:: sphx-glr-script-out .. code-block:: none CV Folds: 0%| | 0/3 [00:00.one_step_on_data_distributed at 0x7c3166fbaef0> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has reduce_retracing=True option that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for more details. 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/stepWARNING:tensorflow:6 out of the last 6 calls to .one_step_on_data_distributed at 0x7c3166fbaef0> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has reduce_retracing=True option that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for more details.  2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 6%|▌ | 2/34 [00:00<00:03, 9.71it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 9%|▉ | 3/34 [00:00<00:03, 9.80it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 12%|█▏ | 4/34 [00:00<00:03, 9.87it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step Datapoints: 15%|█▍ | 5/34 [00:00<00:02, 9.75it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 18%|█▊ | 6/34 [00:00<00:02, 9.79it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 21%|██ | 7/34 [00:00<00:02, 9.75it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 24%|██▎ | 8/34 [00:00<00:02, 9.65it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 26%|██▋ | 9/34 [00:00<00:02, 9.70it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 29%|██▉ | 10/34 [00:01<00:02, 9.72it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 32%|███▏ | 11/34 [00:01<00:02, 9.68it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 35%|███▌ | 12/34 [00:01<00:02, 9.71it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 38%|███▊ | 13/34 [00:01<00:02, 9.76it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step Datapoints: 41%|████ | 14/34 [00:01<00:02, 9.72it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 44%|████▍ | 15/34 [00:01<00:01, 9.74it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 47%|████▋ | 16/34 [00:01<00:01, 9.76it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 50%|█████ | 17/34 [00:01<00:01, 9.68it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step Datapoints: 53%|█████▎ | 18/34 [00:01<00:01, 9.59it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 56%|█████▌ | 19/34 [00:01<00:01, 9.55it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 59%|█████▉ | 20/34 [00:02<00:01, 9.45it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step Datapoints: 62%|██████▏ | 21/34 [00:02<00:01, 9.60it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step Datapoints: 65%|██████▍ | 22/34 [00:02<00:01, 9.71it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step Datapoints: 68%|██████▊ | 23/34 [00:02<00:01, 9.70it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step Datapoints: 71%|███████ | 24/34 [00:02<00:01, 9.73it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 76%|███████▋ | 26/34 [00:02<00:00, 9.79it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step Datapoints: 79%|███████▉ | 27/34 [00:02<00:00, 9.84it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step Datapoints: 82%|████████▏ | 28/34 [00:02<00:00, 9.88it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step Datapoints: 85%|████████▌ | 29/34 [00:02<00:00, 9.72it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step Datapoints: 88%|████████▊ | 30/34 [00:03<00:00, 9.76it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 91%|█████████ | 31/34 [00:03<00:00, 9.77it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 94%|█████████▍| 32/34 [00:03<00:00, 9.67it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step Datapoints: 97%|█████████▋| 33/34 [00:03<00:00, 9.72it/s] 1/2 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step Datapoints: 100%|██████████| 34/34 [00:03<00:00, 9.73it/s] CV Folds: 33%|███▎ | 1/3 [00:06<00:12, 6.20s/it](4020, 28, 28) Epoch 1/10 1/126 ━━━━━━━━━━━━━━━━━━━━ 1:40 808ms/step - accuracy: 0.1250 - loss: 2.3656 39/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.4280 - loss: 1.6646  78/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.5217 - loss: 1.4044 117/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.5722 - loss: 1.2592 126/126 ━━━━━━━━━━━━━━━━━━━━ 1s 1ms/step - accuracy: 0.7000 - loss: 0.8913 Epoch 2/10 1/126 ━━━━━━━━━━━━━━━━━━━━ 1s 12ms/step - accuracy: 0.8438 - loss: 0.4830 39/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.7655 - loss: 0.6245  80/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.7718 - loss: 0.6169 120/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.7779 - loss: 0.6067 126/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.7968 - loss: 0.5690 Epoch 3/10 1/126 ━━━━━━━━━━━━━━━━━━━━ 1s 12ms/step - accuracy: 0.8750 - loss: 0.3561 41/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8124 - loss: 0.5224  82/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8146 - loss: 0.5205 123/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8174 - loss: 0.5154 126/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8284 - loss: 0.4927 Epoch 4/10 1/126 ━━━━━━━━━━━━━━━━━━━━ 1s 12ms/step - accuracy: 0.9375 - loss: 0.3082 42/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8350 - loss: 0.4816  83/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8345 - loss: 0.4809 124/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8364 - loss: 0.4758 126/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8453 - loss: 0.4533 Epoch 5/10 1/126 ━━━━━━━━━━━━━━━━━━━━ 1s 12ms/step - accuracy: 0.8750 - loss: 0.3008 42/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8358 - loss: 0.4395  82/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8404 - loss: 0.4361 121/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8440 - loss: 0.4323 126/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8570 - loss: 0.4134 Epoch 6/10 1/126 ━━━━━━━━━━━━━━━━━━━━ 1s 12ms/step - accuracy: 0.8750 - loss: 0.2896 39/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8423 - loss: 0.4071  77/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8493 - loss: 0.4046 117/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8537 - loss: 0.4014 126/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8674 - loss: 0.3836 Epoch 7/10 1/126 ━━━━━━━━━━━━━━━━━━━━ 1s 12ms/step - accuracy: 0.8750 - loss: 0.2921 41/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8391 - loss: 0.3811  81/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8496 - loss: 0.3775 120/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8552 - loss: 0.3743 126/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8724 - loss: 0.3583 Epoch 8/10 1/126 ━━━━━━━━━━━━━━━━━━━━ 1s 12ms/step - accuracy: 0.8750 - loss: 0.2784 42/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8514 - loss: 0.3570  82/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8598 - loss: 0.3542 123/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8650 - loss: 0.3513 126/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8801 - loss: 0.3375 Epoch 9/10 1/126 ━━━━━━━━━━━━━━━━━━━━ 1s 12ms/step - accuracy: 0.8750 - loss: 0.2839 36/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8591 - loss: 0.3376  74/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8665 - loss: 0.3345 115/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8720 - loss: 0.3316 126/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8873 - loss: 0.3178 Epoch 10/10 1/126 ━━━━━━━━━━━━━━━━━━━━ 1s 13ms/step - accuracy: 0.8750 - loss: 0.2753 41/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8658 - loss: 0.3181  82/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8752 - loss: 0.3141 122/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8803 - loss: 0.3116 126/126 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8940 - loss: 0.3003 Datapoints: 0%| | 0/33 [00:00` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: _01_tensorflow.ipynb <_01_tensorflow.ipynb>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_