{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "a42d8335-7241-0a78-ff14-7a761c9beecf"
      },
      "outputs": [],
      "source": [
        "%matplotlib inline\n",
        "import mxnet as mx\n",
        "import numpy as np\n",
        "import matplotlib.pyplot as plt\n",
        "import logging\n",
        "\n",
        "logger = logging.getLogger()\n",
        "logger.setLevel(logging.DEBUG)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "b3a3cce9-8501-a8a4-952a-623279a96bdb"
      },
      "outputs": [],
      "source": [
        "# Variables are place holders for input arrays. We give each variable a unique name.\n",
        "data = mx.symbol.Variable('data')\n",
        "\n",
        "# The input is fed to a fully connected layer that computes Y=WX+b.\n",
        "# This is the main computation module in the network.\n",
        "# Each layer also needs an unique name. We'll talk more about naming in the next section.\n",
        "fc1  = mx.symbol.FullyConnected(data = data, name='fc1', num_hidden=128)\n",
        "# Activation layers apply a non-linear function on the previous layer's output.\n",
        "# Here we use Rectified Linear Unit (ReLU) that computes Y = max(X, 0).\n",
        "act1 = mx.symbol.Activation(data = fc1, name='relu1', act_type=\"relu\")\n",
        "\n",
        "fc2  = mx.symbol.FullyConnected(data = act1, name = 'fc2', num_hidden = 64)\n",
        "act2 = mx.symbol.Activation(data = fc2, name='relu2', act_type=\"relu\")\n",
        "\n",
        "fc3  = mx.symbol.FullyConnected(data = act2, name='fc3', num_hidden=10)\n",
        "# Finally we have a loss layer that compares the network's output with label and generates gradient signals.\n",
        "mlp  = mx.symbol.SoftmaxOutput(data = fc3, name = 'softmax')\n",
        "mx.viz.plot_network(mlp)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "230ac3e2-d0bc-bf56-2f0b-3d2ae957833a"
      },
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "import pandas as pd\n",
        "# load data to numpy\n",
        "\n",
        "train_file ='../input/train.csv'\n",
        "test_file = \"../input/test.csv\"\n",
        "result_file = '../input/submission.csv'\n",
        "\n",
        "df_train_data = pd.read_csv(train_file)\n",
        "df_test_data = pd.read_csv(test_file)\n",
        "\n",
        "label = np.array(df_train_data.pop('label'), dtype=int)\n",
        "train_data = np.array(df_train_data.values, dtype=float)\n",
        "test_data = np.array(df_test_data.values, dtype=float)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "5241ccc3-5c5f-dc08-6ef1-532a144cbd40"
      },
      "outputs": [],
      "source": [
        "# plot data as grey image\n",
        "for i in range(10):\n",
        "    plt.subplot(1, 10, i + 1)\n",
        "    plt.imshow(train_data[i].reshape(28, 28) * 255, cmap='Greys_r')\n",
        "    plt.axis('off')\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "737836e7-7258-83de-dfe7-301e13bf490c"
      },
      "outputs": [],
      "source": [
        "# sub mean value\n",
        "mean_data = np.mean(train_data, axis=0)\n",
        "X_train = (train_data - mean_data)/128\n",
        "Y_train = label\n",
        "X_test = (test_data - mean_data)/128\n",
        "\n",
        "print(X_train.shape, X_test.shape)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "759304e0-702c-ae11-f9cd-49823e6720ff"
      },
      "outputs": [],
      "source": [
        "batch_size = 128\n",
        "train_iter = mx.io.NDArrayIter(X_train, Y_train, batch_size=batch_size)\n",
        "test_iter = None"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "ba372870-df04-8165-e230-fa9bc582ff45"
      },
      "outputs": [],
      "source": [
        "data = data.astype(np.float32) / 255\n",
        "data_test = data_test.astype(np.float32) / 255"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "53898b7c-f5d0-e687-f69b-81ca7f13e8d7"
      },
      "outputs": [],
      "source": [
        "model = mx.model.FeedForward(\n",
        "    ctx = mx.cpu(0),      # Run on GPU 0\n",
        "    symbol = mlp,         # Use the network we just defined\n",
        "    num_epoch = 15,       # Train for 10 epochs\n",
        "    learning_rate = 0.1,  # Learning rate\n",
        "    momentum = 0.9,       # Momentum for SGD with momentum\n",
        "    wd = 0.00001)\n",
        "model.fit(\n",
        "    X=train_iter,  # Training data set\n",
        "    eval_data=test_iter,  # Testing data set. MXNet computes scores on test set every epoch\n",
        "    batch_end_callback = mx.callback.Speedometer(batch_size, 100))  # Logging module to print out progress"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "3b95861d-697d-3199-5250-4df1b18320e4",
        "collapsed": true
      },
      "outputs": [],
      "source": ""
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "7aadbf65-a0f7-0075-0b2b-91d43889ab0c"
      },
      "outputs": [],
      "source": [
        "# Predict the test data\n",
        "result = []\n",
        "for i in range(X_test.shape[0]):\n",
        "    label = model.predict(X_test[i:i+1])[0].argmax()\n",
        "    result.append(label)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "bd776e3a-2256-00cf-9f37-ce68b4a09a26"
      },
      "outputs": [],
      "source": [
        "submission = pd.DataFrame(data={'ImageId':(np.arange(len(result)) + 1), 'Label':np.array(result)})\n",
        "submission.to_csv('./submission.csv', index=False)\n",
        "submission.tail()"
      ]
    }
  ],
  "metadata": {
    "_change_revision": 0,
    "_is_fork": false,
    "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.6.0"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}