diff --git a/training/README.md b/training/README.md new file mode 100644 index 0000000..4bd1ba7 --- /dev/null +++ b/training/README.md @@ -0,0 +1,11 @@ +# Training code in python with keras + +## Files + +I included both the python notebook and the normal python code. + +The code itself is the same in both files, just take the format you prefer. + +## Training + +The training is super simple. Just the basic hello world of machine learning. You can easily run it online in google colab for free on a gpu. \ No newline at end of file diff --git a/training/simple.ipynb b/training/simple.ipynb new file mode 100644 index 0000000..09e9563 --- /dev/null +++ b/training/simple.ipynb @@ -0,0 +1,337 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "simple.ipynb", + "provenance": [], + "collapsed_sections": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "code", + "metadata": { + "id": "BeibK12dAiot", + "colab_type": "code", + "colab": {} + }, + "source": [ + "from tensorflow.keras.datasets import mnist\n", + "from tensorflow.keras.models import Sequential\n", + "from tensorflow.keras.layers import Dense, Dropout, Flatten\n", + "from tensorflow.keras.layers import Conv2D, MaxPooling2D\n", + "from tensorflow.keras.utils import to_categorical" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "VAUkfCwTA_Km", + "colab_type": "code", + "outputId": "8dabe82c-7999-49d6-d675-20979c006f10", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "(x_train, y_train), (x_test, y_test) = mnist.load_data()" + ], + "execution_count": 0, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz\n", + "11493376/11490434 [==============================] - 0s 0us/step\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "apDIDKb-BEjA", + "colab_type": "code", + "outputId": "6c25331a-2276-4d3d-9739-3acfb601c0dc", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "# Reshaping for channels_last (tensorflow) with one channel\n", + "size = 28\n", + "print(x_train.shape, x_test.shape)\n", + "x_train = x_train.reshape(len(x_train), size, size, 1).astype('float32')\n", + "x_test = x_test.reshape(len(x_test), size, size, 1).astype('float32')\n", + "print(x_train.shape, x_test.shape)" + ], + "execution_count": 0, + "outputs": [ + { + "output_type": "stream", + "text": [ + "(60000, 28, 28) (10000, 28, 28)\n", + "(60000, 28, 28, 1) (10000, 28, 28, 1)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RwTWdxVbB6Wq", + "colab_type": "code", + "outputId": "1a75bb86-8e7b-425f-c064-2f12c8615d8c", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + } + }, + "source": [ + "# Normalize\n", + "upper = max(x_train.max(), x_test.max())\n", + "lower = min(x_train.min(), x_test.min())\n", + "print(f'Max: {upper} Min: {lower}')\n", + "x_train /= upper\n", + "x_test /= upper" + ], + "execution_count": 0, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Max: 255.0 Min: 0.0\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lYQVq00XBacf", + "colab_type": "code", + "colab": {} + }, + "source": [ + "total_classes = 10\n", + "y_train = to_categorical(y_train, total_classes)\n", + "y_test = to_categorical(y_test, total_classes)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ad2UK8LkBhKe", + "colab_type": "code", + "colab": {} + }, + "source": [ + "# Make the model\n", + "model = Sequential()\n", + "model.add(Conv2D(64, (3, 3), activation='relu', input_shape=(size,size, 1), data_format='channels_last'))\n", + "model.add(Conv2D(32, (3, 3), activation='relu'))\n", + "model.add(MaxPooling2D(pool_size=(2, 2)))\n", + "model.add(Dropout(0.25))\n", + "model.add(Flatten())\n", + "model.add(Dense(128, activation='relu'))\n", + "model.add(Dropout(0.5))\n", + "model.add(Dense(total_classes, activation='softmax'))\n", + "\n", + "model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "v4Vb1_CfEVIl", + "colab_type": "code", + "outputId": "f00919d7-56b6-4577-9c97-283a48cbf804", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 459 + } + }, + "source": [ + "# Train\n", + "model.fit(x_train, y_train,\n", + " batch_size=32,\n", + " epochs=12,\n", + " verbose=True)" + ], + "execution_count": 0, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Train on 60000 samples\n", + "Epoch 1/12\n", + "60000/60000 [==============================] - 15s 256us/sample - loss: 0.2029 - acc: 0.9382\n", + "Epoch 2/12\n", + "60000/60000 [==============================] - 8s 133us/sample - loss: 0.0827 - acc: 0.9750\n", + "Epoch 3/12\n", + "60000/60000 [==============================] - 8s 134us/sample - loss: 0.0650 - acc: 0.9800\n", + "Epoch 4/12\n", + "60000/60000 [==============================] - 7s 123us/sample - loss: 0.0541 - acc: 0.9839\n", + "Epoch 5/12\n", + "60000/60000 [==============================] - 7s 123us/sample - loss: 0.0476 - acc: 0.9850\n", + "Epoch 6/12\n", + "60000/60000 [==============================] - 8s 130us/sample - loss: 0.0391 - acc: 0.9883\n", + "Epoch 7/12\n", + "60000/60000 [==============================] - 8s 128us/sample - loss: 0.0354 - acc: 0.9889\n", + "Epoch 8/12\n", + "60000/60000 [==============================] - 8s 128us/sample - loss: 0.0330 - acc: 0.9895\n", + "Epoch 9/12\n", + "60000/60000 [==============================] - 7s 122us/sample - loss: 0.0283 - acc: 0.9909\n", + "Epoch 10/12\n", + "60000/60000 [==============================] - 7s 122us/sample - loss: 0.0275 - acc: 0.9909\n", + "Epoch 11/12\n", + "60000/60000 [==============================] - 7s 122us/sample - loss: 0.0265 - acc: 0.9918\n", + "Epoch 12/12\n", + "60000/60000 [==============================] - 7s 123us/sample - loss: 0.0239 - acc: 0.9922\n" + ], + "name": "stdout" + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 11 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "BybcqHVqEaQD", + "colab_type": "code", + "outputId": "9b5a41a0-9420-4387-8a01-5462c40878bd", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + } + }, + "source": [ + "score = model.evaluate(x_test, y_test, verbose=0)\n", + "print('Test loss:', score[0])\n", + "print('Test accuracy:', score[1])" + ], + "execution_count": 0, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Test loss: 0.028924251638433304\n", + "Test accuracy: 0.9922\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NNnMBuoURyaX", + "colab_type": "code", + "colab": {} + }, + "source": [ + "# Save for keras\n", + "model.save(\"model.h5\")" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Ia7WzlH9_UxY", + "colab_type": "code", + "outputId": "1d61e90a-f2a8-4ef8-8df2-301d61a89c8d", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 513 + } + }, + "source": [ + "!pip install tensorflowjs\n", + "import tensorflowjs as tfjs\n", + "\n", + "# Save for the web\n", + "tfjs.converters.save_keras_model(model, './js')" + ], + "execution_count": 0, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Requirement already satisfied: tensorflowjs in /usr/local/lib/python3.6/dist-packages (1.4.0)\n", + "Requirement already satisfied: six==1.11.0 in /usr/local/lib/python3.6/dist-packages (from tensorflowjs) (1.11.0)\n", + "Requirement already satisfied: tensorflow==1.15.0 in /usr/local/lib/python3.6/dist-packages (from tensorflowjs) (1.15.0)\n", + "Requirement already satisfied: h5py==2.8.0 in /usr/local/lib/python3.6/dist-packages (from tensorflowjs) (2.8.0)\n", + "Requirement already satisfied: gast==0.2.2 in /usr/local/lib/python3.6/dist-packages (from tensorflowjs) (0.2.2)\n", + "Requirement already satisfied: tensorflow-hub==0.5.0 in /usr/local/lib/python3.6/dist-packages (from tensorflowjs) (0.5.0)\n", + "Requirement already satisfied: numpy==1.16.4 in /usr/local/lib/python3.6/dist-packages (from tensorflowjs) (1.16.4)\n", + "Requirement already satisfied: PyInquirer==1.0.3 in /usr/local/lib/python3.6/dist-packages (from tensorflowjs) (1.0.3)\n", + "Requirement already satisfied: absl-py>=0.7.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow==1.15.0->tensorflowjs) (0.9.0)\n", + "Requirement already satisfied: protobuf>=3.6.1 in /usr/local/lib/python3.6/dist-packages (from tensorflow==1.15.0->tensorflowjs) (3.10.0)\n", + "Requirement already satisfied: tensorflow-estimator==1.15.1 in /usr/local/lib/python3.6/dist-packages (from tensorflow==1.15.0->tensorflowjs) (1.15.1)\n", + "Requirement already satisfied: wheel>=0.26 in /usr/local/lib/python3.6/dist-packages (from tensorflow==1.15.0->tensorflowjs) (0.33.6)\n", + "Requirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow==1.15.0->tensorflowjs) (1.1.0)\n", + "Requirement already satisfied: grpcio>=1.8.6 in /usr/local/lib/python3.6/dist-packages (from tensorflow==1.15.0->tensorflowjs) (1.15.0)\n", + "Requirement already satisfied: astor>=0.6.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow==1.15.0->tensorflowjs) (0.8.1)\n", + "Requirement already satisfied: keras-applications>=1.0.8 in /usr/local/lib/python3.6/dist-packages (from tensorflow==1.15.0->tensorflowjs) (1.0.8)\n", + "Requirement already satisfied: tensorboard<1.16.0,>=1.15.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow==1.15.0->tensorflowjs) (1.15.0)\n", + "Requirement already satisfied: google-pasta>=0.1.6 in /usr/local/lib/python3.6/dist-packages (from tensorflow==1.15.0->tensorflowjs) (0.1.8)\n", + "Requirement already satisfied: opt-einsum>=2.3.2 in /usr/local/lib/python3.6/dist-packages (from tensorflow==1.15.0->tensorflowjs) (3.1.0)\n", + "Requirement already satisfied: keras-preprocessing>=1.0.5 in /usr/local/lib/python3.6/dist-packages (from tensorflow==1.15.0->tensorflowjs) (1.1.0)\n", + "Requirement already satisfied: wrapt>=1.11.1 in /usr/local/lib/python3.6/dist-packages (from tensorflow==1.15.0->tensorflowjs) (1.11.2)\n", + "Requirement already satisfied: Pygments>=2.2.0 in /usr/local/lib/python3.6/dist-packages (from PyInquirer==1.0.3->tensorflowjs) (2.5.2)\n", + "Requirement already satisfied: prompt-toolkit==1.0.14 in /usr/local/lib/python3.6/dist-packages (from PyInquirer==1.0.3->tensorflowjs) (1.0.14)\n", + "Requirement already satisfied: regex>=2016.11.21 in /usr/local/lib/python3.6/dist-packages (from PyInquirer==1.0.3->tensorflowjs) (2019.12.20)\n", + "Requirement already satisfied: setuptools in /usr/local/lib/python3.6/dist-packages (from protobuf>=3.6.1->tensorflow==1.15.0->tensorflowjs) (42.0.2)\n", + "Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.6/dist-packages (from tensorboard<1.16.0,>=1.15.0->tensorflow==1.15.0->tensorflowjs) (0.16.0)\n", + "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.6/dist-packages (from tensorboard<1.16.0,>=1.15.0->tensorflow==1.15.0->tensorflowjs) (3.1.1)\n", + "Requirement already satisfied: wcwidth in /usr/local/lib/python3.6/dist-packages (from prompt-toolkit==1.0.14->PyInquirer==1.0.3->tensorflowjs) (0.1.8)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NriyjqVh_ge9", + "colab_type": "code", + "colab": {} + }, + "source": [ + "" + ], + "execution_count": 0, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/training/simple.py b/training/simple.py new file mode 100644 index 0000000..1918ef2 --- /dev/null +++ b/training/simple.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +"""simple.ipynb + +Automatically generated by Colaboratory. + +Original file is located at + https://colab.research.google.com/drive/1CGpActfOTQuiUkle2q40rg8Bf7ijfyAU +""" + +from tensorflow.keras.datasets import mnist +from tensorflow.keras.models import Sequential +from tensorflow.keras.layers import Dense, Dropout, Flatten +from tensorflow.keras.layers import Conv2D, MaxPooling2D +from tensorflow.keras.utils import to_categorical + +(x_train, y_train), (x_test, y_test) = mnist.load_data() + +# Reshaping for channels_last (tensorflow) with one channel +size = 28 +print(x_train.shape, x_test.shape) +x_train = x_train.reshape(len(x_train), size, size, 1).astype('float32') +x_test = x_test.reshape(len(x_test), size, size, 1).astype('float32') +print(x_train.shape, x_test.shape) + +# Normalize +upper = max(x_train.max(), x_test.max()) +lower = min(x_train.min(), x_test.min()) +print(f'Max: {upper} Min: {lower}') +x_train /= upper +x_test /= upper + +total_classes = 10 +y_train = to_categorical(y_train, total_classes) +y_test = to_categorical(y_test, total_classes) + +# Make the model +model = Sequential() +model.add(Conv2D(64, (3, 3), activation='relu', input_shape=(size,size, 1), data_format='channels_last')) +model.add(Conv2D(32, (3, 3), activation='relu')) +model.add(MaxPooling2D(pool_size=(2, 2))) +model.add(Dropout(0.25)) +model.add(Flatten()) +model.add(Dense(128, activation='relu')) +model.add(Dropout(0.5)) +model.add(Dense(total_classes, activation='softmax')) + +model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) + +# Train +model.fit(x_train, y_train, + batch_size=32, + epochs=12, + verbose=True) + +score = model.evaluate(x_test, y_test, verbose=0) +print('Test loss:', score[0]) +print('Test accuracy:', score[1]) + +# Save for keras +model.save("model.h5") + +!pip install tensorflowjs +import tensorflowjs as tfjs + +# Save for the web +tfjs.converters.save_keras_model(model, './js') +