{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "_cell_guid": "8ee8660a-b49b-d832-9e9c-1d2876e32b23"
      },
      "source": [
        ""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "b61f591f-ce27-c82c-c1e2-0b89222bc1c4"
      },
      "outputs": [],
      "source": [
        "# This Python 3 environment comes with many helpful analytics libraries installed\n",
        "# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n",
        "# For example, here's several helpful packages to load in \n",
        "\n",
        "import numpy as np # linear algebra\n",
        "import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n",
        "\n",
        "# Input data files are available in the \"../input/\" directory.\n",
        "# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n",
        "\n",
        "from subprocess import check_output\n",
        "print(check_output([\"ls\", \"../input\"]).decode(\"utf8\"))\n",
        "\n",
        "# Any results you write to the current directory are saved as output."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "6113dac9-d95c-08c5-716e-9c83ff11c737"
      },
      "outputs": [],
      "source": [
        "from keras.models import Sequential\n",
        "from keras.layers import Dense, Dropout, Flatten\n",
        "from keras.layers import Convolution2D, MaxPooling2D\n",
        "from keras.optimizers import SGD\n",
        "from keras.utils import np_utils\n",
        "\n",
        "\n",
        "# Caricamento delle librerie generiche\n",
        "import numpy as np\n",
        "import matplotlib.pyplot as plt\n",
        "import pandas as pd\n",
        "from sklearn.model_selection import train_test_split"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "6309e22b-708c-7f55-00f1-1cffd75f249c"
      },
      "outputs": [],
      "source": [
        "train=pd.read_csv('../input/train.csv')\n",
        "test=pd.read_csv('../input/test.csv')"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "fb179888-d21e-fba4-67a0-8d3c52cc8952"
      },
      "outputs": [],
      "source": [
        "# Creo un validation set da passare come parametro alla rete grande come il 10% dell'intero train usando TRAIN-TEST-SPLIT\n",
        "\n",
        "T,Val=train_test_split(train, test_size=0.05, train_size=0.95)\n",
        "\n",
        "# il .value \u00e8 per far si che siano dei numpy array visto che le KERAS cnn non prendono in input i DATAFRAME\n",
        "T_y=T.label.values\n",
        "T_x=T.drop(['label'],axis=1).values\n",
        "\n",
        "Val_y=Val.label.values\n",
        "Val_x=Val.drop(['label'],axis=1).values\n",
        "\n",
        "# Ora per poter mandare questi dati in ingresso alla rete si deve fare un reshape in 28x28"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "fd7e1c77-495b-a0dd-095b-7c083c172a2b"
      },
      "outputs": [],
      "source": [
        "# Ora sono array di matrici 28 x 28\n",
        "\n",
        "T_x=T_x.reshape(-1,1,28,28)\n",
        "Val_x=Val_x.reshape(-1,1,28,28)\n",
        "\n",
        "print (T_x.shape)\n",
        "print (Val_x.shape)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "a5dcdd5f-9aac-3026-70b3-f23d3ee6232b"
      },
      "outputs": [],
      "source": [
        "T_y=np_utils.to_categorical(T_y,10)\n",
        "Val_y=np_utils.to_categorical(Val_y,10)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "1c691a2d-8cb9-16ae-f7c3-670010414e39"
      },
      "outputs": [],
      "source": [
        "# provo con un semplice layer convoluzionale e uno di pooling per iniziare\n",
        "\n",
        "model=Sequential()\n",
        "\n",
        "#Convoluzionale\n",
        "model.add(Convolution2D(32,3,3,input_shape=(1,28,28),activation='relu',border_mode='same'))\n",
        "# usiamo 32 filtri di dimensione 3x3 , va specificato la dimensione dell'input che nel mio caso sono\n",
        "# le immagini 28x28x1(che \u00e8 come se fosse la profondit\u00e0--> se ci fossero i valori RGB cio\u00e8 3 valori per pixel avrei x3),\n",
        "# come activation function si potrebbe utilizzare la sigmoide ma si preferisce la RELU che \u00e8 una sigmoide migliorata per le rete neurali\n",
        "\n",
        "# Visto che il contenuto informativo del bordo nelle nostre immagini non \u00e8 troppo importante(Spesso sono pixel neri)\n",
        "# Anche se potremmo adottare una gestione FULL (perch\u00e8 utilizziamo THEANO) utilizziamo un 'same'\n",
        "\n",
        "model.add(Convolution2D(32, 3, 3, border_mode='same'))\n",
        "\n",
        "#Pooling \n",
        "# Ora non vanno speicificate le dimensioni dell'input perch\u00e8 si adatta automaticamente a quelle del layer \n",
        "# inserito con l'ultimo add\n",
        "\n",
        "model.add(MaxPooling2D(pool_size=(2,2),dim_ordering='th'))\n",
        "\n",
        "model.add(Dropout(0.3))\n",
        "\n",
        "# Ora \u00e8 necessario utilizzare un FLATTEN layer per riportare il tutto in maniera vettoriale e mandare in ingresso \n",
        "# a una FULL CONNETTED NN , non specifico parametri del FLATTEN perch\u00e8 dovrebbe settari in automatico\n",
        "\n",
        "model.add(Flatten())\n",
        "\n",
        "# Ora inserisco un layer DENSE ovvero il primo della FCNN con 64 nodi e activation sempre RELU\n",
        "\n",
        "model.add(Dense(128,activation='relu'))\n",
        "\n",
        "# Utilizzando un layer di pooling appena prima del FLatten si ottiene un errore perch\u00e8 si sta riducendo di troppo\n",
        "# la dimensione e quindi flatten ottiene un input con una dimensione = 0 , per ora risolvo il problema ignorando\n",
        "# il layer di pooling ( altrimenti potrei espandere le dimensioni due volte --> due convulutional2D prima del pooling)\n",
        "\n",
        "# Ora va inserito l'ultimo dense layer per la classificazione con 10 nodi e l'activation SOFTMAX in modo da avere \n",
        "# su ogni nodo la probabilit\u00e0 di ogni classe\n",
        "model.add(Dropout(0.3))\n",
        "model.add(Dense(10,activation='softmax'))\n",
        "\n",
        "# Ora che ho inserito i layer nella rete si deve"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "a736fa1a-2975-a5ef-76fb-add8779b6fde"
      },
      "outputs": [],
      "source": [
        "# COMPILE :\n",
        "# - Specificare l'ottimizzatore ----> Stocasthic gradient descend in prima istanza\n",
        "# - il tipo di loss che sar\u00e0 categorical_crossentropy perch\u00e8 un porblema multi classe e per l'appunto utilizziamo quella\n",
        "# rappresentazione delle label vista prima\n",
        "# - e la metrica che sar\u00e0 ACCURACy\n",
        "model.compile(optimizer='adadelta',loss='categorical_crossentropy', metrics=['accuracy'])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "b00df20e-9658-de94-0021-48f9ceaf0982"
      },
      "outputs": [],
      "source": [
        "batches=128 # numero di campioni per ogni ottimizzazione\n",
        "epochs= 28 # Numero dei passaggi \n",
        "\n",
        "hist=model.fit(T_x,T_y, batch_size=batches, nb_epoch=epochs, validation_data=(Val_x,Val_y),verbose=0)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "807a28f4-f305-ac16-e22b-715468a67610"
      },
      "outputs": [],
      "source": [
        "\n",
        "# Traccio un grafico del variare della LOSS  e della ACCURACY con le iterazioni\n",
        "# sfruttando .history() di hist . Ma prima faccio un .evalutate su val_x e val_y\n",
        "\n",
        "scores = model.evaluate(T_x,T_y, verbose=0)\n",
        "\n",
        "print (scores)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "01251b11-991f-3e16-15a0-07a6fd4d221a"
      },
      "outputs": [],
      "source": [
        "# tracciamento del grafico della LOSS e VAL-LOSS al passo di iterazione\n",
        "plt.plot(hist.history['loss'])\n",
        "plt.plot(hist.history['val_loss'])\n",
        "plt.title('Loss Rate')\n",
        "plt.ylabel('Loss')\n",
        "plt.xlabel('Training interations')\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "617e115b-fb1c-2224-0372-006fbc8fe0f9"
      },
      "outputs": [],
      "source": [
        "# E tracciamento del gradfico degli score\n",
        "\n",
        "plt.plot(hist.history['val_acc'])\n",
        "plt.title('Accuracy Rate')\n",
        "plt.ylabel('Accuracy %')\n",
        "plt.xlabel('Training iterations')\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "5352dbc8-956a-dbb4-68f8-541ee430dda3"
      },
      "outputs": [],
      "source": [
        "scores = model.evaluate(Val_x,Val_y, verbose=0)\n",
        "\n",
        "print (scores)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "0459ebeb-0bf4-1b0e-a74a-62e236ab44d2"
      },
      "outputs": [],
      "source": [
        "# Caricamento e predizione sul test\n",
        "test=test.values\n",
        "test=test.reshape(-1,1,28,28)\n",
        "predicition=model.predict_classes(test,verbose=0)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "0bf08711-031c-472b-b4fb-38073e01b800"
      },
      "outputs": [],
      "source": [
        "Risultati=pd.DataFrame()\n",
        "Risultati['ImageId']=list(range(1,len(test)+1))\n",
        "Risultati['Label']=predicition\n",
        "Risultati.to_csv('result_CNN.csv',index=False)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "_cell_guid": "10244ae6-1cce-817f-4f1b-a830b78d9550"
      },
      "outputs": [],
      "source": [
        ""
      ]
    }
  ],
  "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
}