{"cells":[{"metadata":{},"cell_type":"markdown","source":"# TF 2.0 With Keras - Minimal Example"},{"metadata":{},"cell_type":"markdown","source":"## Imports and settings"},{"metadata":{"_uuid":"4a4ea273-3d76-441f-8bff-3cd9e39ecdd3","_cell_guid":"81c156ba-f7b8-4b38-be1d-a68040aeac34","trusted":true},"cell_type":"code","source":"# Python imports\nimport random as rn\n\n# Numerical imports\nimport numpy as np\nimport pandas as pd\n\n# Tensorflow imports\nimport tensorflow as tf\n\n# Keras imports\nfrom tensorflow.keras.backend import sigmoid\nfrom tensorflow.keras.callbacks import EarlyStopping\nfrom tensorflow.keras.datasets import mnist\nfrom tensorflow.keras.initializers import lecun_normal\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Activation, AlphaDropout, Conv2D, Dense, Input, Flatten\nfrom tensorflow.keras.optimizers import Adam, SGD\nfrom tensorflow.keras.utils import Sequence, get_custom_objects, to_categorical\n\n# Plotting imports\nimport matplotlib\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\n# Plotting settings\nsns.set()\nsns.set_palette(\"colorblind\")\nsns.set_style(\"ticks\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Build a Keras model"},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_model():\n    \n    # Seed randomness\n    rn.seed(0)\n    np.random.seed(0)\n    tf.random.set_seed(0)\n\n    # Shapes\n    input_shape = (28, 28, 1)\n    output_shape = 10\n\n    # Input layer\n    model = Sequential()\n    model.add(Input(shape=input_shape))\n    model.add(Flatten())\n    model.add(Dense(np.prod(input_shape), activation=\"selu\", kernel_initializer=lecun_normal(seed=0)))\n\n    # Hidden layers\n    model.add(Dense(1024, activation=\"selu\", kernel_initializer=lecun_normal(seed=0)))\n    model.add(Dense(1024, activation=\"selu\", kernel_initializer=lecun_normal(seed=0)))\n    \n    # Output layer\n    model.add(Dense(output_shape, activation=\"softmax\", kernel_initializer=lecun_normal(seed=0)))\n\n    # Optimizer and compilation\n    nadam = Adam(decay=1e-6, clipvalue=0.5)\n    model.compile(optimizer=nadam, loss=\"categorical_crossentropy\", metrics=[\"accuracy\"])\n    \n    return model\n\nmodel = build_model()\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Train and test the model"},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\n\n# Seed randomness\nrn.seed(0)\nnp.random.seed(0)\ntf.random.set_seed(0)\n\n# Load and split data into test/train\n(x_train, y_train), (x_test, y_test) = mnist.load_data()\nprint(f\"There are {len(x_train)} training images.\")\nprint(f\"There are {len(x_test)} testing images.\")\n\n# Add channels\nx_train = x_train.reshape(-1, 28, 28, 1)\nx_test = x_test.reshape(-1, 28, 28, 1)\n\n# Convert class vectors to binary class matrices\ny_train = to_categorical(y_train, 10)\ny_test = to_categorical(y_test, 10)\n\n# Store the best model based on val_accuracy and stop when no improvements are made\nearly_stopping = EarlyStopping(\n    monitor=\"val_accuracy\",\n    mode=\"auto\",\n    verbose=0,\n    patience=10,\n    restore_best_weights=True\n)\n\n# Build, fit, and test model\nmodel = build_model()\nhistory = model.fit(\n    x_train,\n    y_train,\n    batch_size=256,  # use group norm when <= 16; use batch norm when >= 32\n    epochs=100,\n    verbose=0,\n    validation_split=0.2,\n    shuffle=False,\n    callbacks=[early_stopping]\n)\n\ny1 = history.history[\"accuracy\"]\ny2 = history.history[\"val_accuracy\"]\nx = list(range(1, len(y1) + 1))\nsns.lineplot(x, y1)\nsns.lineplot(x, y2)\n\nplt.title(\"Accuracy per epoch\")\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Accuracy\")\nplt.legend([\"Train\", \"Valid\"], loc=\"lower right\")\nplt.show()\n\nscore = model.evaluate(x_test, y_test, verbose=0)\nprint(f\"Train Loss:     {history.history['loss'][-1]:.4f}\")\nprint(f\"Valid Loss:     {history.history['val_loss'][-1]:.4f}\")\nprint(f\"Test  Loss:     {score[0]:.4f}\")\nprint()\n\nprint(f\"Train Accuracy: {history.history['accuracy'][-1]:.4f}\")\nprint(f\"Valid Accuracy: {history.history['val_accuracy'][-1]:.4f}\")\nprint(f\"Test  Accuracy: {score[1]:.4f}\")\nprint()","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}