Created
March 6, 2019 10:30
-
-
Save Gijs-Koot/686587b4bb95013d381b7f4d552b54b5 to your computer and use it in GitHub Desktop.
colab-mnist-tutorial.ipynb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"nbformat": 4, | |
"nbformat_minor": 0, | |
"metadata": { | |
"colab": { | |
"name": "colab-mnist-tutorial.ipynb", | |
"version": "0.3.2", | |
"provenance": [], | |
"collapsed_sections": [], | |
"include_colab_link": true | |
}, | |
"kernelspec": { | |
"name": "python3", | |
"display_name": "Python 3" | |
} | |
}, | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "view-in-github", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"<a href=\"https://colab.research.google.com/gist/Gijs-Koot/686587b4bb95013d381b7f4d552b54b5/colab-mnist-tutorial.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" | |
] | |
}, | |
{ | |
"metadata": { | |
"id": "yGtbkw5cIHqM", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"## this imports some software that we need for the tutorial\n", | |
"\n", | |
"from PIL import Image, ImageChops, ImageMath\n", | |
"import matplotlib.pyplot as plt\n", | |
"import numpy as np" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "GLL2iSrMIYnT", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"## load the dataset, download from google if needed\n", | |
"\n", | |
"from tensorflow.keras.datasets import mnist\n", | |
"\n", | |
"(train_images, train_labels), (test_images, test_labels) = mnist.load_data()\n", | |
"\n", | |
"print(f\"Dimensions of train data: {train_images.shape}\")\n", | |
"print(f\"Dimensions of test data: {test_images.shape}\")" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "SYQxjy65L38R", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"## this code shows some of the images in our trainset\n", | |
"\n", | |
"fig, axes = plt.subplots(10, 10, figsize=(10, 10), sharex=True, sharey=True)\n", | |
"\n", | |
"for i in range(10):\n", | |
" for j in range(10):\n", | |
" axes[i,j].imshow(train_images[i * 10 + j])" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "78hXplpuVWPg", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"## these are the labels\n", | |
"\n", | |
"train_labels[:100]" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "E-SRbU_DUJyk", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"## to get a single training (or test) instance, you can index with a number\n", | |
"\n", | |
"train_images[1]" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "KpvBXHS8Tn0x", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"## this is an array with pixel values, with the code below you can see the image\n", | |
"plt.imshow(train_images[230])" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "rSC-UA-OUp-1", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"## for training we want the pixel values to be between 0 and 1, and instead of a matrix, we want a single vector of length 784\n", | |
"\n", | |
"X_train = train_images.reshape(60000, -1) / 255\n", | |
"X_test = test_images.reshape(10000, -1) / 255\n", | |
"\n", | |
"X_train[230]" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "TIfbHm6sVp-e", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"## another way to look at the training data - no problem for a computer but no human would be able to recognize a seven in this image\n", | |
"\n", | |
"plt.plot(np.arange(784), X_train[230])" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "MBWgRr-BLwPZ", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"## this is the point of the tutorial\n", | |
"## creating a neural network is easy and very concrete\n", | |
"\n", | |
"from tensorflow.keras import models, layers\n", | |
"\n", | |
"model = models.Sequential()\n", | |
"\n", | |
"## we have one hidden layer with 512 \"neurons\"\n", | |
"model.add(layers.Dense(512, activation='relu', input_shape=(784,)))\n", | |
"\n", | |
"## output has 10 neurons, corresponding to 10 digits\n", | |
"model.add(layers.Dense(10, activation='softmax'))" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "U6QKajKBJWD0", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"## with this line, we tell how to optimize and which metrics to track\n", | |
"## the model is actually compiled to run on the GPU\n", | |
"\n", | |
"model.compile(optimizer='rmsprop', loss='sparse_categorical_crossentropy', metrics=['accuracy'])" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "R5yIvmCfhFea", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"model.summary()" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "Vpwn_y1OPGsA", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"## this line starts the training\n", | |
"## you can see the error on the trainset and the error on the testset\n", | |
"## after how many epochs does the model start overfitting?\n", | |
"\n", | |
"hist = model.fit(X_train, train_labels, epochs=10, batch_size=32, validation_data=(X_test, test_labels))" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "dUiuo9ngYjVu", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"## reported accuracy is 98%, let's see\n", | |
"\n", | |
"test_sample = X_test[100]\n", | |
"\n", | |
"plt.imshow(test_sample.reshape(28, 28))" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "7VIBiWaiY2ND", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"test_labels[100]" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "XH1K22CtaCuf", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"## a technical challenge, the model outputs probabilities, not the actual label\n", | |
"\n", | |
"model.predict(X_test[100].reshape(1,-1))" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "WWdnr1umZCux", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"## here is a helper function to convert dimensions and translate the probabilities\n", | |
"\n", | |
"def get_model_prediction(model, sample):\n", | |
" sample = np.asarray(sample)\n", | |
" if sample.shape in [(28, 28), (784,)]:\n", | |
" p = model.predict(sample.reshape(1, -1))\n", | |
" else:\n", | |
" raise Exception(f\"Wrong input dimension: {sample.shape}\")\n", | |
" return np.argmax(p)" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "R5U-8nyRZrj6", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"get_model_prediction(model, X_test[100])" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "QUDwb45hcooh", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"## here is a function that allows you to upload files\n", | |
"\n", | |
"from google.colab import files\n", | |
"\n", | |
"def upload_image():\n", | |
"\n", | |
" uploaded = files.upload()\n", | |
" arr = np.asarray(Image.open(list(uploaded.keys())[0]))\n", | |
" arr = arr.max(axis = 2)\n", | |
" return 1 - arr / arr.max()" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "j3gLXn9Kds3I", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"img = upload_image()" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "dysZbxEVfWc4", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"plt.imshow(img)" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "od3hI-85eXnI", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"get_model_prediction(model, img)" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment