{"cells":[{"cell_type":"markdown","metadata":{},"source":["# Tensorflow js model\n","> Creating and serving a Tensorflow javascript model in the browser.\n","\n","- toc: false\n","- badges: true\n","- comments: true\n","- categories: [tfjs, keras, serving]"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"taEElfKSBHge"},"source":["In this tutorial we learn how to \n","\n","\n","1. Train a model with Keras with GPU\n","2. Convert a model to web format \n","3. Upload the model to GitHub Pages \n","4. Prediction using TensorFlow.js \n","\n"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"b1JCrGrePvKp"},"source":["We will create a simple model that models XOR operation. Given two inputs $(x_0, x_1)$ it outputs $y$\n","\n","$$\\left[\\begin{array}{cc|c} \n"," x_0 & x_1 & y\\\\\n"," 0 & 0 & 0\\\\ \n"," 0 & 1 & 1\\\\\n"," 1 & 0 & 1\\\\\n"," 1 & 1 & 0\n","\\end{array}\\right]$$"]},{"cell_type":"markdown","metadata":{},"source":["## Build the model"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"WKYiL-oYR0yk"},"source":["Imports "]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":34},"colab_type":"code","id":"a-UbSG-DR3ID","outputId":"c8c804fc-d97d-45df-dff4-6cc729f21951"},"outputs":[{"name":"stderr","output_type":"stream","text":["Using TensorFlow backend.\n"]}],"source":["from keras.models import Sequential\n","from keras.layers.core import Dense, Dropout, Activation\n","from keras.optimizers import SGD\n","import numpy as np "]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"UvBySAixR4Ca"},"source":["Initialize the inputs "]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{},"colab_type":"code","id":"Hj65iQS6R6pO"},"outputs":[],"source":["X = np.array([[0,0],[0,1],[1,0],[1,1]])\n","y = np.array([[0],[1],[1],[0]])"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"TTyQKnEgSBQb"},"source":["Create the model "]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{},"colab_type":"code","id":"ivnpyw3ZSAF9"},"outputs":[],"source":["model = Sequential()\n","model.add(Dense(8, input_dim=2))\n","model.add(Activation('tanh'))\n","model.add(Dense(1))\n","model.add(Activation('sigmoid'))\n","\n","sgd = SGD(lr=0.1)\n","model.compile(loss='binary_crossentropy', optimizer=sgd)"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"zzrpHO1XSIeJ"},"source":["Train the model "]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":34},"colab_type":"code","id":"jRwYsPJxRrYT","outputId":"733d8a80-8589-4d5e-cbc9-9e8f4c8f2c1e"},"outputs":[{"data":{"text/plain":[""]},"execution_count":9,"metadata":{"tags":[]},"output_type":"execute_result"}],"source":["model.fit(X, y, batch_size=1, epochs=1000, verbose= 0)"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"VHlJ2cmpSbZ7"},"source":["Predict the output "]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":85},"colab_type":"code","id":"ky1bM2EiSHYt","outputId":"cd528c04-469d-479f-eda5-ed610716a9f0"},"outputs":[{"name":"stdout","output_type":"stream","text":["[[0.00149857]\n"," [0.99531186]\n"," [0.9949425 ]\n"," [0.00591634]]\n"]}],"source":["print(model.predict_proba(X))"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"vvdWZCRslZUz"},"source":["Save the model "]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{},"colab_type":"code","id":"mxRke-l9lXfY"},"outputs":[],"source":["model.save('saved_model/keras.h5')"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"glkP5CvySfgK"},"source":["## Convert the model "]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"q30sPc63lbvw"},"source":["Download the library "]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{},"colab_type":"code","id":"-FSJVtS9SiVi"},"outputs":[],"source":["!pip install tensorflowjs"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"HWCP02udldLr"},"source":["Convert the model "]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{},"colab_type":"code","id":"DuQP_mkeSkKL"},"outputs":[],"source":["!tensorflowjs_converter --input_format keras saved_model/keras.h5 web_model"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"dr8MnQUbUBY7"},"source":["## Create a web page to serve the model"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"SC9QaDQreTDr"},"source":["Import TensorFlow.js "]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{},"colab_type":"code","id":"iwJQerK2eA_u"},"outputs":[],"source":["header = '\\n'"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"GE_Y5U3UeW6U"},"source":["Code for loading the web model. We predict a tensor of zeros and show the result in the page. "]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{},"colab_type":"code","id":"kpGEMkjJecBM"},"outputs":[],"source":["script = '\\\n","\\n\\\n"," \\n'"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"0TDOfXR6f9tp"},"source":["Body of the page"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{},"colab_type":"code","id":"cf5VErepf9H0"},"outputs":[],"source":["body = '\\\n","\\n\\\n","

\\n\\\n","'"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"2DaBOiA-jTER"},"source":["Save the code as html file"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{},"colab_type":"code","id":"pM6JIkRCglMu"},"outputs":[],"source":["with open('index.html','w') as f:\n"," f.write(header+script+body)\n"," f.close()"]}],"metadata":{"accelerator":"GPU","colab":{"collapsed_sections":[],"name":"2b154a09-e5b9-4b3d-a1a0-b44c299ccf25","provenance":[{"file_id":"https://github.com/zaidalyafeai/Notebooks/blob/master/ONePlace.ipynb","timestamp":1588884143528}]},"kernelspec":{"display_name":"Python 3","name":"python3"}},"nbformat":4,"nbformat_minor":0}