{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# Importing the libaries\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom matplotlib.image import imread\nfrom keras.models import Sequential\nfrom keras.layers import Conv2D\nfrom keras.layers import MaxPool2D\nfrom keras.layers import Flatten\nfrom keras.layers import Dense\nfrom keras.layers import Dropout\nfrom keras.preprocessing.image import ImageDataGenerator,img_to_array,load_img\nfrom keras.optimizers import SGD\nfrom keras.optimizers import RMSprop, Adam\nfrom keras.callbacks.callbacks import EarlyStopping,ModelCheckpoint,CSVLogger, ReduceLROnPlateau\nfrom livelossplot import PlotLossesKeras\nfrom keras.applications import VGG16,VGG19\nfrom keras.models import Model\nimport os\nimport zipfile\nimport glob\nimport shutil\nprint(os.listdir('../input/dogs-vs-cats'))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"print(\"This notebook is taken from : https://www.kaggle.com/vipulshinde/dogs-vs-cats-using-custom-cnn-vgg16-model\")\n\n# Unipping the data\nzip_files = glob.glob('../input/*/*.zip')\nprint(zip_files)\n\n# extract file into a temp folder\ndef extract_zip(file):\n    with zipfile.ZipFile(file,\"r\") as zip_ref:\n        zip_ref.extractall(\"data\")\n        \n# extract both train and test1 zip\nfor files in zip_files:\n    extract_zip(files)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Checking the new files along with number of samples\nprint(os.listdir('data'))\nprint(len(os.listdir('/kaggle/working/data/train')),'Training Samples')\nprint(len(os.listdir('/kaggle/working/data/test1')),'Testing Samples')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Checking the names of few data samples\nprint(os.listdir('/kaggle/working/data/train')[:5])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(10,10)) # specifying the overall grid size\n# define location of dataset\nfolder = '/kaggle/working/data/train'\nfor i in range(25):\n    plt.subplot(5,5,i+1)    # the number of images in the grid is 5*5 (25)\n    filename = folder + '/dog.' + str(i) + '.jpg'\n    image = imread(filename)\n    plt.imshow(image)\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plot dog photos from the dogs vs cats dataset\n\n# define location of dataset\nfolder = '/kaggle/working/data/train'\n# plot first few images\nfor i in range(9):\n\t# define subplot\n    plt.subplot(330 + 1 + i)\n\t# define filename\n    filename = folder + '/dog.' + str(i) + '.jpg'\n\t# load image pixels\n    image = imread(filename)\n\t# plot raw pixel data\n    plt.imshow(image, aspect = 'auto')\n# show the figure\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plot cat photos from the dogs vs cats dataset\n\n# define location of dataset\nfolder = '/kaggle/working/data/train'\n# plot first few images\nfor i in range(9):\n    # define subplot\n    plt.subplot(330 + 1 + i)\n    # define filename\n    filename = folder + '/cat.' + str(i) + '.jpg'\n    # load image pixels\n    image = imread(filename)\n    # plot raw pixel data\n    plt.imshow(image, aspect = 'auto')\n# show the figure\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# create new directories for training data and validation data\ndataset_home = 'dataset/'\nsubdirs = ['training_set/', 'validation_set/']\nfor subdir in subdirs:\n\t# create label subdirectories\n    labeldirs = ['dogs/', 'cats/']\n    for labldir in labeldirs:\n        newdir = dataset_home + subdir + labldir\n        os.makedirs(newdir, exist_ok=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# create new directory for test data\ntestdir = dataset_home + 'testing_set'\nos.makedirs(testdir, exist_ok= True)\ndirs = '/kaggle/working/dataset/testing_set/' + 'Test'\nos.makedirs(dirs,exist_ok = True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(os.listdir(dataset_home))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# seed random number generator\nfrom random import random\nfrom random import seed\nseed(1)\n# define ratio of pictures to use for validation\nvalidation_ratio = 0.25\n# copy training dataset images into subdirectories\nfrom shutil import copyfile\ntraining_source = '/kaggle/working/data/train/'\nfor file in os.listdir(training_source):\n    src = training_source + '/' + file\n    destination = 'training_set/'\n    if random() < validation_ratio:\n        destination = 'validation_set/'\n    if file.startswith('cat'):\n        dst = dataset_home + destination + 'cats/'  + file\n        copyfile(src, dst)\n    elif file.startswith('dog'):\n        dst = dataset_home + destination + 'dogs/'  + file\n        copyfile(src, dst)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Deleting the images in test folder if needed in order to get results on more random images\na = glob.glob('/kaggle/working/dataset/testing_set/Test/*.jpg')\nfor j in a:\n    os.remove(j)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Creating some samples for classifying images using the build model\ntest_source = \"/kaggle/working/data/test1\"\n#print(os.listdir(test_source)[:5])\ntest_dest = \"/kaggle/working/dataset/testing_set/Test\"\n# Selecting 10 random files from the test main folder\nrandom_samples = np.random.choice(os.listdir(test_source),50)\nfor file in random_samples:\n    new_src = test_source + '/' + file\n    shutil.copy(new_src,test_dest)\nprint(os.listdir(test_dest))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Building the CNN model\nmodel = Sequential()\n\nmodel.add(Conv2D(32, (3, 3), padding='same', input_shape=(200,200,3), activation='relu'))\nmodel.add(Conv2D(32, (3, 3), padding='same', activation='relu'))\nmodel.add(MaxPool2D(pool_size=(2, 2)))\n\nmodel.add(Conv2D(64, (3, 3), padding='same', activation='relu'))\nmodel.add(Conv2D(64, (3, 3), padding='same', activation='relu'))\nmodel.add(MaxPool2D(pool_size=(2, 2)))\n\nmodel.add(Conv2D(128, (3, 3), padding='same', activation='relu'))\nmodel.add(Conv2D(128, (3, 3), padding='same', activation='relu'))\nmodel.add(MaxPool2D(pool_size=(2, 2)))\n\nmodel.add(Conv2D(256, (3, 3), padding='same', activation='relu'))\nmodel.add(Conv2D(256, (3, 3), padding='same', activation='relu'))\nmodel.add(MaxPool2D(pool_size=(2, 2)))\n\nmodel.add(Flatten())\nmodel.add(Dense(units = 256, activation='relu'))\nmodel.add(Dropout(0.5))\n\nmodel.add(Dense(units = 256, activation='relu'))\nmodel.add(Dropout(0.5))\n\nmodel.add(Dense(units = 1, activation = 'sigmoid'))\n\nmodel.compile(loss='binary_crossentropy',\n            optimizer=RMSprop(lr=0.0001),\n            metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Preparing the data and performing Data Augmentation\ntrain_datagen = ImageDataGenerator(rescale=1./255,\n                                    shear_range=0.2,\n                                    zoom_range=0.2,\n                                    horizontal_flip=True)\n\nvalidation_datagen = ImageDataGenerator(rescale=1./255)\n\ntest_datagen = ImageDataGenerator(rescale=1./255)\n\ntrain_set = train_datagen.flow_from_directory('dataset/training_set',\n                                                target_size=(331, 331),\n                                                batch_size=64,\n                                                class_mode='binary')\nvalidation_set = validation_datagen.flow_from_directory('dataset/validation_set',\n                                                target_size=(331, 331),\n                                                batch_size=64,\n                                                class_mode='binary')\ntest_set = test_datagen.flow_from_directory('dataset/testing_set',\n                                                target_size=(331, 331),\n                                                batch_size=1,class_mode = 'binary',shuffle = False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Creating h5 file for storing best_model data\nwith open('best_model.h5', 'w') as best:\n    pass\n# Creating CSV file for storing losses\nwith open('CSVLogs.csv','w') as loss:\n    pass","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Creating the callback functions\nes = EarlyStopping(monitor='val_loss',mode= 'min',verbose=1,patience=10,restore_best_weights=True)\nmc = ModelCheckpoint('best_model.h5',monitor='val_loss',mode= 'min',verbose=1,save_best_only=False)\ncsv = CSVLogger('CSVLogs.csv',separator=',', append=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Fitting the model to data\noutput = model.fit_generator(train_set, steps_per_epoch=(18697//64),epochs= 20,\n                             validation_data = validation_set, validation_steps= (6303//64),\n                             callbacks=[es,mc,csv,PlotLossesKeras()])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Evalauting the model\nloss,score = model.evaluate_generator(validation_set,steps = (6303//64), verbose = 0)\nprint('accuracy : %.3f'% (np.round(score*100,1)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Testing the model\nprobabilities = model.predict_generator(test_set)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Plotting the probabilities along with images:\nfor index, probability in enumerate(probabilities):\n    image_path = \"/kaggle/working/dataset/testing_set/\" + test_set.filenames[index]\n    img = imread(image_path)\n    plt.imshow(img)\n    if probability > 0.5:\n        plt.title(\"%.2f\" % (probability[0]*100) + \"% dog\")\n    else:\n        plt.title(\"%.2f\" % ((1-probability[0])*100) + \"% cat\")\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Making new single predictions\ndef detect_image(filepath):\n    test_image = load_img(filepath, target_size = (200,200))\n    plt.imshow(test_image)\n    test_image = img_to_array(test_image)\n    test_image = np.expand_dims(test_image, axis = 0)\n    result = model.predict(test_image)\n    train_set.class_indices\n    if result[0][0] == 1:\n        prediction = 'dog'\n    else:\n        prediction = 'cat'\n    plt.title(prediction)\n\ndetect_image('/kaggle/working/dataset/testing_set/Test/1057.jpg')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# save model to JSON\nmodel_json = model.to_json()\nwith open(\"model.json\", \"w\") as json_file:\n    json_file.write(model_json)\n# save weights to HDF5\nwith open(\"model.h5\",'w') as h5_file:\n    pass\nmodel.save_weights(\"model.h5\")\nprint(\"Saved model to disk\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Loading the VGG model using Transfer Learning\ntransfer_model = VGG16(include_top = False, weights = 'imagenet',input_shape = (200,200,3))\nfor layer in transfer_model.layers:\n    layer.trainable = False\n# Defining the output layers\nflat = Flatten()(transfer_model.layers[-1].output)\nclass1 = Dense(units = 256, activation='relu')(flat)\nclass2 = Dense(units = 256, activation = 'relu')(class1)\noutput = Dense(units = 1, activation='sigmoid')(class2)\n# define new model\ntransfer_model = Model(inputs=transfer_model.inputs, outputs=output)\ntransfer_model.compile(loss='binary_crossentropy',\n            optimizer=RMSprop(lr=0.001),\n            metrics=['accuracy'])\ntransfer_model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"transfer_model.fit_generator(train_set, steps_per_epoch=(18697//64),epochs= 10,\n                             validation_data = validation_set, validation_steps= (6303//64),\n                             callbacks = [csv,PlotLossesKeras()])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Evalauting the model\nloss,score = transfer_model.evaluate_generator(validation_set,steps = (6303//64), verbose = 0)\nprint('accuracy : %.3f'% (np.round(score*100,1)))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications import NASNetLarge\nfrom keras.models import Model\n\nNASNet_transfer_model = NASNetLarge(input_shape=(331,331,3), include_top=False, weights='imagenet')\nfor layer in NASNet_transfer_model.layers:\n    layer.trainable = False\n# Defining the output layers\nflat = Flatten()(NASNet_transfer_model.layers[-1].output)\nclass1 = Dense(units = 256, activation='relu')(flat)\nclass2 = Dense(units = 256, activation = 'relu')(class1)\noutput = Dense(units = 1, activation='sigmoid')(class2)\n# define new model\nNASNet_transfer_model = Model(inputs = NASNet_transfer_model.inputs, outputs=output)\nNASNet_transfer_model.compile(loss='binary_crossentropy',\n                              optimizer=Adam(learning_rate=0.001),\n                              metrics=['accuracy'])\nNASNet_transfer_model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"NASNet_transfer_model.fit_generator(train_set, steps_per_epoch=(18697//64),epochs= 10,\n                                    validation_data = validation_set, validation_steps= (6303//64),\n                                    callbacks = [csv,PlotLossesKeras()])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Evalauting the model\nloss,score = NASNet_transfer_model.evaluate_generator(validation_set,steps = (6303//64), verbose = 0)\nprint('accuracy : %.3f'% (np.round(score*100,1)))","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}