{"cells":[{"metadata":{"_cell_guid":"8c56a778-ba24-4d51-a89d-a16b7da3f47c","_uuid":"a04a2a1268aabc722a26e5aada6921afd8b19e2f"},"cell_type":"markdown","source":"# CNN Model Intro with Fashion MNIST Implementation\n### Brief Introduction\nThis notebook will cover the following two major topics :\n\n#### Understand the basic concepts of CNN model\n#### Implement CNN model in realtime using Fashion MNIST dataset\n\n## Understand the basic concepts of CNN model :\n\nMankind is an awesome natural machine and is capable of looking at multiple images every second and process them without realizing how the processing is done. But same is not with machines. \n\nThe first step in image processing is to understand, how to represent an image so that the machine can read it?\n\nEvery image is an cumulative arrangement of dots (a pixel) arranged in a special order. If you change the order or color of a pixel, the image would change as well. \n\n![](https://ujwlkarn.files.wordpress.com/2016/08/screen-shot-2016-08-07-at-9-15-21-pm.png)\nThree basic components to define a basic convolutional neural network.\n\n### The Convolutional Layer\n### The Pooling layer\n### The Output layer\n\nLet’s see each of them in detail\n\n### The Convolutional Layer :\n\nIn this layer if we have an image of size 6*6. We define a weight matrix which extracts certain features from the images*\n![](https://cdn.analyticsvidhya.com/wp-content/uploads/2017/06/28010254/conv1.png)\nWe have initialized the weight as a 3*3 matrix. This weight shall now run across the image such that all the pixels are covered at least once, to give a convolved output. The value 429 above, is obtained by the adding the values obtained by element wise multiplication of the weight matrix and the highlighted 3*3 part of the input image.\n![](https://cdn.analyticsvidhya.com/wp-content/uploads/2017/06/28011851/conv.gif)\nThe 6*6 image is now converted into a 4*4 image.  Think of weight matrix like a paint brush painting a wall. The brush first paints the wall horizontally and then comes down and paints the next row horizontally. Pixel values are used again when the weight matrix moves along the image. This basically enables parameter sharing in a convolutional neural network.\n\nLet’s see how this looks like in a real image.\n![](https://cdn.analyticsvidhya.com/wp-content/uploads/2017/06/28132834/convimages.png)\n\n* The weight matrix behaves like a filter in an image, extracting particular information from the original image matrix. \n* A weight combination might be extracting edges, while another one might a particular color, while another one might just blur the unwanted noise.\n* The weights are learnt such that the loss function is minimized and extract features from the original image which help the network in correct prediction.\n* When we use multiple convolutional layers, the initial layer extract more generic features,and as network gets deeper the features get complex.\n\nLet us understand some concepts here before we go further deep\n\n#### What is Stride?\n\nAs shown above above, the filter or the weight matrix we moved across the entire image moving one pixel at a time.If this is a hyperparameter to move weight matrix 1 pixel at a time across image it is called as stride of 1. Let us see for stride of 2 how it looks.\n![](https://cdn.analyticsvidhya.com/wp-content/uploads/2017/06/28090227/stride1.gif)\n\nAs you can see the size of image keeps on reducing as we increase the stride value. \n\nPadding the input image with zeros across it solves this problem for us. We can also add more than one layer of zeros around the image in case of higher stride values.\n![](https://cdn.analyticsvidhya.com/wp-content/uploads/2017/06/28093553/zero-padding.png)\nWe can see how the initial shape of the image is retained after we padded the image with a zero. This is known as same padding since the output image has the same size as the input. \n![](https://cdn.analyticsvidhya.com/wp-content/uploads/2017/06/28094927/padding.gif)\nThis is known as same padding (which means that we considered only the valid pixels of the input image). The middle 4*4 pixels would be the same. Here we have retained more information from the borders and have also preserved the size of the image.\n\n#### Having Multiple filters & the Activation Map\n\n* The depth dimension of the weight would be same as the depth dimension of the input image.\n* The weight extends to the entire depth of the input image. \n* Convolution with a single weight matrix would result into a convolved output with a single depth dimension. In case of multiple filters all have same dimensions applied together.\n* The output from the each filter is stacked together forming the depth dimension of the convolved image. \n\nSuppose we have an input image of size 32*32*3. And we apply 10 filters of size 5*5*3 with valid padding. The output would have the dimensions as 28*28*10.\n\nYou can visualize it as –\n![](https://cdn.analyticsvidhya.com/wp-content/uploads/2017/06/28113904/activation-map.png)\nThis activation map is the output of the convolution layer.\n\n### The Pooling Layer\n\nIf images are big in size, we would need to reduce the no.of trainable parameters.For this we need to use pooling layers between convolution layers. Pooling is used for reducing the spatial size of the image and is implemented independently on each depth dimension resulting in no change in image depth. Max pooling is the most popular form of pooling layer.\n![](https://cdn.analyticsvidhya.com/wp-content/uploads/2017/06/28022816/maxpool.png)\nHere we have taken stride as 2, while pooling size also as 2. The max operation is applied to each depth dimension of the convolved output. As you can see, the 4*4 convolved output has become 2*2 after the max pooling operation.\n\nLet’s see how max pooling looks on a real image.\n![](https://cdn.analyticsvidhya.com/wp-content/uploads/2017/06/28133544/pooling.png)\nIn the above image we have taken a convoluted image and applied max pooling on it which resulted in still retaining the image information that is a car but if we closely observe the dimensions of the image is reduced to half which basically means we can reduce the parameters to a great number.\n\nThere are other forms of pooling like average pooling, L2 norm pooling.\n\n#### Output dimensions\n\nIt is tricky at times to understand the input and output dimensions at the end of each convolution layer. For this we will use three hyperparameters that would control the size of output volume.\n\n1. No of Filter: The depth of the output volume will be equal to the number of filter applied.The depth of the activation map will be equal to the number of filters.\n\n2. Stride – When we have a stride of one we move across and down a single pixel. With higher stride values, we move large number of pixels at a time and hence produce smaller output volumes.\n\n3. Zero padding – This helps us to preserve the size of the input image. If a single zero padding is added, a single stride filter movement would retain the size of the original image.\n\nWe can apply a simple formula to calculate the output dimensions.\n\nThe spatial size of the output image can be calculated as( [W-F+2P]/S)+1. \nwhere, W is the input volume size, \n       F is the size of the filter, \n       P is the number of padding applied \n       S is the number of strides. \n       \nLet us take an example of an input image of size 64*64*3, we apply 10 filters of size 3*3*3, with single stride and no zero padding.\n\nHere W=64, F=3, P=0 and S=1. The output depth will be equal to the number of filters applied i.e. 10.\n\nThe size of the output volume will be ([64-3+0]/1)+1 = 62. Therefore the output volume will be 62*62*10.\n\n### The Output layer\n* With no of layers of convolution and padding, we need the output in the form of a class.\n* To generate the final output we need to apply a fully connected layer to generate an output equal to the number of classes we need.\n* Convolution layers generate 3D activation maps while we just need the output as whether or not an image belongs to a particular class. \n* The Output layer has a loss function like categorical cross-entropy, to compute the error in prediction. Once the forward pass is complete the backpropagation begins to update the weight and biases for error and loss reduction.\n\n### Summary:\n* Pass an input image to the first convolutional layer. The convoluted output is obtained as an activation map. The filters applied in the convolution layer extract relevant features from the input image to pass further.\n* Each filter shall give a different feature to aid the correct class prediction. In case we need to retain the size of the image, we use same padding(zero padding), otherwise valid padding is used since it helps to reduce the number of features.\n* Pooling layers are then added to further reduce the number of parameters\n* Several convolution and pooling layers are added before the prediction is made. Convolutional layer help in extracting features. As we go deeper in the network more specific features are extracted as compared to a shallow network where the features extracted are more generic.\n* The output layer in a CNN as mentioned previously is a fully connected layer, where the input from the other layers is flattened and sent so as the transform the output into the number of classes as desired by the network.\n* The output is then generated through the output layer and is compared to the output layer for error generation. A loss function is defined in the fully connected output layer to compute the mean square loss. The gradient of error is then calculated.\n* The error is then backpropagated to update the filter(weights) and bias values.\n* One training cycle is completed in a single forward and backward pass.\n\n### Implement CNN model in realtime using Fashion MNIST dataset\n\n![](https://pyimagesearch.com/wp-content/uploads/2019/02/fashion_mnist_dataset_sample.png)\nFashion-MNIST is a dataset of Zalando's article images—consisting of a training set of 60,000 examples and a test set of 10,000 examples. Each example is a 28x28 grayscale image, associated with a label from 10 classes. Zalando intends Fashion-MNIST to serve as a direct drop-in replacement for the original MNIST dataset for benchmarking machine learning algorithms. It shares the same image size and structure of training and testing splits.\nThe original MNIST dataset contains a lot of handwritten digits. Members of the AI/ML/Data Science community love this dataset and use it as a benchmark to validate their algorithms. In fact, MNIST is often the first dataset researchers try.  \"If it doesn't work on MNIST, it won't work at all\", they said. \"Well, if it does work on MNIST, it may still fail on others.\"\n\nZalando seeks to replace the original MNIST dataset\n\n### Data Description\n\n* Each image is 28 pixels in height and 28 pixels in width, for a total of 784 pixels in total.\n* Each pixel has a single pixel-value associated with it, indicating the lightness or darkness of that pixel, with higher numbers meaning darker. This pixel-value is an integer between 0 and 255. \n* The training and test data sets have 785 columns. \n* The first column consists of the class labels (see above), and represents the article of clothing. \n* The rest of the columns contain the pixel-values of the associated image.\n\nTo locate a pixel on the image, suppose that we have decomposed x as x = i * 28 + j, where i and j are integers between 0 and 27. The pixel is located on row i and column j of a 28 x 28 matrix.\nFor example, pixel31 indicates the pixel that is in the fourth column from the left, and the second row from the top, as in the ascii-diagram below. \n\n### Get the Data\n\nYou can use direct links to download the dataset.\n\n| Name  | Content | Examples | Size | Link | MD5 Checksum|\n| --- | --- |--- | --- |--- |--- |\n| `train-images-idx3-ubyte.gz`  | training set images  | 60,000|26 MBytes | [Download](http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz)|`8d4fb7e6c68d591d4c3dfef9ec88bf0d`|\n| `train-labels-idx1-ubyte.gz`  | training set labels  |60,000|29 KBytes | [Download](http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz)|`25c81989df183df01b3e8a0aad5dffbe`|\n| `t10k-images-idx3-ubyte.gz`  | test set images  | 10,000|4.3 MBytes | [Download](http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz)|`bef4ecab320f06d8554ea6380940ec79`|\n| `t10k-labels-idx1-ubyte.gz`  | test set labels  | 10,000| 5.1 KBytes | [Download](http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz)|`bb300cfdad3c16e7a12a480ee83cd310`|\n\nAlternatively, you can clone this GitHub repository; the dataset appears under `data/fashion`. This repo also contains some scripts for benchmark and visualization.\n   \n```bash\ngit clone git@github.com:zalandoresearch/fashion-mnist.git\n```\n\n#### Labels\nEach training and test example is assigned to one of the following labels:\n\n* 0 T-shirt/top \n* 1 Trouser\n* 2 Pullover\n* 3 Dress\n* 4 Coat\n* 5 Sandal\n* 6 Shirt\n* 7 Sneaker\n* 8 Bag\n* 9 Ankle boot \n\n#### TL;DR\n\n* Each row is a separate image\n* Column 1 is the class label.\n* Remaining columns are pixel numbers (784 total).\n* Each value is the darkness of the pixel (1 to 255)\n\n### Acknowledgements\n\n* Original dataset was downloaded from https://github.com/zalandoresearch/fashion-mnist\n\n* Dataset was converted to CSV with this script: https://pjreddie.com/projects/mnist-in-csv/","execution_count":null},{"metadata":{"_cell_guid":"dec05004-ccb3-490e-b588-27c0f4f06d1e","_uuid":"41907ec74cae883fa8d56f6556cade5c67c8f3e0","trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"from subprocess import check_output\nprint(check_output([\"ls\", \"../input\"]).decode(\"utf8\"))\nimport pandas as pd\nimport numpy as np\nimport warnings\nwarnings.filterwarnings('ignore')\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nimport keras\nfrom keras.models import Sequential\nfrom keras.layers import Conv2D,MaxPooling2D,Dense,Flatten,Dropout\nfrom keras.optimizers import Adam\nfrom keras.callbacks import TensorBoard\nnum_classes = 10\nepochs = 20","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"07e7dc997f3a62c3d36021550c1313a10bab4d1b"},"cell_type":"markdown","source":"**Create dataframes for train and test datasets**","execution_count":null},{"metadata":{"trusted":true,"_uuid":"994c029e48618920f7e363e8397712286e351ad4","_kg_hide-input":true},"cell_type":"code","source":"train_df = pd.read_csv('../input/fashionmnist/fashion-mnist_train.csv',sep=',')\ntest_df = pd.read_csv('../input/fashionmnist/fashion-mnist_test.csv', sep = ',')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a1673df4108e5ac8fc4c32f05c4dd025c0db8458"},"cell_type":"markdown","source":"Let us explore the train and test data","execution_count":null},{"metadata":{"trusted":true,"_uuid":"42309d6099a4bb2da08538183ddba8f7a6373a62","_kg_hide-input":true},"cell_type":"code","source":"train_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ea8cf38825ba66ec04a532c8012dcbdbe9d2b01d","_kg_hide-input":true},"cell_type":"code","source":"test_df.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8e1fbecf244157e5e8b7660d812be8200882cdd2"},"cell_type":"markdown","source":"Now it is observed that the first column is the label data and because it has 10 classes so it is going to have from 0 to 9.The remaining columns are the actual pixel data.Here as you can see there are about 784 columns that contain pixel data.\nHere each row is a different image representation in the form pixel data.\n\nNow let us split the train data into x and y arrays where x represents the image data and y represents the labels.\n\nTo do that we need to convert the dataframes into numpy arrays of float32 type which is the acceptable form for tensorflow and keras.","execution_count":null},{"metadata":{"trusted":true,"_uuid":"a6c10699c448487214315e0795284bc019b08fb5","_kg_hide-input":true},"cell_type":"code","source":"train_data = np.array(train_df, dtype = 'float32')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"4823e55d2aff1e8d915383a4ffc85e0ceb9bf5e6"},"cell_type":"markdown","source":"Similarly let us do the same process for test data","execution_count":null},{"metadata":{"trusted":true,"_uuid":"bf132ccb32200a5b328c016e4035fa93221c5025","_kg_hide-input":true},"cell_type":"code","source":"test_data = np.array(test_df, dtype='float32')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2addec56cdadf3dbaa37f11819883b045baad8ca"},"cell_type":"markdown","source":"Now let us slice the train arrays into x and y arrays namely x_train,y_train to store all image data and label data respectively.\ni.e \n\n- x_train contains all the rows and all columns except the label column and excluding header info .\n- y_train contains all the rows and first column and excluding header info .\n\n\nSimilarly slice the test arrays into x and y arrays namely x_train,y_train to store all image data and label data respectively.\ni.e \n\n- x_test contains all the rows and all columns except the label column and excluding header info .\n- y_test contains all the rows and first column and excluding header info .\n\n####  Important Note : Since the image data in x_train and x_test is from 0 to 255 ,  we need to rescale this from 0 to 1.To do this we need to divide the x_train and x_test by 255 . It's important that the training set and the testing set be preprocessed in the same way:","execution_count":null},{"metadata":{"trusted":true,"_uuid":"d97ee0d425a0b27b2a827ea7ced09b32f160b5ef"},"cell_type":"code","source":"x_train = train_data[:,1:]/255\n\ny_train = train_data[:,0]\n\nx_test= test_data[:,1:]/255\n\ny_test=test_data[:,0]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"70550e4f6caf2f895e50b03fdaad358a9b25e57e"},"cell_type":"markdown","source":"Now we are gonna split the training data into validation and actual training data for training the model and testing it using the validation set. This is achieved using the train_test_split method of scikit learn library.","execution_count":null},{"metadata":{"trusted":true,"_uuid":"b13fa2f08b0ff9a88614cafbaebf759cfb416654","_kg_hide-input":true},"cell_type":"code","source":"x_train,x_validate,y_train,y_validate = train_test_split(x_train,y_train,test_size = 0.2,random_state = 12345)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d1993a73683cfcca0bef7fe602b26b382b635816"},"cell_type":"markdown","source":"Now let us visualise the some samples after the resize of the data which needs to be ready for train the network .\n","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"class_names = ['T_shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', \n               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']\nplt.figure(figsize=(10, 10))\nfor i in range(36):\n    plt.subplot(6, 6, i + 1)\n    plt.xticks([])\n    plt.yticks([])\n    plt.grid(False)\n    plt.imshow(x_train[i].reshape((28,28)))\n    label_index = int(y_train[i])\n    plt.title(class_names[label_index])\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Labels\nEach training and test example is assigned to one of the following labels as shown below:\n\n* 0 T-shirt/top\n* 1 Trouser\n* 2 Pullover\n* 3 Dress\n* 4 Coat\n* 5 Sandal\n* 6 Shirt\n* 7 Sneaker\n* 8 Bag\n* 9 Ankle boot\n\nI think the best way is to visualise the above 10 types of classes to get a feel of what these items look like :) .So let us visualise\n","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"W_grid = 15\nL_grid = 15\n\nfig, axes = plt.subplots(L_grid, W_grid, figsize = (16,16))\naxes = axes.ravel() # flaten the 15 x 15 matrix into 225 array\nn_train = len(train_data) # get the length of the train dataset\n\n# Select a random number from 0 to n_train\nfor i in np.arange(0, W_grid * L_grid): # create evenly spaces variables \n\n    # Select a random number\n    index = np.random.randint(0, n_train)\n    # read and display an image with the selected index    \n    axes[i].imshow( train_data[index,1:].reshape((28,28)) )\n    labelindex = int(train_data[index,0])\n    axes[i].set_title(class_names[labelindex], fontsize = 9)\n    axes[i].axis('off')\n\nplt.subplots_adjust(hspace=0.3)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7c36ac2bcbbab7d9f3c160cea448cdc9f1360e26"},"cell_type":"markdown","source":"As you can observe above the shape of shoe from the sample image\n\n### Create the Convolutional Neural Networks (CNN)\n\n#### Define model\n\n#### Compile model\n\n#### Train model\n\nFirst of all let us define the shape of the image before we define the model. Defined the shape of the image as 3d with rows and columns and 1 for the 3d visualisation\n","execution_count":null},{"metadata":{"trusted":true,"_uuid":"504e5c30506b5c8e04c767450b292adebb491a96","_kg_hide-input":true},"cell_type":"code","source":"image_rows = 28\nimage_cols = 28\nbatch_size = 4096\nimage_shape = (image_rows,image_cols,1) ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"4da137b824248b458d31259df09016144d04bc78"},"cell_type":"markdown","source":"Now we need to do more formating on the x_train,x_test and x_validate sets.","execution_count":null},{"metadata":{"trusted":true,"_uuid":"45992f45e39c0e2170f07048415299f518503c8b","_kg_hide-input":true},"cell_type":"code","source":"x_train = x_train.reshape(x_train.shape[0],*image_shape)\nx_test = x_test.reshape(x_test.shape[0],*image_shape)\nx_validate = x_validate.reshape(x_validate.shape[0],*image_shape)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"fededa051da1671a01614b43bdb7f4286f7a4e0f"},"cell_type":"markdown","source":"#### Define the model \n\nThe first layer in model network, keras.layers.Flatten, transforms the format of the images from a two-dimensional array (of 28 by 28 pixels) to a one-dimensional array (of 28 * 28 = 784 pixels). This layer unstacks rows of pixels in the image and lining them up and has no parameters to learn; it only reformats the data.\n\nAfter the pixels are flattened, the network consists of a sequence of two keras.layers.Dense layers. These are densely connected, or fully connected, neural layers. The first Dense layer has 32 nodes (or neurons). The second (and last) layer is a 10-node softmax layer that returns an array of 10 probability scores that sum to 1. Each node contains a score that indicates the probability that the current image belongs to one of the 10 classes.","execution_count":null},{"metadata":{"trusted":true,"_uuid":"3e7ac49b5d3af585ba0ea700fffcc2640b90bfe0","_kg_hide-input":true},"cell_type":"code","source":"cnn_model = Sequential([\n    Conv2D(filters=32,kernel_size=3,activation='relu',input_shape = image_shape),\n    MaxPooling2D(pool_size=2) ,# down sampling the output instead of 28*28 it is 14*14\n    Dropout(0.2),\n    Flatten(), # flatten out the layers\n    Dense(32,activation='relu'),\n    Dense(10,activation = 'softmax')\n    \n])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"65a718079d1fa5b6564a3edd20eb9e332d76f196"},"cell_type":"markdown","source":"#### Compile the model\n\nBefore the model is ready for training, it needs a few more settings. These are added during the model's compile step:\n\n* Loss function —This measures how accurate the model is during training. You want to minimize this function to \"steer\" the model in the right direction.Here we will use \"sparse_categorical_crossentropy\"\n* Optimizer —This is how the model is updated based on the data it sees and its loss function.\n* Metrics —Used to monitor the training and testing steps. The following example uses accuracy, the fraction of the images that are correctly classified.","execution_count":null},{"metadata":{"trusted":true,"_uuid":"e4a6a6cd73c8e9f1089e24d4595985b47999b823","_kg_hide-input":true},"cell_type":"code","source":"cnn_model.compile(loss ='sparse_categorical_crossentropy', optimizer=Adam(lr=0.001),metrics =['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Train Model:\nTraining the neural network model requires the following steps:\n\n* Feed the training data to the model. In this example, the training data is in the x_train and y_train arrays.\n* The model learns to associate images and labels.\n* You ask the model to make predictions about a test set—in this example, the x_test array. Verify that the predictions match the labels from the y_test array.\n\nTo start training, call the model.fit method—so called because it \"fits\" the model to the training data:","execution_count":null},{"metadata":{"trusted":true,"_uuid":"8d5323fb34205db477e2087f1e034e1991e400c5","_kg_hide-input":false,"_kg_hide-output":true},"cell_type":"code","source":"history = cnn_model.fit(\n    x_train,\n    y_train,\n    batch_size=4096,\n    epochs=75,\n    verbose=1,\n    validation_data=(x_validate,y_validate),\n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let us plot the Training Accuracy vs Loss to get a better understanding of the model training.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(10, 10))\n\nplt.subplot(2, 2, 1)\nplt.plot(history.history['loss'], label='Loss')\nplt.plot(history.history['val_loss'], label='Validation Loss')\nplt.legend()\nplt.title('Training - Loss Function')\n\nplt.subplot(2, 2, 2)\nplt.plot(history.history['acc'], label='Accuracy')\nplt.plot(history.history['val_acc'], label='Validation Accuracy')\nplt.legend()\nplt.title('Train - Accuracy')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5d4f52eccdba23e1cc1c2de369daf87381ec388a"},"cell_type":"markdown","source":"- #### Evaluate /Score the model","execution_count":null},{"metadata":{"_cell_guid":"4543df54-7373-49f8-a23a-6d8062eefe38","_uuid":"9de535d8a446b7168ac3790445610425527c8a47","trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"score = cnn_model.evaluate(x_test,y_test,verbose=0)\nprint('Test Loss : {:.4f}'.format(score[0]))\nprint('Test Accuracy : {:.4f}'.format(score[1]))","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"f860c207-af4d-4c32-b4d2-4ea2d39902fe","_uuid":"d18bc5dd0ec23cda8ea5ad846b9877704f484951"},"cell_type":"markdown","source":"### Results\n\n","execution_count":null},{"metadata":{"_cell_guid":"00dc5434-a008-490d-bb89-a394cf95c4bc","_uuid":"adbb96b3d90dcab280f06341a8483f246f583a03"},"cell_type":"markdown","source":"\nLet's plot training and validation accuracy as well as loss.","execution_count":null},{"metadata":{"_cell_guid":"324c3a68-6381-4a39-a5a1-8fac766150c0","_uuid":"042117c73a10d7cbda6bc42ab60f9b0407cdf2c1","trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\n%matplotlib inline\naccuracy = history.history['acc']\nval_accuracy = history.history['val_acc']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\nepochs = range(len(accuracy))\nplt.plot(epochs, accuracy, 'bo', label='Training Accuracy')\nplt.plot(epochs, val_accuracy, 'b', label='Validation Accuracy')\nplt.title('Training and Validation accuracy')\nplt.legend()\nplt.figure()\nplt.plot(epochs, loss, 'bo', label='Training Loss')\nplt.plot(epochs, val_loss, 'b', label='Validation Loss')\nplt.title('Training and validation loss')\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"1311601b-9a53-4e59-adcd-4365c811f85e","_uuid":"28e5331842de7baaffb3a1e74f6a4c03e140759a"},"cell_type":"markdown","source":"### Classification Report\nWe can summarize the performance of our classifier as follows","execution_count":null},{"metadata":{"_cell_guid":"721514ef-520b-42a2-9d57-2f82fbae8393","_uuid":"0275d1189e6425353537fa3ebe5d97d7b6759551","trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"#Get the predictions for the test data\npredicted_classes = cnn_model.predict_classes(x_test)\n#Get the indices to be plotted\ny_true = test_df.iloc[:, 0]\ncorrect = np.nonzero(predicted_classes==y_true)[0]\nincorrect = np.nonzero(predicted_classes!=y_true)[0]\nfrom sklearn.metrics import classification_report\ntarget_names = [\"Class {}\".format(i) for i in range(num_classes)]\nprint(classification_report(y_true, predicted_classes, target_names=target_names))","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"dc36576e-c630-4581-89fe-3bed02c378bb","_uuid":"2863d680886cc22a2e6f11270b411e435410adaf"},"cell_type":"markdown","source":"It's apparent that our classifier is underperforming for class 6 in terms of both precision and recall. For class 2, classifier is slightly lacking precision whereas it is slightly lacking recall (i.e. missed) for class 4.\n\nPerhaps we would gain more insight after visualizing the correct and incorrect predictions.\n\nLet us examine the test label and check if it the right classification or not.","execution_count":null},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"L = 5\nW = 5\nfig, axes = plt.subplots(L, W, figsize = (12,12))\naxes = axes.ravel()\n\nfor i in np.arange(0, L * W):  \n    axes[i].imshow(x_test[i].reshape(28,28))\n    axes[i].set_title(f\"Prediction Class = {predicted_classes[i]:0.1f}\\n Original Class = {y_test[i]:0.1f}\")\n    axes[i].axis('off')\n\nplt.subplots_adjust(wspace=0.5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"4034a8c82e307dc949d441b6111818b129495ace"},"cell_type":"markdown","source":"### I hope you had a good understanding of CNN Model and its usage in practice using Fashion MNIST dataset.\n\n# Please do share your comments/suggestions and if you like this  kernel appreciate to UPVOTE.\n\nI recently created few useful kernels like below which might be of great interest to you in your data science work .Do visit them and share your thoughts/comments/upvote.","execution_count":null}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}