{"cells":[{"metadata":{},"cell_type":"markdown","source":"**In this kernel intermediate layers of model trained for kannada MNIST challenge will be visualized to understand inner workings of the CNN**"},{"metadata":{},"cell_type":"markdown","source":"Link to original notebook with model and full prediction process - [Kannada MNIST](https://www.kaggle.com/rohan9889/kannada-mnist-cnn-keras)"},{"metadata":{},"cell_type":"markdown","source":"The visualization code use is taken from [Link to repository](https://github.com/gabrielpierobon/cnnshapes/blob/master/README.md)"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Model"},{"metadata":{},"cell_type":"markdown","source":"Making model from same architecture as previous notebook"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"from keras.models import Sequential, Model\nfrom keras.layers import Conv2D, Dense, Dropout, BatchNormalization, Flatten, MaxPool2D","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Sequential()\n\nmodel.add(Conv2D(32,kernel_size=3,activation='relu',input_shape=(28,28,1)))\nmodel.add(Conv2D(32,kernel_size=3,activation='relu'))\nmodel.add(MaxPool2D())\nmodel.add(Conv2D(32,kernel_size=5,strides=2,padding='same',activation='relu'))\nmodel.add(Dropout(0.4))\n\nmodel.add(Conv2D(64,kernel_size=3,activation='relu'))\nmodel.add(Conv2D(64,kernel_size=3,activation='relu'))\nmodel.add(MaxPool2D())\nmodel.add(Conv2D(64,kernel_size=5,strides=2,padding='same',activation='relu'))\nmodel.add(Dropout(0.4))\n\nmodel.add(Flatten())\nmodel.add(Dense(128, activation='relu'))\nmodel.add(Dropout(0.4))\nmodel.add(Dense(10, activation='softmax'))\n\nmodel.compile(optimizer=\"adam\", loss=\"categorical_crossentropy\", metrics=[\"accuracy\"])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Weight Loading"},{"metadata":{},"cell_type":"markdown","source":"Loading the weights on which the model was previously trained (.984 accuracy)"},{"metadata":{"trusted":true},"cell_type":"code","source":"model.load_weights('/kaggle/input/kannada-mnist-model-weights/BWeight.md5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data = pd.read_csv('/kaggle/input/Kannada-MNIST/test.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X = data.drop(['id'],axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X = X.values.reshape(X.shape[0],28,28,1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Visualization"},{"metadata":{"trusted":true},"cell_type":"code","source":"layer_outputs = [layer.output for layer in model.layers]\n# Storing layers of model in a list\nactivation_model = Model(inputs=model.input, outputs=layer_outputs)\n# A simple model that takes its input as input of previously trained model and produces output based on provided \n# list of layers","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Using the imported data to predict the activations of all present layers"},{"metadata":{"trusted":true},"cell_type":"code","source":"activations = activation_model.predict(X[0:10])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Visualizing 10th channel of first activation"},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.matshow(activations[0][9, :, :, 10], cmap='viridis')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Visualzing for all activations"},{"metadata":{"trusted":true},"cell_type":"code","source":"layer_names = []\nfor layer in model.layers[:6]:\n    layer_names.append(layer.name) # Names of the layers, so you can have them as part of your plot\n    \nimages_per_row = 16\n\nfor layer_name, layer_activation in zip(layer_names, activations): # Displays the feature maps\n    n_features = layer_activation.shape[-1] # Number of features in the feature map\n    size = layer_activation.shape[1] #The feature map has shape (1, size, size, n_features).\n    n_cols = n_features // images_per_row # Tiles the activation channels in this matrix\n    display_grid = np.zeros((size * n_cols, images_per_row * size))\n    for col in range(n_cols): # Tiles each filter into a big horizontal grid\n        for row in range(images_per_row):\n            channel_image = layer_activation[0,\n                                             :, :,\n                                             col * images_per_row + row]\n            channel_image = np.clip(channel_image, 0, 255).astype('uint8')\n            display_grid[col * size : (col + 1) * size, # Displays the grid\n                         row * size : (row + 1) * size] = channel_image\n    scale = 1 / size\n    plt.figure(figsize=(scale * display_grid.shape[1],\n                        scale * display_grid.shape[0]))\n    plt.title(layer_name)\n    plt.grid(False)\n    plt.imshow(display_grid, aspect='auto')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**It is clear that as we move to higher layers low level information is being filtered and only high level info remains**"},{"metadata":{},"cell_type":"markdown","source":"**Low layers are looking for edges and other suck info but as we move forward in the layers it becomes clear that these features are not important for high level features, high level features only look for semantics of the image**"},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":1}