-
Notifications
You must be signed in to change notification settings - Fork 0
/
CNN-Kaggle
1 lines (1 loc) · 30.5 KB
/
CNN-Kaggle
1
{"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"name":"CNN-Kaggle","provenance":[],"toc_visible":true,"collapsed_sections":["sbaf4qpV3Q8h","vbBwmhs83ocw","E3oUXGsI4ELO","Ob3Mk8Sb4QTe","yPMp3eWz40IS","NkjNwajE5vc3","11Z3P1yP6BrS","hoIjU4eE6V85","w5NLBgiX7Pkt","VYfeUSQa_Qw7","J566vvvCDkfY","U_Z_4_mx_io_","n-fVHzuw_2ee","bzzXCd4XAGCb","eeGwIqlSARnP","lVOLlv45Astl","Y2Mg7mJeA8r7","PTZrkWUoBgaD","2fDohMeEJAlv","WHQGqvvtJoG7","T7_BLMsgCNAN"],"authorship_tag":"ABX9TyOJkH1xnVupej3xAKlsc/Pa"},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"}},"cells":[{"cell_type":"markdown","source":["# **Conv2D=MaxPool2D=Flatten+Dense+Padding+Stride+Data Augmentation+Regularization**"],"metadata":{"id":"1shiRUCk84PT"}},{"cell_type":"markdown","source":["## **Import Basic Libraries**\n","more to be imported as needed"],"metadata":{"id":"qt-R0P5L0Z63"}},{"cell_type":"code","source":["import numpy as np\n","import pandas as pd\n","import matplotlib.pyplot as plt\n","%matplotlib inline\n","import PIL\n","import PIL.Image\n","\n","import tensorflow as tf"],"metadata":{"id":"dAhZxcqb0slp"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Load Data**"],"metadata":{"id":"fYFF_T_e03M0"}},{"cell_type":"code","source":["train_dir = \"../input/dogs-vs-cats/train.zip\"\n","\n","import zipfile\n","with zipfile.ZipFile(train_dir, \"r\") as f:\n"," f.extractall('.')"],"metadata":{"id":"oJiM-d_K07nZ"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["# File Path\n","IMAGE_FOLDER_PATH = \"../working/train\"\n","FILE_PATH = [os.path.join(IMAGE_FOLDER_PATH,i) for i in os.listdir(IMAGE_FOLDER_PATH)]\n","\n","# Labels\n","labels=[i for i in os.listdir(IMAGE_FOLDER_PATH)]\n","\n","# Targets\n","targets=[i.split('.')[0] for i in labels]\n","y=targets\n","\n","# Dataframe\n","data = pd.DataFrame({'PATH':FILE_PATH,'targets':targets}) \n","data"],"metadata":{"id":"Q6JJmcuw1EHF"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Train-Val Split**"],"metadata":{"id":"uR8tP40k1QkZ"}},{"cell_type":"code","source":["from sklearn.model_selection import train_test_split\n","train_df, val_df = train_test_split(data, test_size=0.20, random_state=42)"],"metadata":{"id":"qyjLpL-v1Umh"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **EDA - Further Analysis of Data**"],"metadata":{"id":"koeNJaNH2ECm"}},{"cell_type":"code","source":["train_df.info()"],"metadata":{"id":"1YNoX9yf2Ho5"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["train_df['targets'].value_counts()"],"metadata":{"id":"-c7LM4TE2OFo"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Visualize the Data**\n","\n","**Image-Gallery Function**"],"metadata":{"id":"D5ZLNELx2kdV"}},{"cell_type":"code","source":["from keras.preprocessing.image import load_img\n","\n","def gallery(nrow,ncol,name): # This function creates a grid of images from dataset.\n"," \n"," img_df = train_df[train_df['targets'] == name] # little data sorting\n"," path_df = img_df['PATH']\n"," \n"," # Gallery using Matplotlib \n"," fig, ax = plt.subplots(nrow,ncol,figsize = (12,12), dpi = 100)\n"," axes = ax.ravel()\n"," \n"," for idx,ax in enumerate(axes):\n"," ax.imshow(load_img(path_df.iloc[idx]))\n"," return fig.show()"],"metadata":{"id":"ly74-4n32pDY"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["gallery(5,5,name='cat')"],"metadata":{"id":"OY6VIKhK29i2"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["gallery(5,5,name='dog')"],"metadata":{"id":"7HsPVFJN3Dfk"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Image Data Augmentation**\n","Data augmentation takes the approach of generating more training data from existing training samples, by augmenting the samples via a number of random transformations that yield believable-looking images. The goal is that at training time, your model will never see the exact same picture twice. This helps expose the model to more aspects of the data and generalize better.\n","\n","Image augmentation is a technique of applying different transformations to original images which results in multiple transformed copies of the same image. Each copy, however, is different from the other in certain aspects depending on the augmentation techniques you apply like shifting, rotating, flipping, etc.\n","\n","Applying these small amounts of variations on the original image does not change its target class but only provides a new perspective of capturing the object in real life. And so, we use it is quite often for building deep learning models.\n","\n","These image augmentation techniques not only expand the size of your dataset but also incorporate a level of variation in the dataset which allows your model to generalize better on unseen data. Also, the model becomes more robust when it is trained on new, slightly altered images."],"metadata":{"id":"sbaf4qpV3Q8h"}},{"cell_type":"markdown","source":["### **Train Data**"],"metadata":{"id":"vbBwmhs83ocw"}},{"cell_type":"code","source":["from tensorflow.keras.preprocessing.image import ImageDataGenerator\n","\n","datagen=ImageDataGenerator(\n","# featurewise_center=True,\n","# samplewise_center=T,\n","# featurewise_std_normalization=False,\n","# samplewise_std_normalization=False,\n","# zca_whitening=True,\n","# zca_epsilon=1e-06,\n","# rotation_range=90,\n","# width_shift_range=0.5,\n","# height_shift_range=0.5,\n","# brightness_range=None,\n","# shear_range=0.0,\n","# zoom_range=0.0,\n","# channel_shift_range=0.0,\n","# fill_mode='nearest',\n","# cval=0.0,\n"," horizontal_flip=True,\n"," vertical_flip=True,\n"," rescale=1./255,\n","# preprocessing_function=None,\n","# data_format=None,\n","# validation_split=0.0,\n","# interpolation_order=1,\n","# dtype=None\n",")\n","\n","train=datagen.flow_from_directory(\n"," directory='/content/data/beans',\n"," # classes=['a','b'],\n"," class_mode=\"categorical\",\n"," color_mode=\"rgb\",\n"," # batch_size=32,\n"," # target_size=(500,500),\n"," # shuffle=True,\n"," # seed=None,\n"," # save_to_dir=None,\n"," # save_prefix='',\n"," # save_format='png',\n"," # subset=None,\n"," # interpolation=\"bilinear\",\n"," # follow_links=False,\n"," # **kwargs\n",")\n","\n","train"],"metadata":{"id":"AxuVHB_83YDQ"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["***The Keras ImageDataGenerator class is not an “additive” operation. It’s not taking the original data, randomly transforming it, and then returning both the original data and transformed data. Instead, the ImageDataGenerator accepts the original data, randomly transforms it, and returns only the new, transformed data.***"],"metadata":{"id":"Io2PBlfn350Q"}},{"cell_type":"markdown","source":["### **Validation Data**"],"metadata":{"id":"E3oUXGsI4ELO"}},{"cell_type":"code","source":["val=datagen.flow_from_dataframe(dataframe=val_df,\n"," x_col=\"PATH\",\n"," y_col=\"targets\",\n"," target_size=(224, 224),\n"," class_mode=\"binary\")\n","\n","val"],"metadata":{"id":"LM7OCvLY3_hI"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["##**Build Model**"],"metadata":{"id":"Ob3Mk8Sb4QTe"}},{"cell_type":"code","source":["from keras.layers import Conv2D, MaxPool2D, Dropout, Flatten, Dense, Activation, BatchNormalization\n","from keras.models import Sequential\n","from tensorflow.keras import regularizers\n","\n","model = Sequential()\n","\n","model.add(Conv2D(filters=32,kernel_size=3,strides=(3,3),padding='same',activation='relu',input_shape=(224,224,3))),\n","model.add(BatchNormalization())\n","model.add(MaxPool2D(pool_size=(2, 2), strides=None, padding=\"same\")),\n","model.add(Dropout(0.25))\n","\n","model.add(Conv2D(filters=64,kernel_size=3,strides=(3,3),padding='same',activation='relu')),\n","model.add(MaxPool2D(pool_size=(2, 2), strides=None, padding=\"same\")),\n","\n","model.add(Conv2D(filters=128,kernel_size=3,strides=(3,3),padding='same',activation='relu')),\n","model.add(MaxPool2D(pool_size=(2, 2), strides=None, padding=\"same\")),\n","\n","# flatten output of conv\n","model.add(Flatten())\n","\n","# hidden layer\n","model.add(Dense(512, activation='relu', kernel_regularizer=regularizers.L1L2(l1=0.001,l2=0.001))) # Added Regularization\n","model.add(Dropout(0.25))\n","\n","# output layer\n","model.add(Dense(1, activation='sigmoid'))\n","\n","model.summary()"],"metadata":{"id":"RR9czyDG4YEX"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["##**Visualize Model**"],"metadata":{"id":"yPMp3eWz40IS"}},{"cell_type":"code","source":["!pip install visualkeras\n","import visualkeras\n","visualkeras.layered_view(model, legend=True)"],"metadata":{"id":"KsonpuA44-oL"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["from keras.utils.vis_utils import plot_model\n","plot_model(model, 'model.png',show_shapes=True)"],"metadata":{"id":"u1I5KONl5L7W"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Compile & Callback & Train**"],"metadata":{"id":"NkjNwajE5vc3"}},{"cell_type":"code","source":["# Model Compile\n","model.compile(optimizer='adam',\n"," loss=tf.keras.losses.BinaryCrossentropy(from_logits=False),\n"," metrics=tf.keras.metrics.BinaryAccuracy())\n","\n","# Callbacks\n","from keras.callbacks import EarlyStopping, ReduceLROnPlateau\n","es=tf.keras.callbacks.EarlyStopping(monitor='val_binary_accuracy', patience=3) # This callback will stop the training when there is no improvement in the loss for three consecutive epochs.,\n","lrr = ReduceLROnPlateau(monitor='val_binary_accuracy',patience=2) \n","cb = [es, lrr]\n","\n","# Train\n","history=model.fit(train, \n"," epochs=20,\n"," # verbose=\"auto\",\n"," callbacks=cb, \n"," # validation_split=0.2,\n"," validation_data=val,\n"," shuffle=True,\n"," # class_weight=None,\n"," # sample_weight=None,\n"," # initial_epoch=0,\n"," # steps_per_epoch=None,\n"," # validation_steps=None,\n"," # validation_batch_size=None,\n"," # validation_freq=1,\n"," # max_queue_size=10,\n"," # workers=1,\n"," # use_multiprocessing=False,\n"," )"],"metadata":{"id":"OQCgBFO456tB"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Plot Filters**\n","\n","**First-5**\n","\n","As known, initial layer's filters identify low-level features. The middle-layer's filters identify edges in the image, whereas, end-layer's filters identifies more high-level features like colour of the eyes.\n","\n"],"metadata":{"id":"t0SUezwbRs6o"}},{"cell_type":"code","source":["for layer in model.layers:\n"," print('Layer : ',layer.name)\n","\n"," # retrieve weights from the second hidden layer\n"," filters, biases = layer.get_weights()\n","\n"," # plot first 5 filters from each layer\n"," n_filters, ix = 5, 1\n"," for i in range(5):\n","\n"," # get the filter\n"," f = filters[:, :, :, i]\n"," \n"," # plot each channel separately\n","\t for j in range(3):\n"," \n"," # specify subplot and turn of axis\n"," ax = pyplot.subplot(n_filters, 3, ix)\n"," ax.set_yticks([])\n","\n"," # plot filter channel in grayscale\n"," pyplot.imshow(f[:, :, j], cmap='gray')\n"," ix += 1\n","\n","# show the figure\n","pyplot.show()"],"metadata":{"id":"zEss-lDESzIk"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["##**Plot Outputs**\n","\n","The output of a convolution layer is bundled as one image with multiple channels. These could be thought as feature channels, in contrast with color channels. For example, if a convolution layer has F number of filters, it will output an image with F number of channels, no matter how many (color or feature) channels the input image had. A convolution filter will convolve over all input channels and the linear combination of its convolution would be fed to its activation function."],"metadata":{"id":"5xlAD7UYX5W9"}},{"cell_type":"code","source":["fig = plt.figure(figsize=(20,15))\n","for layer in model.layers:\n"," print('Layer : ',layer.name)\n"," \n"," # Details about the layer\n"," details = Model(inputs=model.inputs , outputs=layer.output)\n","\n"," for i in range(1,outputs.shape+1):\n","\n"," plt.subplot(8,8,i)\n"," plt.imshow(outputs[0,:,:,i-1])\n"," \n","plt.show()"],"metadata":{"id":"f-R1B1tHYDgs"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Save Model**"],"metadata":{"id":"11Z3P1yP6BrS"}},{"cell_type":"code","source":["# Saving Model\n","model.save('model.h5')"],"metadata":{"id":"W53PQ3OQ6K71"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Plotting Accuracy**"],"metadata":{"id":"hoIjU4eE6V85"}},{"cell_type":"code","source":["# summarize history for accuracy\n","plt.plot(history.history['binary_accuracy'])\n","plt.plot(history.history['val_binary_accuracy'])\n","plt.title('model accuracy')\n","plt.ylabel('accuracy')\n","plt.xlabel('epoch')\n","plt.legend(['train', 'val'], loc='upper left')\n","plt.show()"],"metadata":{"id":"Zvx7lEy96eC_"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["# **Transfer Learning**\n","\n","Transfer learning is a machine learning method where we reuse a pre-trained model as the starting point for a model on a new task.\n","\n","**To put it simply—a model trained on one task is repurposed on a second, related task as an optimization that allows rapid progress when modeling the second task. By applying transfer learning to a new task, one can achieve significantly higher performance than training with only a small amount of data.**\n","\n","Transfer learning is so common that it is rare to train a model for an image or natural language processing-related tasks from scratch.\n","\n","![tl](https://assets-global.website-files.com/5d7b77b063a9066d83e1209c/616b35e31e352613b291f4c7_P46neY1rhMd5NbTxhCbaWWAnwJwhgCZjSLp2C2-6Pzf8sBEfAxtlhnAOV_Jq_gX-zOaztDWLrtFal42V-EDr86Gcd8QYrWh4uMxZ-_-X_Pd5tOge9EkBmFr7UxrEWLMwCNZi14WK%3Ds0.jpeg)\n","\n","TensorFlow Hub is an online repository of already trained TensorFlow models that you can use. These models can either be used as is, or they can be used for Transfer Learning. Transfer learning is a process where you take an existing trained model, and extend it to do additional work. This involves leaving the bulk of the model unchanged, while adding and retraining the final layers, in order to get a different set of possible outputs.\n","\n","![tl2](https://miro.medium.com/max/1000/0*xNjEPIZmPvKeqss6)"],"metadata":{"id":"bxQBgeD36qw5"}},{"cell_type":"markdown","source":["***The model that we'll use is MobileNet v2 (but any model from tf2 compatible image classifier URL from tfhub.dev would work).***"],"metadata":{"id":"ddqK0tnn68zN"}},{"cell_type":"markdown","source":["## **Download MobileNet**\n","\n","Download the MobileNet model and create a Keras model from it. **MobileNet** is expecting images of 224 $\\times$ 224 pixels, in 3 color channels (RGB).\n","\n","With transfer learning we reuse parts of an already trained model and change the final layer, or several layers, of the model, and then retrain those layers on our own dataset.\n","\n","In addition to complete models, TensorFlow Hub also distributes models without the last classification layer. These can be used to easily do transfer learning.\n","\n","*Note that we're calling the partial model from TensorFlow Hub (without the final classification layer) a `feature_extractor`. The reasoning for this term is that it will take the input all the way to a layer containing a number of features. So it has done the bulk of the work in identifying the content of an image, except for creating the final probability distribution. That is, it has extracted the features of the image.*\n","\n","![mobilenetv2](https://ars.els-cdn.com/content/image/1-s2.0-S2210670720309070-gr4.jpg)"],"metadata":{"id":"w5NLBgiX7Pkt"}},{"cell_type":"code","source":["import tensorflow_hub as hub\n","mobilenet =\"https://tfhub.dev/google/tf2-preview/mobilenet_v2/classification/2\"\n","feature_extractor = hub.KerasLayer(mobilenet,input_shape=(224,224,3))\n","\n","# Freeze the variables in the feature extractor layer, so that the training only modifies the final classifier layer.\n","feature_extractor.trainable = False"],"metadata":{"id":"Dea-bWxF6xUi"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Build Model**"],"metadata":{"id":"VYfeUSQa_Qw7"}},{"cell_type":"code","source":["from keras.models import Sequential\n","from tensorflow.keras.layers import Dense\n","\n","model5 = tf.keras.Sequential()\n","\n","model5.add(feature_extractor),\n","model5.add(Dense(1, activation='sigmoid'))\n","\n","model5.summary()"],"metadata":{"id":"e4KkTbOW_VTY"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Fine Tuning**"],"metadata":{"id":"J566vvvCDkfY"}},{"cell_type":"code","source":["# fine tuning\n","feature_extractor.trainable = True\n","\n","# Let's take a look to see how many layers are in the base model\n","print(\"Number of layers in the base model: \", len(feature_extractor.layers))\n","\n","# Fine-tune from this layer onwards\n","fine_tune_at = 100\n","\n","# Freeze all the layers before the `fine_tune_at` layer\n","for layer in feature_extractor.layers[:fine_tune_at]:\n"," layer.trainable = False"],"metadata":{"id":"cCVgwrR_D7hG"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["# fine tuning with low learning_rate 1/10 from base\n","model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),\n"," optimizer = tf.keras.optimizers.RMSprop(learning_rate=base_learning_rate/10),\n"," metrics=['accuracy'])\n","len(model.trainable_variables)"],"metadata":{"id":"E4zfdPmNFCoa"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["# running fine tuning\n","FINE_TUNING = True\n","if FINE_TUNING:\n"," fine_tune_epochs = 10\n"," total_epochs = initial_epochs + fine_tune_epochs\n","\n"," # fine tuning training \n"," history_fine = model.fit(train_generator,\n"," batch_size=BATCH_SIZE,\n"," epochs=total_epochs, # fine tuning\n"," initial_epoch=history.epoch[-1],\n"," validation_data=validation_generator)"],"metadata":{"id":"rBM_6hZ5Fq66"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Compile & Train**"],"metadata":{"id":"U_Z_4_mx_io_"}},{"cell_type":"code","source":["# Model Compile\n","model5.compile(optimizer='adam',\n"," loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),\n"," metrics=tf.keras.metrics.BinaryAccuracy())\n","\n","# Train\n","history5=model5.fit(train, \n"," epochs=25,\n"," # verbose=\"auto\",\n"," # callbacks=cb, \n"," # validation_split=0.2,\n"," validation_data=val,\n"," shuffle=True,\n"," # class_weight=None,\n"," # sample_weight=None,\n"," # initial_epoch=0,\n"," # steps_per_epoch=None,\n"," # validation_steps=None,\n"," # validation_batch_size=None,\n"," # validation_freq=1,\n"," # max_queue_size=10,\n"," # workers=1,\n"," # use_multiprocessing=False,\n"," )"],"metadata":{"id":"JxVC1saH_m1S"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Plotting**"],"metadata":{"id":"n-fVHzuw_2ee"}},{"cell_type":"code","source":["# summarize history for accuracy\n","plt.plot(history5.history['binary_accuracy'])\n","plt.plot(history5.history['val_binary_accuracy'])\n","plt.title('model accuracy')\n","plt.ylabel('accuracy')\n","plt.xlabel('epoch')\n","plt.legend(['train', 'val'], loc='upper left')\n","plt.show()"],"metadata":{"id":"9fkX23dR_60c"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Predict**"],"metadata":{"id":"bzzXCd4XAGCb"}},{"cell_type":"code","source":["pred = model5.predict(val)\n","pred"],"metadata":{"id":"PLqyMHINAJsk"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Converting Probabilities of Prediction**"],"metadata":{"id":"eeGwIqlSARnP"}},{"cell_type":"code","source":["# class map => { logit : class name }\n","class_map = { v: k for k, v in val.class_indices.items() }\n","\n","# apply a sigmoid because our model returns logits\n","predict = tf.nn.sigmoid(pred)\n","predict = tf.where(pred < 0.5, 0, 1).numpy()\n","\n","predict"],"metadata":{"id":"aST9nbN5Ab4w"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["val_df['targets']=[0 if x=='cat' else 1 for x in val_df['targets']]\n","val_df['predict']=predict\n","val_df"],"metadata":{"id":"AsfiicIkAhnf"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Confusion Matrix**"],"metadata":{"id":"lVOLlv45Astl"}},{"cell_type":"code","source":["from sklearn.metrics import ConfusionMatrixDisplay, confusion_matrix, classification_report \n","fig, ax = plt.subplots(figsize = (9, 6))\n","\n","cm = confusion_matrix(val_df[\"targets\"],val_df[\"predict\"])\n","\n","disp = ConfusionMatrixDisplay(confusion_matrix = cm, display_labels = [\"cat\", \"dog\"])\n","disp.plot(cmap = plt.cm.Blues, ax = ax)\n","ax.set_title(\"Validation Set\")\n","plt.show()"],"metadata":{"id":"fCMjH7ImAws_"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **MisClassified**"],"metadata":{"id":"Y2Mg7mJeA8r7"}},{"cell_type":"code","source":["error_df=[row['PATH'] for i,row in val_df.iterrows() if row[\"targets\"] != row['predict']]\n","error_df[:10]"],"metadata":{"id":"2konmtPwBAxv"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["from keras.preprocessing.image import load_img\n","\n","def show_error(nrow,ncol): # This function creates a grid of images from dataset.\n"," \n"," # Gallery using Matplotlib \n"," fig, ax = plt.subplots(nrow,ncol,figsize = (12,12), dpi = 100)\n"," axes = ax.ravel()\n"," \n"," for idx,ax in enumerate(axes):\n"," ax.imshow(load_img(error_df.iloc[idx]))\n"," return fig.show()\n","\n","show_error(5,5)\n"],"metadata":{"id":"Sl7jY3n2pP1Y"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Test Data-For Submission**"],"metadata":{"id":"PTZrkWUoBgaD"}},{"cell_type":"code","source":["test_dir = \"../input/dogs-vs-cats/test1.zip\"\n","\n","import zipfile\n","with zipfile.ZipFile(test_dir, \"r\") as tst:\n"," tst.extractall('.')"],"metadata":{"id":"axH8wPgjBfqh"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["# File Path\n","IMAGE_FOLDER_PATH = \"../working/test1\"\n","FILE_PATH = [os.path.join(IMAGE_FOLDER_PATH,i) for i in os.listdir(IMAGE_FOLDER_PATH)]\n","\n","# Dataframe\n","test_df = pd.DataFrame({'PATH':FILE_PATH}) \n","test_df"],"metadata":{"id":"jRyj-bm9BxZR"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Processing Test Data**"],"metadata":{"id":"2fDohMeEJAlv"}},{"cell_type":"code","source":["from tensorflow.keras.preprocessing.image import ImageDataGenerator\n","\n","datagen=ImageDataGenerator(\n","# featurewise_center=True,\n","# samplewise_center=True,\n","# featurewise_std_normalization=False,\n","# samplewise_std_normalization=False,\n","# zca_whitening=True,\n","# zca_epsilon=1e-06,\n","# rotation_range=90,\n","# width_shift_range=0.5,\n","# height_shift_range=0.5,\n","# brightness_range=None,\n","# shear_range=0.0,\n"," zoom_range=0.5,\n","# channel_shift_range=0.0,\n","# fill_mode='nearest',\n","# cval=0.0,\n"," horizontal_flip=True,\n"," vertical_flip=True,\n"," rescale=1./255,\n","# preprocessing_function=None,\n","# data_format=None,\n","# validation_split=0.0,\n","# interpolation_order=1,\n","# dtype=None\n",")\n","\n","test=datagen.flow_from_dataframe(dataframe=test_df,\n"," x_col=\"PATH\",\n"," y_col=None,\n"," class_mode=None,\n"," shuffle=False.\n"," target_size=(224, 224),\n"," )\n","\n","test"],"metadata":{"id":"wmZYXow2B4CJ"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Final Submission**"],"metadata":{"id":"WHQGqvvtJoG7"}},{"cell_type":"code","source":["idx=[int(str(x).split('.')[0]) for x in labels]\n","idx[:5]"],"metadata":{"id":"PC0Z9RQCB_7Q"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["import numpy as np\n","pred=model5.predict(test) \n","classes=np.argmax(pred,axis=1)\n","classes"],"metadata":{"id":"LmGuEhSfJerM"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["submission=pd.DataFrame({'id': idx,\n"," 'label': classes,\n"," })\n","submission\n","# # submission.to_csv('submission.csv', index=False)"],"metadata":{"id":"AiMKH6JjCGFJ"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["# **Suggestions:-**\n","* Kaggle - https://www.kaggle.com/pythonkumar\n","* GitHub - https://github.com/KumarPython\n","* Twitter - https://twitter.com/KumarPython\n","* LinkedIn - https://www.linkedin.com/in/kumarpython/"],"metadata":{"id":"VuMGBilRDjKa"}},{"cell_type":"markdown","source":["# **Feature Importance using SHAP**\n","\n","SHAP or SHAPley Additive exPlanations is a visualization tool that can be used for making a machine learning model more explainable by visualizing its output. It can be used for explaining the prediction of any model by computing the contribution of each feature to the prediction. It is a combination of various tools like lime, SHAPely sampling values, DeepLift, QII, and many more. \n","\n","The idea is using game theory to interpret target model. All features are “contributor” and trying to predict the task which is “game” and the “reward” is actual prediction minus the result from explanation model.\n","\n","![shap](https://miro.medium.com/max/700/1*Fb4sZSoSxxtQ14yy4aaN8g.png)\n","\n","**Interpreting CNN Models**\n","\n","Here’s the interesting part, can we really unbox the opacity presented to us by a seemingly black-box CNN model and try and understand what’s really going on under the hood and what does the model really see when it looks at an image? There are a wide variety of techniques and tools for interpreting decisions made by vision-based deep learning models.\n","\n","![shap3](https://miro.medium.com/max/700/1*_e8cWSTcpGrSs9FeOB105A.png)\n"],"metadata":{"id":"T7_BLMsgCNAN"}},{"cell_type":"code","source":["# import shap\n","# import numpy as np\n","# tensorflow.compat.v1.disable_eager_execution()\n","\n","# # select a set of background examples to take an expectation over\n","# background = x_train[np.random.choice(x_train.shape[0], 100, replace=False)]\n","\n","# # explain predictions of the model on three images\n","# e = shap.DeepExplainer(model, background)\n","# # ...or pass tensors directly\n","# # e = shap.DeepExplainer((model.layers[0].input, model.layers[-1].output), background)\n","# shap_values = e.shap_values(x_test[1:5])"],"metadata":{"id":"wnOu3kl421uc"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Each Image**"],"metadata":{"id":"LU9zKGmr7hGe"}},{"cell_type":"code","source":["!pip install SHAP\n","\n","import shap\n","tf.compat.v1.disable_v2_behavior()\n","\n","# print the JS visualization code to the notebook\n","shap.initjs()\n","\n","# define a masker that is used to mask out partitions of the input image.\n","masker = shap.maskers.Image(\"inpaint_telea\", (32,224,224,3))\n","\n","# create an explainer with model and image masker\n","explainer = shap.Explainer(model, masker, output_names=classes)\n","\n","# # here we explain two images using 5 evaluations of the underlying model to estimate the SHAP values\n","shap_values = explainer(val[5],outputs=shap.Explanation.argsort.flip[:4])\n","\n","# output with shap values\n","shap.plots.image(shap_values)"],"metadata":{"id":"jD4XtEH8CWNA"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["## **Each Layer**\n","\n","This technique tries to combine a multitude of ideas from Integrated Gradients, SHapley Additive exPlanations (SHAP) and SmoothGrad. This technique tries to explain model decisions using expected gradients (an extension of integrated gradients). This is a feature attribution method designed for differentiable models based on an extension of Shapley values to infinite player games. We will use the shap framework here for this technique."],"metadata":{"id":"RiKsD6q1-MEm"}},{"cell_type":"code","source":["!pip install SHAP\n","\n","import shap\n","tf.compat.v1.disable_v2_behavior()\n","\n","# print the JS visualization code to the notebook\n","shap.initjs()\n","\n","# utility function to pass inputs to specific model layers\n","def map2layer(x, layer):\n"," feed_dict = dict(zip([model.layers[0].input], [preprocess_input(x.copy())]))\n"," return K.get_session().run(model.layers[layer].input, feed_dict)\n","\n","# make model predictions\n","e = shap.GradientExplainer((model.layers[7].input, model.layers[-1].output), \n"," map2layer(preprocess_input(X.copy()), 7))\n","shap_values, indexes = e.shap_values(map2layer(to_predict, 7), ranked_outputs=2)\n","index_names = np.vectorize(lambda x: class_names[str(x)][1])(indexes)\n","print(index_names)\n","Out [47]: array([['chain', 'chain_mail'],\n"," ['great_grey_owl', 'prairie_chicken'],\n"," ['desktop_computer', 'screen'],\n"," ['Egyptian_cat', 'tabby']], dtype='<U16')\n","\n","# visualize model decisions\n","visualize_model_decisions(shap_values=shap_values, x=to_predict, \n"],"metadata":{"id":"5lFnYDJ2-TQW"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":["${a_n}$\n","\n","${x_n}$ and ${y_n}$ are 2 numbers "],"metadata":{"id":"gdMLlX1yvda5"}},{"cell_type":"code","source":[""],"metadata":{"id":"HG2futD8vmnr"},"execution_count":null,"outputs":[]}]}