jhfjhfj1/autokeras

View on GitHub
docs/ipynb/image_classification.ipynb

Summary

Maintainability
Test Coverage
{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab_type": "code"
   },
   "outputs": [],
   "source": [
    "!pip install autokeras"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab_type": "code"
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from keras.datasets import mnist\n",
    "\n",
    "import autokeras as ak"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text"
   },
   "source": [
    "## A Simple Example\n",
    "The first step is to prepare your data. Here we use the MNIST dataset as an\n",
    "example\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab_type": "code"
   },
   "outputs": [],
   "source": [
    "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n",
    "x_train = x_train[:100]\n",
    "y_train = y_train[:100]\n",
    "x_test = x_test[:100]\n",
    "y_test = y_test[:100]\n",
    "print(x_train.shape)  # (60000, 28, 28)\n",
    "print(y_train.shape)  # (60000,)\n",
    "print(y_train[:3])  # array([7, 2, 1], dtype=uint8)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text"
   },
   "source": [
    "The second step is to run the ImageClassifier.\n",
    "It is recommended have more trials for more complicated datasets.\n",
    "This is just a quick demo of MNIST, so we set max_trials to 1.\n",
    "For the same reason, we set epochs to 10.\n",
    "You can also leave the epochs unspecified for an adaptive number of epochs.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab_type": "code"
   },
   "outputs": [],
   "source": [
    "# Initialize the image classifier.\n",
    "clf = ak.ImageClassifier(overwrite=True, max_trials=1)\n",
    "# Feed the image classifier with training data.\n",
    "clf.fit(x_train, y_train, epochs=1)\n",
    "\n",
    "\n",
    "# Predict with the best model.\n",
    "predicted_y = clf.predict(x_test)\n",
    "print(predicted_y)\n",
    "\n",
    "\n",
    "# Evaluate the best model with testing data.\n",
    "print(clf.evaluate(x_test, y_test))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text"
   },
   "source": [
    "## Validation Data\n",
    "By default, AutoKeras use the last 20% of training data as validation data. As\n",
    "shown in the example below, you can use validation_split to specify the\n",
    "percentage.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab_type": "code"
   },
   "outputs": [],
   "source": [
    "clf.fit(\n",
    "    x_train,\n",
    "    y_train,\n",
    "    # Split the training data and use the last 15% as validation data.\n",
    "    validation_split=0.15,\n",
    "    epochs=1,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text"
   },
   "source": [
    "You can also use your own validation set instead of splitting it from the\n",
    "training data with validation_data.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab_type": "code"
   },
   "outputs": [],
   "source": [
    "split = 50000\n",
    "x_val = x_train[split:]\n",
    "y_val = y_train[split:]\n",
    "x_train = x_train[:split]\n",
    "y_train = y_train[:split]\n",
    "clf.fit(\n",
    "    x_train,\n",
    "    y_train,\n",
    "    # Use your own validation set.\n",
    "    validation_data=(x_val, y_val),\n",
    "    epochs=1,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text"
   },
   "source": [
    "## Customized Search Space\n",
    "For advanced users, you may customize your search space by using AutoModel\n",
    "instead of ImageClassifier. You can configure the ImageBlock for some\n",
    "high-level configurations, e.g., block_type for the type of neural network to\n",
    "search, normalize for whether to do data normalization, augment for whether to\n",
    "do data augmentation. You can also do not specify these arguments, which would\n",
    "leave the different choices to be tuned automatically. See the following\n",
    "example for detail.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab_type": "code"
   },
   "outputs": [],
   "source": [
    "input_node = ak.ImageInput()\n",
    "output_node = ak.ImageBlock(\n",
    "    # Only search ResNet architectures.\n",
    "    block_type=\"resnet\",\n",
    "    # Normalize the dataset.\n",
    "    normalize=True,\n",
    "    # Do not do data augmentation.\n",
    "    augment=False,\n",
    ")(input_node)\n",
    "output_node = ak.ClassificationHead()(output_node)\n",
    "clf = ak.AutoModel(\n",
    "    inputs=input_node, outputs=output_node, overwrite=True, max_trials=1\n",
    ")\n",
    "clf.fit(x_train, y_train, epochs=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text"
   },
   "source": [
    "The usage of AutoModel is similar to the functional API of Keras. Basically, you\n",
    "are building a graph, whose edges are blocks and the nodes are intermediate\n",
    "outputs of blocks. To add an edge from input_node to output_node with\n",
    "output_node = ak.[some_block]([block_args])(input_node).\n",
    "\n",
    "You can even also use more fine grained blocks to customize the search space\n",
    "even further. See the following example.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab_type": "code"
   },
   "outputs": [],
   "source": [
    "input_node = ak.ImageInput()\n",
    "output_node = ak.Normalization()(input_node)\n",
    "output_node = ak.ImageAugmentation(horizontal_flip=False)(output_node)\n",
    "output_node = ak.ResNetBlock(version=\"v2\")(output_node)\n",
    "output_node = ak.ClassificationHead()(output_node)\n",
    "clf = ak.AutoModel(\n",
    "    inputs=input_node, outputs=output_node, overwrite=True, max_trials=1\n",
    ")\n",
    "clf.fit(x_train, y_train, epochs=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text"
   },
   "source": [
    "## Data Format\n",
    "The AutoKeras ImageClassifier is quite flexible for the data format.\n",
    "\n",
    "For the image, it accepts data formats both with and without the channel\n",
    "dimension. The images in the MNIST dataset do not have the channel dimension.\n",
    "Each image is a matrix with shape (28, 28). AutoKeras also accepts images of\n",
    "three dimensions with the channel dimension at last, e.g., (32, 32, 3), (28,\n",
    "28, 1).\n",
    "\n",
    "For the classification labels, AutoKeras accepts both plain labels, i.e.\n",
    "strings or integers, and one-hot encoded encoded labels, i.e. vectors of 0s and\n",
    "1s.\n",
    "\n",
    "So if you prepare your data in the following way, the ImageClassifier should\n",
    "still work.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab_type": "code"
   },
   "outputs": [],
   "source": [
    "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n",
    "\n",
    "# Reshape the images to have the channel dimension.\n",
    "x_train = x_train.reshape(x_train.shape + (1,))\n",
    "x_test = x_test.reshape(x_test.shape + (1,))\n",
    "\n",
    "# One-hot encode the labels.\n",
    "eye = np.eye(10)\n",
    "y_train = eye[y_train]\n",
    "y_test = eye[y_test]\n",
    "\n",
    "print(x_train.shape)  # (60000, 28, 28, 1)\n",
    "print(y_train.shape)  # (60000, 10)\n",
    "print(y_train[:3])\n",
    "# array([[0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],\n",
    "#        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
    "#        [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.]])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text"
   },
   "source": [
    "We also support using tf.data.Dataset format for the training data.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab_type": "code"
   },
   "outputs": [],
   "source": [
    "train_set = tf.data.Dataset.from_tensor_slices(((x_train,), (y_train,)))\n",
    "test_set = tf.data.Dataset.from_tensor_slices(((x_test,), (y_test,)))\n",
    "\n",
    "clf = ak.ImageClassifier(overwrite=True, max_trials=1)\n",
    "# Feed the tensorflow Dataset to the classifier.\n",
    "clf.fit(train_set, epochs=1)\n",
    "# Predict with the best model.\n",
    "predicted_y = clf.predict(test_set)\n",
    "# Evaluate the best model with testing data.\n",
    "print(clf.evaluate(test_set))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text"
   },
   "source": [
    "## Reference\n",
    "[ImageClassifier](/image_classifier),\n",
    "[AutoModel](/auto_model/#automodel-class),\n",
    "[ImageBlock](/block/#imageblock-class),\n",
    "[Normalization](/block/#normalization-class),\n",
    "[ImageAugmentation](/block/#image-augmentation-class),\n",
    "[ResNetBlock](/block/#resnetblock-class),\n",
    "[ImageInput](/node/#imageinput-class),\n",
    "[ClassificationHead](/block/#classificationhead-class).\n"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "name": "image_classification",
   "private_outputs": false,
   "provenance": [],
   "toc_visible": true
  },
  "kernelspec": {
   "display_name": "Python 3",
   "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.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}