{"cells":[{"metadata":{},"cell_type":"markdown","source":"This kernel is modified from a simpler kernel available at\n* https://www.kaggle.com/uysimty/get-start-image-classification"},{"metadata":{"_uuid":"fe76d1d1ded592430e7548feacfa38dc42f085d9"},"cell_type":"markdown","source":"# Import Library"},{"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 tensorflow as tf\nfrom keras.preprocessing.image import ImageDataGenerator, load_img\nfrom keras.utils import to_categorical\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\nimport random\nimport os\nprint(os.listdir(\"../input\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Set the input directory\ninput_dir_name=\"../input/cat-and-dog/training_set/training_set/\"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Lets explore a litile bit training data"},{"metadata":{"trusted":true},"cell_type":"code","source":"import glob\ndog_list=[]\ncat_list=[]\nfor name in glob.glob(input_dir_name+\"dogs/*\"):\n    dog_list.append(name)\nfor name in glob.glob(input_dir_name+\"cats/*\"):\n    cat_list.append(name)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# lets see some dog images"},{"metadata":{"trusted":true},"cell_type":"code","source":"samples=random.choices(dog_list, k=6)\nw=10\nh=10\nfig=plt.figure(figsize=(8, 8))\ncolumns = 3\nrows = 2\nfor i in range(1, columns*rows):\n    fig.add_subplot(rows, columns, i)\n    image = load_img(samples[i])\n    plt.imshow(image)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7335a579cc0268fba5d34d6f7558f33c187eedb3"},"cell_type":"markdown","source":"# Prepare Traning Data\n* here I have used keras \"imagedatagenerator\" to formulated the training tensor data for CNN. This is very easy way of creating tensor for CNN, directily by reading images from training folders as specified in \"input_dir\"."},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 128\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n# All images will be rescaled by 1./255\ntrain_datagen = ImageDataGenerator(rescale=1/255)\n# Flow training images in batches of 128 using train_datagen generator\ntrain_generator = train_datagen.flow_from_directory(\n        input_dir_name,  # This is the source directory for training images\n        target_size=(200, 200),  # All images will be resized to 200 x 200\n        batch_size=batch_size,\n        # Specify the classes explicitly\n        classes = ['dogs','cats'],\n        # Since we use categorical_crossentropy loss, we need categorical labels\n        class_mode='categorical')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Model architecture \n(Taken form :https://github.com/tirthajyoti/Deep-learning-with-Python)"},{"metadata":{"trusted":true,"_uuid":"8c9f833c1441b657c779844912d0b8028218d454"},"cell_type":"code","source":"model = tf.keras.models.Sequential([\n    # Note the input shape is the desired size of the image 200x 200 with 3 bytes color\n    # The first convolution\n    tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(200, 200, 3)),\n    tf.keras.layers.MaxPooling2D(2, 2),\n    # The second convolution\n    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),\n    tf.keras.layers.MaxPooling2D(2,2),\n    # The third convolution\n    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),\n    tf.keras.layers.MaxPooling2D(2,2),\n    # The fourth convolution\n    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),\n    tf.keras.layers.MaxPooling2D(2,2),\n    # The fifth convolution\n    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),\n    tf.keras.layers.MaxPooling2D(2,2),\n    # Flatten the results to feed into a dense layer\n    tf.keras.layers.Flatten(),\n    # 128 neuron in the fully-connected layer\n    tf.keras.layers.Dense(128, activation='relu'),\n    # 2 output neurons for 2 classes with the softmax activation\n    tf.keras.layers.Dense(2, activation='softmax')\n])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.keras.optimizers import RMSprop\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=RMSprop(lr=0.001),\n              metrics=['acc'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"demo_run=False\nn_epochs=3 if demo_run else 50\ntotal_sample=train_generator.n\nhistory = model.fit_generator(\n        train_generator, \n        steps_per_epoch=int(total_sample/batch_size),  \n        epochs=n_epochs,\n        verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"aa1fbc4081ae0de2993188b2bf658a0be5bc0687"},"cell_type":"markdown","source":"# Save Model\n* if you want to use the trained model later on for your predicitons, you can save the model now and use it later for your prediciton without training the model again."},{"metadata":{"trusted":true,"_uuid":"67575a4decdaf79a915d23151626b784ffa82642"},"cell_type":"code","source":"model.save_weights(\"model.h5\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1b76c0a9040bc0babf0a453e567e41e22f8a1e0e"},"cell_type":"markdown","source":"# Virtualize Training"},{"metadata":{"trusted":true,"_uuid":"79055f2dc3e2abb47bea758e0464c86ca42ab431"},"cell_type":"code","source":"plt.plot(history.history['loss'], color='b', label=\"Training loss\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"764dc66e4b2bc558f3a0f90b80bb802f5b3d45a8"},"cell_type":"markdown","source":"# Prepare Testing Data"},{"metadata":{"trusted":true,"_uuid":"c35e70d3e1e4834dbbf840fa0ea08c049bfcd915"},"cell_type":"code","source":"test_dir_name=\"../input/cat-and-dog/test_set/test_set\"\nos.listdir(test_dir_name)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_dir_name=\"../input/cat-and-dog/test_set/test_set/\"","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"291bc3996dce8d05e174b27d64f03996d3e8038e"},"cell_type":"markdown","source":"# Create Testing Generator"},{"metadata":{"trusted":true,"_uuid":"52249ec1c35fb1be3adef386be245de3794e55aa"},"cell_type":"code","source":"test_datagen=ImageDataGenerator(rescale=1/255)\ntest_generator = test_datagen.flow_from_directory(\n        test_dir_name,  # This is the source directory for test images\n        target_size=(200, 200),  # All images will be resized to 200 x 200\n        batch_size=batch_size,\n        class_mode=None\n    )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"nb_samples=test_generator.n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_generator.labels","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2fa580afca2931ec5ce374e732d8c1789d03f2ed"},"cell_type":"markdown","source":"# Predict"},{"metadata":{"trusted":true,"_uuid":"4782eb23fa7d003f0e2415d995894017edb2d896"},"cell_type":"code","source":"predict = model.predict_generator(test_generator, steps=np.ceil(nb_samples/batch_size))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":" # lets evaluate the results\n* For categoral classication the prediction will come with probability of each category. So we will  pick the category that have the highest probability with numpy average max"},{"metadata":{"trusted":true},"cell_type":"code","source":"predicted_labels= np.argmax(predict, axis=-1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"true_labels=test_generator.labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import accuracy_score\nprint(accuracy_score(predicted_labels,true_labels))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"* Its really a low accuracy, we need to fine tune the network architecture, hyperparameters and so on."},{"metadata":{"_uuid":"b00add65fe765529e637c3a9904d710bb7eff1d8"},"cell_type":"markdown","source":"### Lets Virtaulize prediction  for few samples"},{"metadata":{"trusted":true},"cell_type":"code","source":"filename=test_generator.filenames[1]\nlabel=predicted_labels[1]\nplt.figure(figsize=(5, 5))\nimg = load_img(test_dir_name+filename)\nplt.imshow(img)\nif(label==0):\n    cl=\"cat\"\nelse:\n    cl='dog'\nplt.xlabel('Your predicted images is '+'(' + \"{}\".format(cl) + ')' )\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_generator.class_indices.items()","execution_count":null,"outputs":[]},{"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":4}