{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":5441,"databundleVersionId":38425,"sourceType":"competition"},{"sourceId":9900,"sourceType":"datasetVersion","datasetId":6209},{"sourceId":110819,"sourceType":"datasetVersion","datasetId":57539},{"sourceId":110930,"sourceType":"datasetVersion","datasetId":57578}],"dockerImageVersionId":11543,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"Project Description","metadata":{}},{"cell_type":"markdown","source":"In this project, we will build a model capable of classifying images. This is using convolutional neural networks, and also using transfer learning. The benefit of transfer learning is that we will import a ready-made convolutional neural network trained on millions of images, and the reason for using transfer learning is the small number of data we have, which causes the model to be unable to correctly predict and classify images. correct on the test set","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport keras\nimport cv2\nimport os\nimport random\nfrom keras.utils import to_categorical\nfrom sklearn.model_selection import train_test_split","metadata":{"execution":{"iopub.status.busy":"2024-08-10T20:26:18.005750Z","iopub.execute_input":"2024-08-10T20:26:18.006215Z","iopub.status.idle":"2024-08-10T20:26:18.011768Z","shell.execute_reply.started":"2024-08-10T20:26:18.006147Z","shell.execute_reply":"2024-08-10T20:26:18.010805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Part 1 - Data Preprocessing","metadata":{}},{"cell_type":"code","source":"from keras.applications.resnet50 import preprocess_input\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator","metadata":{"execution":{"iopub.status.busy":"2024-08-10T20:26:18.013251Z","iopub.execute_input":"2024-08-10T20:26:18.013797Z","iopub.status.idle":"2024-08-10T20:26:18.025765Z","shell.execute_reply.started":"2024-08-10T20:26:18.013586Z","shell.execute_reply":"2024-08-10T20:26:18.024478Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Preprocessing the Training set","metadata":{}},{"cell_type":"code","source":"data_generator = ImageDataGenerator(preprocessing_function=preprocess_input)\ntrain_generator = data_generator.flow_from_directory(\n        '../input/catsdogs-trainvalid-80pc-prepd/trainvalidfull4keras/trainvalidfull4keras/train',\n        target_size=(224, 224),\n        batch_size=32,\n        class_mode='categorical')","metadata":{"execution":{"iopub.status.busy":"2024-08-10T20:26:18.027184Z","iopub.execute_input":"2024-08-10T20:26:18.027570Z","iopub.status.idle":"2024-08-10T20:26:35.827028Z","shell.execute_reply.started":"2024-08-10T20:26:18.027495Z","shell.execute_reply":"2024-08-10T20:26:35.826088Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Preprocessing the validation set","metadata":{}},{"cell_type":"code","source":"validation_generator = data_generator.flow_from_directory(\n        '../input/catsdogs-trainvalid-80pc-prepd/trainvalidfull4keras/trainvalidfull4keras/valid',\n        target_size=(224, 224),\n        batch_size=32,\n        class_mode='categorical')","metadata":{"execution":{"iopub.status.busy":"2024-08-10T20:26:35.828280Z","iopub.execute_input":"2024-08-10T20:26:35.828601Z","iopub.status.idle":"2024-08-10T20:26:40.007906Z","shell.execute_reply.started":"2024-08-10T20:26:35.828545Z","shell.execute_reply":"2024-08-10T20:26:40.007137Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Part 2 - Building the CNN","metadata":{}},{"cell_type":"code","source":"from tensorflow.python.keras.applications import ResNet50\nresnet_weights_path = '../input/resnet50/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5'","metadata":{"execution":{"iopub.status.busy":"2024-08-10T20:26:40.009181Z","iopub.execute_input":"2024-08-10T20:26:40.009465Z","iopub.status.idle":"2024-08-10T20:26:40.013467Z","shell.execute_reply.started":"2024-08-10T20:26:40.009414Z","shell.execute_reply":"2024-08-10T20:26:40.012573Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cnn = tf.keras.models.Sequential()\n\n# first layer resnet_weights_path\ncnn.add(ResNet50(include_top = False, pooling = 'avg', weights = resnet_weights_path))\n\n# for 2nd layer in output, classification model will use \"softmax\" activation\ncnn.add(tf.keras.layers.Dense(units=2, activation='softmax'))\n\n# No training first layer (ResNet) model as it is already trained\ncnn.layers[0].trainable = False\n\ncnn.summary()","metadata":{"execution":{"iopub.status.busy":"2024-08-10T20:26:40.014929Z","iopub.execute_input":"2024-08-10T20:26:40.015275Z","iopub.status.idle":"2024-08-10T20:26:51.489047Z","shell.execute_reply.started":"2024-08-10T20:26:40.015208Z","shell.execute_reply":"2024-08-10T20:26:51.488118Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Part 3 - Training the CNN","metadata":{}},{"cell_type":"markdown","source":"Compiling the CNN","metadata":{}},{"cell_type":"code","source":"cnn.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2024-08-10T20:26:51.490519Z","iopub.execute_input":"2024-08-10T20:26:51.490798Z","iopub.status.idle":"2024-08-10T20:26:51.632123Z","shell.execute_reply.started":"2024-08-10T20:26:51.490747Z","shell.execute_reply":"2024-08-10T20:26:51.630998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Training the CNN on the Training set and evaluating it on the Test set","metadata":{}},{"cell_type":"markdown","source":"history = cnn.fit(x = train_generator, validation_data = validation_generator, epochs = 15)\n\n\nNote: The Keras fit function takes arrays of data, numpy arrays, not generators. The function you need is fit_generator. Note that fit_generator takes slightly different parameters, such as steps_per_epoch instead of batch_size","metadata":{}},{"cell_type":"code","source":"history = cnn.fit_generator(\n        train_generator,\n        steps_per_epoch=20,\n        epochs = 10,\n        validation_data=validation_generator,\n        validation_steps=20,\n    )","metadata":{"execution":{"iopub.status.busy":"2024-08-10T20:27:56.774838Z","iopub.execute_input":"2024-08-10T20:27:56.775146Z","iopub.status.idle":"2024-08-10T21:01:33.888258Z","shell.execute_reply.started":"2024-08-10T20:27:56.775098Z","shell.execute_reply":"2024-08-10T21:01:33.887244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"plot accuracy and loss","metadata":{}},{"cell_type":"code","source":" plt.figure(1, figsize = (15,8)) \n    \nplt.subplot(221)  \nplt.plot(history.history['acc'])  \nplt.plot(history.history['val_acc'])  \nplt.title('model accuracy')  \nplt.ylabel('accuracy')  \nplt.xlabel('epoch')  \nplt.legend(['train', 'valid']) \n    \nplt.subplot(222)  \nplt.plot(history.history['loss'])  \nplt.plot(history.history['val_loss'])  \nplt.title('model loss')  \nplt.ylabel('loss')  \nplt.xlabel('epoch')  \nplt.legend(['train', 'valid']) \n\nplt.show()","metadata":{"_uuid":"00e51568f7e6022c6738c0e1a41080bc7152c257","execution":{"iopub.status.busy":"2024-08-10T21:01:56.283105Z","iopub.execute_input":"2024-08-10T21:01:56.283509Z","iopub.status.idle":"2024-08-10T21:01:56.694089Z","shell.execute_reply.started":"2024-08-10T21:01:56.283442Z","shell.execute_reply":"2024-08-10T21:01:56.692732Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Preprocessing the test set","metadata":{}},{"cell_type":"code","source":"test_generator = data_generator.flow_from_directory(\n    directory = '../input/test-files-prepd/test4keras/test4keras',\n    target_size = (224, 224),\n    batch_size = 32,\n    class_mode = None,\n    shuffle = False,\n    seed = 123\n)","metadata":{"_uuid":"3941e7c5d983e2ad6ae6d6da0a1415ea27e1db7e","execution":{"iopub.status.busy":"2024-08-10T21:02:07.417256Z","iopub.execute_input":"2024-08-10T21:02:07.417587Z","iopub.status.idle":"2024-08-10T21:02:19.035461Z","shell.execute_reply.started":"2024-08-10T21:02:07.417537Z","shell.execute_reply":"2024-08-10T21:02:19.034514Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Reset before each call to predict\ntest_generator.reset()\n\npred = cnn.predict_generator(test_generator, steps = len(test_generator), verbose = 1)\n\npredicted_class_indices = np.argmax(pred, axis = 1)","metadata":{"_uuid":"9911ff38ec4b82f5282f078aae63b2a510a9a6cc","execution":{"iopub.status.busy":"2024-08-10T21:02:19.037185Z","iopub.execute_input":"2024-08-10T21:02:19.037711Z","iopub.status.idle":"2024-08-10T21:30:24.600451Z","shell.execute_reply.started":"2024-08-10T21:02:19.037525Z","shell.execute_reply":"2024-08-10T21:30:24.598597Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TEST_DIR = '../input/test-files-prepd/test4keras/test4keras/'\nf, ax = plt.subplots(4, 5, figsize = (15, 15))\n\nfor i in range(0,20):\n    imgBGR = cv2.imread(TEST_DIR + test_generator.filenames[i])\n    imgRGB = cv2.cvtColor(imgBGR, cv2.COLOR_BGR2RGB)\n    \n    # a if condition else b\n    predicted_class = \"Dog\" if predicted_class_indices[i] else \"Cat\"\n\n    ax[i//5, i%5].imshow(imgRGB)\n    ax[i//5, i%5].axis('off')\n    ax[i//5, i%5].set_title(\"Predicted:{}\".format(predicted_class))    \n\nplt.show()","metadata":{"_uuid":"e54bc22bd1a2af7d704f9164b624b79b8cbd4f56","execution":{"iopub.status.busy":"2024-08-10T21:30:43.776272Z","iopub.execute_input":"2024-08-10T21:30:43.776649Z","iopub.status.idle":"2024-08-10T21:30:45.394684Z","shell.execute_reply.started":"2024-08-10T21:30:43.776588Z","shell.execute_reply":"2024-08-10T21:30:45.393679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We note in the end that our model succeeded in classifying all images correctly because the accuracy of the model on the test set was very high.","metadata":{}}]}