{"cells":[{"metadata":{},"cell_type":"markdown","source":"In this kernel I have applied transfer learning , I have used VGG16 pretrained model and designed the last FC layer manually which I have further connected to a softmax layer.\n\nUsing this I have acheived an acuracy of 94% with 4 epoch. Increasing the epochs might increase the efficiency further(you can try if you want!!)\n\nIn this kernal I have tried keeping a standard apporach so that the same code can be reused in other problems(ofcourse with minor tweeeks!!).\n","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"# Import all required libraries","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"%matplotlib inline\nimport numpy as np\nimport pandas as pd\nimport datetime as dt\nimport matplotlib.pyplot as plt\nfrom mpl_toolkits.axes_grid1 import ImageGrid\nfrom os import listdir, makedirs\nfrom os.path import join, exists, expanduser\nfrom tqdm import tqdm\nfrom sklearn.metrics import log_loss, accuracy_score\nfrom keras.preprocessing import image\nfrom keras.applications.vgg16 import VGG16\nfrom keras.applications.resnet50 import ResNet50\nfrom keras.applications import xception\nfrom keras.applications import inception_v3\nfrom keras.applications.vgg16 import preprocess_input, decode_predictions\nfrom sklearn.linear_model import LogisticRegression\n\nfrom keras.models import Sequential\nfrom keras.layers import Dense , Dropout , Lambda, Flatten\nfrom keras.optimizers import Adam ,RMSprop\nfrom sklearn.model_selection import train_test_split\nfrom keras import  backend as K\nfrom keras.preprocessing.image import ImageDataGenerator,load_img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"start = dt.datetime.now()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Loading required data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"label=pd.read_csv(\"/kaggle/input/dog-breed-identification/labels.csv\")\nlabel","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Selecting TOP 16","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"label_df=pd.DataFrame(label['breed'].value_counts()).reset_index()\nlabel_df.columns=['breed_name','count']\nlabel_df=label_df.head(16)\nlabel_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"label_df.sort_values(by=\"count\",ascending=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"label = label[label['breed'].isin(label_df['breed_name'])]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Adding .jpg extension","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"    \nlabel['id_ext']=label['id'].apply(lambda x:x+'.jpg')\nlabel=label.reset_index()\nlabel=label.drop(['index','id'],axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"label.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# One hot coding of breeds","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"label_onehot=pd.get_dummies(label,columns=['breed'],prefix=None)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"label_onehot","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"label_onehot.columns","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Renaming the columns","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"label_onehot.columns = label_onehot.columns.str.replace(r'breed_', '')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#label_onehot\nlabel_onehot=label_onehot.rename(columns={'id_ext':'id'})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"label_onehot","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Checking a random sample","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import random\nsample=random.choice(label_onehot['id'])\nsample","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image=load_img(\"/kaggle/input/dog-breed-identification/train/\"+sample)\nimage","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Train and Test split","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df, validate_df = train_test_split(label_onehot, test_size=0.1)\ntrain_df = train_df.reset_index()\nvalidate_df = validate_df.reset_index()\n\n# validate_df = validate_df.sample(n=100).reset_index() # use for fast testing code purpose\n# train_df = train_df.sample(n=1800).reset_index() # use for fast testing code purpose\n\ntotal_train = train_df.shape[0]\ntotal_validate = validate_df.shape[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.shape,validate_df.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# VGG 16 pretrained model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.models import Sequential\nfrom keras import layers\nfrom keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense, Activation,GlobalMaxPooling2D\nfrom keras import applications\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras import optimizers\nfrom keras.applications import VGG16\nfrom keras.models import Model\n\nimage_size = 224\ninput_shape = (image_size, image_size, 3)\n\nepochs = 4\nbatch_size = 16\n\npre_trained_model = VGG16(input_shape=input_shape, include_top=False, weights=\"imagenet\")\n    \nfor layer in pre_trained_model.layers[:15]:\n    layer.trainable = False\n\nfor layer in pre_trained_model.layers[15:]:\n    layer.trainable = True\n    \nlast_layer = pre_trained_model.get_layer('block5_pool')\nlast_output = last_layer.output\n    \n# Flatten the output layer to 1 dimension\nx = GlobalMaxPooling2D()(last_output)\n# Add a fully connected layer with 512 hidden units and ReLU activation\nx = Dense(512, activation='relu')(x)\n# Add a dropout rate of 0.5\nx = Dropout(0.5)(x)\n# Add a final sigmoid layer for classification\nx = layers.Dense(16, activation='softmax')(x)\n\nmodel = Model(pre_trained_model.input, x)\n\nmodel.compile(loss='binary_crossentropy',\n              optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),\n              metrics=['accuracy'])\n\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.columns","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data Augmentation","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Training Data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train_datagen = ImageDataGenerator(\n    rotation_range=15,\n    rescale=1./255,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    fill_mode='nearest',\n    width_shift_range=0.1,\n    height_shift_range=0.1\n)\n\ntrain_generator = train_datagen.flow_from_dataframe(\n    train_df, \n    \"/kaggle/input/dog-breed-identification/train\", \n    x_col='id',\n    y_col=['afghan_hound', 'airedale', 'basenji', 'beagle',\n       'bernese_mountain_dog', 'cairn', 'entlebucher', 'great_pyrenees',\n       'japanese_spaniel', 'leonberg', 'maltese_dog', 'pomeranian', 'samoyed',\n       'scottish_deerhound', 'shih-tzu', 'tibetan_terrier'],\n    class_mode='raw',\n    target_size=(image_size, image_size),\n    batch_size=batch_size\n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Validation Data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"validation_datagen = ImageDataGenerator(rescale=1./255)\nvalidation_generator = validation_datagen.flow_from_dataframe(\n    validate_df, \n    \"/kaggle/input/dog-breed-identification/train\", \n    x_col='id',\n    y_col=['afghan_hound', 'airedale', 'basenji', 'beagle',\n       'bernese_mountain_dog', 'cairn', 'entlebucher', 'great_pyrenees',\n       'japanese_spaniel', 'leonberg', 'maltese_dog', 'pomeranian', 'samoyed',\n       'scottish_deerhound', 'shih-tzu', 'tibetan_terrier'],\n    class_mode='raw',\n    target_size=(image_size, image_size),\n    batch_size=batch_size\n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Example of Data AUgmentation","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"example_df = train_df.sample(n=1).reset_index(drop=True)\nexample_generator = train_datagen.flow_from_dataframe(\n    example_df, \n    \"/kaggle/input/dog-breed-identification/train/\", \n    x_col='id',\n    y_col=['afghan_hound', 'airedale', 'basenji', 'beagle',\n       'bernese_mountain_dog', 'cairn', 'entlebucher', 'great_pyrenees',\n       'japanese_spaniel', 'leonberg', 'maltese_dog', 'pomeranian', 'samoyed',\n       'scottish_deerhound', 'shih-tzu', 'tibetan_terrier'],\n    class_mode='raw',\n)\nplt.figure(figsize=(12, 12))\nfor i in range(0, 9):\n    plt.subplot(3, 3, i+1)\n    for X_batch, Y_batch in example_generator:\n        image = X_batch[0]\n        plt.imshow(image)\n        break\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Fit the model, accuracy 94%","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# fine-tune the model\nhistory = model.fit_generator(\n    train_generator,\n    epochs=epochs,\n    validation_data=validation_generator,\n    validation_steps=total_validate//batch_size,\n    steps_per_epoch=total_train//batch_size)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"loss, accuracy = model.evaluate_generator(validation_generator, total_validate//batch_size, workers=12)\nprint(\"Test: accuracy = %f  ;  loss = %f \" % (accuracy, loss))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"validate_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_dog(row):\n    for i in validate_df.columns[2:]:\n        if row[i]==1:\n            return i        \nvalidate_df['breed']=validate_df.apply(get_dog,axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"validate_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"validate_df=validate_df[['id','breed']]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"validate_df.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Checking output from validata data to check accuracy","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_test = validate_df.sample(n=9).reset_index()\n#print(sample_test)\nplt.figure(figsize=(12, 12))\nfor index, row in sample_test.iterrows():\n    filename = row['id']\n    print(filename)\n    category = row['breed']\n    img = load_img(\"/kaggle/input/dog-breed-identification/train/\"+filename, target_size=(256, 256))\n    \n    plt.subplot(3, 3,index+1)\n    plt.imshow(img)\n    plt.xlabel('(' + \"{}\".format(category) + ')')\nplt.tight_layout()\nplt.show()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"end = dt.datetime.now()\nprint('Total time {} s.'.format((end - start).seconds))\n","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":4}