{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load and apply a trained Keras model\n",
    "\n",
    "This example is from [Stefan Wunsch (CERN IML TensoFlow and Keras workshop)](https://github.com/stwunsch/iml_tensorflow_keras_workshop).\n",
    "\n",
    "The code of this notebook shows how you can load and apply an already trained Keras model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import png\n",
    "from tensorflow.keras.models import load_model\n",
    "from os import listdir\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load the model\n",
    "\n",
    "Loading a Keras model needs only a single line of code, see below. After this call, the model is back in the same state you stored it at the training step either by the `ModelCheckpoint` or `model.save(...)`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = load_model(\"mnist_keras_model.h5\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Apply the model\n",
    "\n",
    "The application is done as shown in the testing phase of the training script. Simply call `model.predict(inputs)` on your data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2022-03-12 17:54:48.613328: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:185] None of the MLIR Optimization Passes are enabled (registered 2)\n"
     ]
    }
   ],
   "source": [
    "predictions = []\n",
    "images = []\n",
    "for f in sorted(listdir(\".\")):\n",
    "    if \"mnist_example_\" in f:\n",
    "        image = np.zeros((1, 28, 28, 1), dtype=np.uint8)\n",
    "        pngdata = png.Reader(open(f, 'rb')).asDirect()\n",
    "        for i_row, row in enumerate(pngdata[2]):\n",
    "            image[0, i_row, :, 0] = row\n",
    "        images.append(image)\n",
    "        \n",
    "        prediction = np.argmax(model.predict(image))\n",
    "        predictions.append(prediction)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 6644 characters]\n",
      "text/plain": [
       "<Figure size 864x144 with 6 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "num_examples = len(images)\n",
    "plt.figure(figsize=(num_examples*2, 2))\n",
    "plt.rcParams.update({'axes.titlesize': 'xx-large'})\n",
    "for i in range(num_examples):\n",
    "    plt.subplot(1, num_examples, i+1)\n",
    "    plt.axis('off')\n",
    "    plt.imshow(np.squeeze(images[i]), cmap=\"gray\")\n",
    "    plt.title(\"{}\".format(predictions[i]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model prediction for each class: [[2.3904847e-16 9.0325976e-12 4.8380059e-07 9.9989939e-01 4.1473118e-05\n",
      "  5.7533276e-09 4.0925880e-09 5.8235182e-05 3.4916306e-07 2.5625425e-16]]\n",
      "Predicted digit: 3\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "f = \"your_own_digit.png\"\n",
    "image = np.zeros((1, 28, 28, 1), dtype=np.uint8)\n",
    "pngdata = png.Reader(open(f, 'rb')).asDirect()\n",
    "for i_row, row in enumerate(pngdata[2]):\n",
    "    image[0, i_row, :, 0] = row\n",
    "    \n",
    "prediction_vector = model.predict(image)\n",
    "prediction = np.argmax(prediction_vector)\n",
    "print (f\"Model prediction for each class: {prediction_vector}\")\n",
    "print (f\"Predicted digit: {prediction}\")\n",
    "plt.axis('off')\n",
    "plt.imshow(np.squeeze(image), cmap=\"gray\");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
