{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Preface to notebook:\n\n1. **In this notebbok I use transfer learning of VGG-16 architecture**\n\n2. I didn't use ***fine tuning*** because it does not greatly increase the accuracy of the model, but increases the training time of the neural network due to retraining of the convolutional part of VGG\n3. Also I didn't use ***augmentation***, because the samples have enough instances of each class, moreover, the classes in the training sample are evenly distributed\n4. I could use the approach with ***deep features***, but it will be on next time. Now -> transfer learning","metadata":{}},{"cell_type":"markdown","source":"# Imported libraries","metadata":{}},{"cell_type":"code","source":"import os\nimport zipfile\nimport random\nimport pandas as pd\nimport numpy as np\nimport seaborn as sns\nimport tensorflow as tf\nfrom tensorflow import keras\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import ConfusionMatrixDisplay, confusion_matrix\nfrom keras.preprocessing.image import load_img, ImageDataGenerator\nfrom keras.models import Sequential\nfrom keras.layers import Flatten, Dense, Dropout\nfrom keras.callbacks import ReduceLROnPlateau, EarlyStopping, ModelCheckpoint\nfrom keras.applications.vgg16 import VGG16, preprocess_input\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-03-31T19:36:44.877554Z","iopub.execute_input":"2022-03-31T19:36:44.877886Z","iopub.status.idle":"2022-03-31T19:36:52.046337Z","shell.execute_reply.started":"2022-03-31T19:36:44.877837Z","shell.execute_reply":"2022-03-31T19:36:52.045654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 64","metadata":{"execution":{"iopub.status.busy":"2022-03-31T19:36:52.048200Z","iopub.execute_input":"2022-03-31T19:36:52.048675Z","iopub.status.idle":"2022-03-31T19:36:52.053292Z","shell.execute_reply.started":"2022-03-31T19:36:52.048630Z","shell.execute_reply":"2022-03-31T19:36:52.052475Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"seed = 666\ntf.random.set_seed(seed)\nnp.random.seed(seed)\nos.environ[\"PYTHONHASHSEED\"] = str(seed)                      \nrandom.seed(666)","metadata":{"execution":{"iopub.status.busy":"2022-03-31T19:36:52.054808Z","iopub.execute_input":"2022-03-31T19:36:52.055150Z","iopub.status.idle":"2022-03-31T19:36:52.067332Z","shell.execute_reply.started":"2022-03-31T19:36:52.055120Z","shell.execute_reply":"2022-03-31T19:36:52.066621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.listdir(\"../input/dogs-vs-cats/\")","metadata":{"execution":{"iopub.status.busy":"2022-03-31T19:36:52.068677Z","iopub.execute_input":"2022-03-31T19:36:52.068952Z","iopub.status.idle":"2022-03-31T19:36:52.081896Z","shell.execute_reply.started":"2022-03-31T19:36:52.068922Z","shell.execute_reply":"2022-03-31T19:36:52.081090Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Unzipping folders and images","metadata":{}},{"cell_type":"code","source":"TRAIN_PATH = \"../input/dogs-vs-cats/train.zip\"\nTEST_PATH = \"../input/dogs-vs-cats/test1.zip\"\n\nFILES = \"/kaggle/files/unzipped/\"\n\nwith zipfile.ZipFile(TRAIN_PATH, 'r') as zipp:\n    zipp.extractall(FILES)\n    \nwith zipfile.ZipFile(TEST_PATH, 'r') as zipp:\n    zipp.extractall(FILES)","metadata":{"execution":{"iopub.status.busy":"2022-03-31T19:36:56.877026Z","iopub.execute_input":"2022-03-31T19:36:56.877418Z","iopub.status.idle":"2022-03-31T19:37:24.062949Z","shell.execute_reply.started":"2022-03-31T19:36:56.877390Z","shell.execute_reply":"2022-03-31T19:37:24.062070Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.listdir(\"/kaggle/files/unzipped/\")\n# for dirpath, dirnames, filenames in os.walk(\"/kaggle/files/unzipped\"):\n#     # iterate over directories\n#     for dirname in dirnames:\n#         print(\"Catalog:\", os.path.join(dirpath, dirname))\n#     # iterate over files\n#     for filename in filenames:\n#         print(\"File:\", os.path.join(dirpath, filename))","metadata":{"execution":{"iopub.status.busy":"2022-03-31T19:37:24.076641Z","iopub.execute_input":"2022-03-31T19:37:24.076926Z","iopub.status.idle":"2022-03-31T19:37:24.094214Z","shell.execute_reply.started":"2022-03-31T19:37:24.076890Z","shell.execute_reply":"2022-03-31T19:37:24.093252Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Pack the data into a dataframe and display it on the screen\n\nColumn 'label' has 2 cateegorical classes","metadata":{}},{"cell_type":"markdown","source":"train dataset","metadata":{}},{"cell_type":"code","source":"train_set = pd.DataFrame({\"image\": os.listdir(\"/kaggle/files/unzipped/train\")})\ntrain_set[\"label\"] = train_set[\"image\"].apply(lambda x: x.split(\".\")[0])#.replace({'dog': 1, 'cat':0})\n\ntrain_set","metadata":{"execution":{"iopub.status.busy":"2022-03-31T19:37:24.096207Z","iopub.execute_input":"2022-03-31T19:37:24.096522Z","iopub.status.idle":"2022-03-31T19:37:24.180787Z","shell.execute_reply.started":"2022-03-31T19:37:24.096493Z","shell.execute_reply":"2022-03-31T19:37:24.179873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"test dataset","metadata":{}},{"cell_type":"code","source":"test_set = pd.DataFrame({\"image\": os.listdir(\"/kaggle/files/unzipped/test1\")})\n\ntest_set","metadata":{"execution":{"iopub.status.busy":"2022-03-31T19:37:24.182453Z","iopub.execute_input":"2022-03-31T19:37:24.182750Z","iopub.status.idle":"2022-03-31T19:37:24.206446Z","shell.execute_reply.started":"2022-03-31T19:37:24.182711Z","shell.execute_reply":"2022-03-31T19:37:24.205609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Distribution of classes","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize = (6, 6), facecolor = \"#e5e5e5\")\nax.set_facecolor(\"#e5e5e5\")\n\nsns.countplot(x = \"label\", palette=\"Set1\", data = train_set, ax = ax)\n\nax.set_title(\"Distribution of Class Labels\")\nsns.despine()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-31T19:37:24.207448Z","iopub.execute_input":"2022-03-31T19:37:24.207643Z","iopub.status.idle":"2022-03-31T19:37:24.469875Z","shell.execute_reply.started":"2022-03-31T19:37:24.207618Z","shell.execute_reply":"2022-03-31T19:37:24.469068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Count of images with dogs in training sample: \", train_set[\"label\"].eq('dog').sum(axis=0))\nprint(\"Count of images with cats in training sample: \", train_set[\"label\"].eq('cat').sum(axis=0))","metadata":{"execution":{"iopub.status.busy":"2022-03-31T19:38:29.505144Z","iopub.execute_input":"2022-03-31T19:38:29.505763Z","iopub.status.idle":"2022-03-31T19:38:29.523640Z","shell.execute_reply.started":"2022-03-31T19:38:29.505720Z","shell.execute_reply":"2022-03-31T19:38:29.522974Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Print some images from train dataset/sample","metadata":{}},{"cell_type":"code","source":"fig = plt.figure(1, figsize = (10, 10))\nfig.suptitle(\"Training sample images \")\n\nfor i in range(36):\n\n    plt.subplot(6, 6, i + 1)\n    image = load_img(FILES + \"train/\" + train_set[\"image\"][i])\n    plt.imshow(image)\n    plt.axis(\"off\")\n    \nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:07:32.286880Z","iopub.execute_input":"2022-03-31T17:07:32.287344Z","iopub.status.idle":"2022-03-31T17:07:34.922459Z","shell.execute_reply.started":"2022-03-31T17:07:32.287292Z","shell.execute_reply":"2022-03-31T17:07:34.921798Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Splitting training dataset on:\n* train_data\n* validation_data\n* test_data","metadata":{}},{"cell_type":"code","source":"train_val_data, test_data = train_test_split(train_set, \n                                        test_size = 0.1, \n                                        stratify = train_set[\"label\"], \n                                        random_state = 666)\nnb_test_samples = test_data.shape[0]\nprint(train_val_data.shape[0], nb_test_samples)\nprint('Size of test set is: {} values'.format(nb_test_samples))","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:07:34.923357Z","iopub.execute_input":"2022-03-31T17:07:34.923586Z","iopub.status.idle":"2022-03-31T17:07:34.981128Z","shell.execute_reply.started":"2022-03-31T17:07:34.923535Z","shell.execute_reply":"2022-03-31T17:07:34.980397Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data, val_data = train_test_split(train_val_data, \n                                        test_size = 0.15, \n                                        stratify = train_val_data[\"label\"], \n                                        random_state = 666)\n\nnb_train_samples = train_data.shape[0]\nnb_validation_samples = val_data.shape[0]\nprint(nb_train_samples, nb_validation_samples)\nprint('Size of train set is: {} values\\nSize of validation set is: {} values'.format(nb_test_samples, nb_validation_samples))","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:07:34.982584Z","iopub.execute_input":"2022-03-31T17:07:34.982848Z","iopub.status.idle":"2022-03-31T17:07:35.027715Z","shell.execute_reply.started":"2022-03-31T17:07:34.982812Z","shell.execute_reply":"2022-03-31T17:07:35.027040Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Creating generators for:\n1. train_set\n* train_generator\n* val_generator\n* test_generator\n2. test_set\n* test_set_generator","metadata":{}},{"cell_type":"markdown","source":"The image generator is created based on the ImageDataGenerator class. The generator divides the values of all image pixels by 255 and converts images to BGR format with an offset.","metadata":{}},{"cell_type":"code","source":"datagen = ImageDataGenerator(rescale=1. / 255,\n                             preprocessing_function = preprocess_input)","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:07:35.030384Z","iopub.execute_input":"2022-03-31T17:07:35.030653Z","iopub.status.idle":"2022-03-31T17:07:35.034839Z","shell.execute_reply.started":"2022-03-31T17:07:35.030619Z","shell.execute_reply":"2022-03-31T17:07:35.033897Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator = datagen.flow_from_dataframe(\n    dataframe = train_data,\n    directory = FILES + \"train/\",\n    x_col = \"image\",\n    y_col = \"label\",\n    target_size=(224, 224),\n    batch_size=batch_size,\n    class_mode='binary',\n    shuffle=True,\n    seed=666)","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:07:35.036357Z","iopub.execute_input":"2022-03-31T17:07:35.036621Z","iopub.status.idle":"2022-03-31T17:07:35.612600Z","shell.execute_reply.started":"2022-03-31T17:07:35.036575Z","shell.execute_reply":"2022-03-31T17:07:35.610213Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_generator = datagen.flow_from_dataframe(\n    dataframe = val_data,\n    directory = FILES + \"train/\",\n    x_col = \"image\",\n    y_col = \"label\",\n    target_size=(224, 224),\n    batch_size=batch_size,\n    class_mode='binary',\n    shuffle=True,\n    seed=666)","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:44:28.265846Z","iopub.execute_input":"2022-03-31T17:44:28.266125Z","iopub.status.idle":"2022-03-31T17:44:28.315466Z","shell.execute_reply.started":"2022-03-31T17:44:28.266092Z","shell.execute_reply":"2022-03-31T17:44:28.314696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_generator = datagen.flow_from_dataframe(\n    dataframe = test_data,\n    directory = FILES + \"train/\",\n    x_col = \"image\",\n    y_col = \"label\",\n    target_size=(224, 224),\n    batch_size=batch_size,\n    class_mode='binary',\n    shuffle=False,\n    seed=666)","metadata":{"execution":{"iopub.status.busy":"2022-03-31T18:28:11.421359Z","iopub.execute_input":"2022-03-31T18:28:11.421869Z","iopub.status.idle":"2022-03-31T18:28:11.460770Z","shell.execute_reply.started":"2022-03-31T18:28:11.421831Z","shell.execute_reply":"2022-03-31T18:28:11.459998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_set_generator = datagen.flow_from_dataframe(\n    dataframe = test_set,\n    directory = FILES + \"test1/\",\n    x_col = \"image\",\n    target_size=(224, 224),\n    batch_size=batch_size,\n    class_mode=None,\n    shuffle=False,\n    seed=666)","metadata":{"execution":{"iopub.status.busy":"2022-03-31T18:28:26.930385Z","iopub.execute_input":"2022-03-31T18:28:26.931005Z","iopub.status.idle":"2022-03-31T18:28:27.046817Z","shell.execute_reply.started":"2022-03-31T18:28:26.930969Z","shell.execute_reply":"2022-03-31T18:28:27.046075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Loading the pre-trained neural network VGG-16 without classification part","metadata":{}},{"cell_type":"code","source":"vgg16_net = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:07:35.710601Z","iopub.execute_input":"2022-03-31T17:07:35.711425Z","iopub.status.idle":"2022-03-31T17:07:39.311216Z","shell.execute_reply.started":"2022-03-31T17:07:35.711384Z","shell.execute_reply":"2022-03-31T17:07:39.310255Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\"Freeze\" the weights of the pre-trained neural network VGG16","metadata":{}},{"cell_type":"code","source":"vgg16_net.trainable = False","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:07:39.312761Z","iopub.execute_input":"2022-03-31T17:07:39.313036Z","iopub.status.idle":"2022-03-31T17:07:39.317554Z","shell.execute_reply.started":"2022-03-31T17:07:39.312997Z","shell.execute_reply":"2022-03-31T17:07:39.316771Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Trainable params = 0","metadata":{}},{"cell_type":"code","source":"vgg16_net.summary()","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:07:39.318918Z","iopub.execute_input":"2022-03-31T17:07:39.319442Z","iopub.status.idle":"2022-03-31T17:07:39.341576Z","shell.execute_reply.started":"2022-03-31T17:07:39.319403Z","shell.execute_reply":"2022-03-31T17:07:39.340775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Function to create a composite neural network based on VGG16","metadata":{}},{"cell_type":"code","source":"def pretrained_model():\n    \n    model = Sequential([\n        vgg16_net,\n        Flatten(),\n        Dense(256, activation='relu'),\n        Dropout(0.5),\n        Dense(1, activation='sigmoid')\n    ])\n    \n    return model","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:07:39.344578Z","iopub.execute_input":"2022-03-31T17:07:39.344869Z","iopub.status.idle":"2022-03-31T17:07:39.351845Z","shell.execute_reply.started":"2022-03-31T17:07:39.344832Z","shell.execute_reply":"2022-03-31T17:07:39.351086Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = pretrained_model()","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:07:43.099443Z","iopub.execute_input":"2022-03-31T17:07:43.099744Z","iopub.status.idle":"2022-03-31T17:07:43.193550Z","shell.execute_reply.started":"2022-03-31T17:07:43.099714Z","shell.execute_reply":"2022-03-31T17:07:43.192710Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(loss='binary_crossentropy',\n              optimizer=keras.optimizers.Adam(learning_rate=1e-5), \n              metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:07:44.357032Z","iopub.execute_input":"2022-03-31T17:07:44.357299Z","iopub.status.idle":"2022-03-31T17:07:45.276493Z","shell.execute_reply.started":"2022-03-31T17:07:44.357271Z","shell.execute_reply":"2022-03-31T17:07:45.275531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Trainable params = 6 423 041","metadata":{}},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:07:45.645373Z","iopub.execute_input":"2022-03-31T17:07:45.645965Z","iopub.status.idle":"2022-03-31T17:07:45.656083Z","shell.execute_reply.started":"2022-03-31T17:07:45.645924Z","shell.execute_reply":"2022-03-31T17:07:45.655347Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Creating callbacks","metadata":{}},{"cell_type":"code","source":"reduce_lr = ReduceLROnPlateau(\n    monitor = \"val_accuracy\", \n    patience = 2,\n    verbose = 1, \n    factor = 0.5, \n    min_lr = 0.000000001\n)\n\nearly_stopping = EarlyStopping(\n    monitor = \"val_accuracy\",\n    patience = 5,\n    verbose = 1,\n    mode = \"max\",\n)\n\ncheckpoint = ModelCheckpoint(\n    monitor = \"val_accuracy\",\n    filepath = \"catdog_vgg16_.{epoch:02d}-{val_accuracy:.6f}.hdf5\",\n    verbose = 1,\n    save_best_only = True, \n    save_weights_only = True\n)","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:07:48.074267Z","iopub.execute_input":"2022-03-31T17:07:48.074892Z","iopub.status.idle":"2022-03-31T17:07:48.080941Z","shell.execute_reply.started":"2022-03-31T17:07:48.074851Z","shell.execute_reply":"2022-03-31T17:07:48.080075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"just my opportunity research of kaggle notebook","metadata":{}},{"cell_type":"code","source":"#!ls -alh /tmp \n\n#!whoami\n\n#!ls /kaggle/files #same\n#os.listdir(\"/kaggle/files\") #same\n\n#!pwd","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:07:48.942913Z","iopub.execute_input":"2022-03-31T17:07:48.943185Z","iopub.status.idle":"2022-03-31T17:07:48.947103Z","shell.execute_reply.started":"2022-03-31T17:07:48.943152Z","shell.execute_reply":"2022-03-31T17:07:48.946082Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train the model using generators","metadata":{}},{"cell_type":"code","source":"history = model.fit(\n    train_generator,\n    steps_per_epoch=nb_train_samples // batch_size,\n    epochs=10,\n    validation_data=val_generator,\n    validation_steps=nb_validation_samples // batch_size,\n    callbacks = [reduce_lr, early_stopping, checkpoint]\n)","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:07:51.322653Z","iopub.execute_input":"2022-03-31T17:07:51.323283Z","iopub.status.idle":"2022-03-31T17:28:46.365670Z","shell.execute_reply.started":"2022-03-31T17:07:51.323240Z","shell.execute_reply":"2022-03-31T17:28:46.364888Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# tf.keras.backend.clear_session()\n\n# model = pretrained_model()\n\n# model.load_weights(\"./catdog_vgg16_.10-0.944111.hdf5\")","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Plotting losses and accuracy for validation sample","metadata":{}},{"cell_type":"code","source":"fig, axes = plt.subplots(1, 2, figsize = (12, 4))\n\nsns.lineplot(x = range(len(history.history[\"loss\"])), y = history.history[\"loss\"], ax = axes[0], label = \"Training Loss\")\nsns.lineplot(x = range(len(history.history[\"loss\"])), y = history.history[\"val_loss\"], ax = axes[0], label = \"Validation Loss\")\n\nsns.lineplot(x = range(len(history.history[\"accuracy\"])), y = history.history[\"accuracy\"], ax = axes[1], label = \"Training Accuracy\")\nsns.lineplot(x = range(len(history.history[\"accuracy\"])), y = history.history[\"val_accuracy\"], ax = axes[1], label = \"Validation Accuracy\")\naxes[0].set_title(\"Loss\"); axes[1].set_title(\"Accuracy\")\n\nsns.despine()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-31T17:29:05.381092Z","iopub.execute_input":"2022-03-31T17:29:05.381377Z","iopub.status.idle":"2022-03-31T17:29:05.747851Z","shell.execute_reply.started":"2022-03-31T17:29:05.381341Z","shell.execute_reply":"2022-03-31T17:29:05.747168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Evaluating accuracy of testing part of our train sample","metadata":{}},{"cell_type":"code","source":"scores = model.evaluate_generator(test_generator, nb_test_samples // batch_size)\nprint(\"Accuracy on test data: %.2f%%\" % (scores[1]*100))","metadata":{"execution":{"iopub.status.busy":"2022-03-31T18:18:24.898984Z","iopub.execute_input":"2022-03-31T18:18:24.899270Z","iopub.status.idle":"2022-03-31T18:18:35.373486Z","shell.execute_reply.started":"2022-03-31T18:18:24.899237Z","shell.execute_reply":"2022-03-31T18:18:35.372740Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Predict results for testing part","metadata":{}},{"cell_type":"code","source":"test_data_pred = model.predict(test_generator, steps = np.ceil(nb_test_samples / batch_size))\n#print(test_data[0:30])\ntest_data.loc[:, \"test_data_pred\"] = np.around(test_data_pred).astype(int)\ntest_data[\"test_data_pred\"] = test_data[\"test_data_pred\"].replace({1: 'dog', 0:'cat'})\nprint(test_data.head(30))","metadata":{"execution":{"iopub.status.busy":"2022-03-31T18:15:16.765237Z","iopub.execute_input":"2022-03-31T18:15:16.765799Z","iopub.status.idle":"2022-03-31T18:15:26.404971Z","shell.execute_reply.started":"2022-03-31T18:15:16.765762Z","shell.execute_reply":"2022-03-31T18:15:26.403386Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Plotting confusion matrix of predicted values for testing part of training sample","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize = (9, 6))\n\ncm = confusion_matrix(test_data[\"label\"], test_data[\"test_data_pred\"])\n\ndisp = ConfusionMatrixDisplay(confusion_matrix = cm, display_labels = [\"cat\", \"dog\"])\ndisp.plot(cmap = 'YlOrBr', ax = ax)\n\nax.set_title(\"Test data Set\")\nplt.xlabel('Predicted values')\nplt.ylabel('True values')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-31T18:18:59.318151Z","iopub.execute_input":"2022-03-31T18:18:59.318425Z","iopub.status.idle":"2022-03-31T18:18:59.913216Z","shell.execute_reply.started":"2022-03-31T18:18:59.318395Z","shell.execute_reply":"2022-03-31T18:18:59.912547Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Evaluate the quality of training using other metrics","metadata":{}},{"cell_type":"code","source":"from sklearn.metrics import classification_report\nprint(classification_report(test_data[\"label\"], test_data[\"test_data_pred\"]))","metadata":{"execution":{"iopub.status.busy":"2022-03-31T18:19:29.515218Z","iopub.execute_input":"2022-03-31T18:19:29.515781Z","iopub.status.idle":"2022-03-31T18:19:29.664203Z","shell.execute_reply.started":"2022-03-31T18:19:29.515742Z","shell.execute_reply":"2022-03-31T18:19:29.663404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Let's evaluate and see the results where our model is wrong","metadata":{}},{"cell_type":"code","source":"test_data_errors = test_data[(test_data.label) != (test_data.test_data_pred)].reset_index(drop = True)\ntest_data_errors","metadata":{"execution":{"iopub.status.busy":"2022-03-31T18:20:18.008599Z","iopub.execute_input":"2022-03-31T18:20:18.009142Z","iopub.status.idle":"2022-03-31T18:20:18.022795Z","shell.execute_reply.started":"2022-03-31T18:20:18.009105Z","shell.execute_reply":"2022-03-31T18:20:18.021798Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = plt.figure(1, figsize = (15, 5))\n\nfor i in range(5):\n    \n    plt.subplot(1, 5, i + 1)\n    image = load_img(\"/kaggle/files/unzipped/train/\" + test_data_errors.image[i])\n    plt.imshow(image)\n    plt.axis(\"off\")\n    plt.title(f\"True Value: {test_data_errors['label'][i]} \\nPrediction: {test_data_errors['test_data_pred'][i]}\")    \n    \nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-31T18:20:53.436003Z","iopub.execute_input":"2022-03-31T18:20:53.436251Z","iopub.status.idle":"2022-03-31T18:20:53.920944Z","shell.execute_reply.started":"2022-03-31T18:20:53.436223Z","shell.execute_reply":"2022-03-31T18:20:53.920180Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Lets use the trained NN on test sample","metadata":{}},{"cell_type":"code","source":"test_preds = model.predict(test_set_generator, steps = np.ceil(test_set.shape[0] / batch_size))\n\ntest_set[\"test_set_preds\"] = np.around(test_preds).astype(int)\ntest_set[\"test_set_preds\"] = test_set[\"test_set_preds\"].replace({1: 'dog', 0:'cat'})","metadata":{"execution":{"iopub.status.busy":"2022-03-31T18:34:13.704788Z","iopub.execute_input":"2022-03-31T18:34:13.705060Z","iopub.status.idle":"2022-03-31T18:34:59.215710Z","shell.execute_reply.started":"2022-03-31T18:34:13.705030Z","shell.execute_reply":"2022-03-31T18:34:59.214849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Here we can see how our network performed on test sample","metadata":{}},{"cell_type":"code","source":"sample_test = test_set.sample(9).reset_index(drop = True)\n\nfig = plt.figure(1, figsize = (10, 10))\nfig.suptitle(\"Sample Predictions\")\n\nfor i in range(len(sample_test)):\n    \n    plt.subplot(3, 3, i + 1)\n    image = load_img(\"/kaggle/files/unzipped/test1/\" + sample_test.image[i])\n    plt.imshow(image)\n    plt.axis(\"off\")\n    plt.title(f\"Predicted as {sample_test['test_set_preds'][i]}\")\n    \nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-31T18:37:47.439467Z","iopub.execute_input":"2022-03-31T18:37:47.449694Z","iopub.status.idle":"2022-03-31T18:37:48.607612Z","shell.execute_reply.started":"2022-03-31T18:37:47.449639Z","shell.execute_reply":"2022-03-31T18:37:48.606926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Let's check how our network will cope with a random picture from the Internet","metadata":{}},{"cell_type":"markdown","source":"I bring the image to the desired input format, on which the network was trained","metadata":{}},{"cell_type":"code","source":"import io\nimport PIL\nimport requests\n\nimage_response = requests.get('https://r4.mt.ru/r4/photo09F4/20944082743-0/png/bp.webp')\npil_im = PIL.Image.open(io.BytesIO(image_response.content)).resize((224,224))\nplt.axis(\"off\")\nplt.imshow(pil_im)\nimg = np.array(pil_im)\nx = preprocess_input(img)\nx = x/255\nx = np.expand_dims(x, axis=0)\nx.shape","metadata":{"execution":{"iopub.status.busy":"2022-03-31T19:06:40.147415Z","iopub.execute_input":"2022-03-31T19:06:40.147680Z","iopub.status.idle":"2022-03-31T19:06:41.344049Z","shell.execute_reply.started":"2022-03-31T19:06:40.147651Z","shell.execute_reply":"2022-03-31T19:06:41.343315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"res = model.predict(x)\nif res>=0.5:\n    res1='dog'\nelse:\n    res1='cat'\n    \nplt.title(f\"Predicted as: {res1}, model confidence: {res[0][0]:.4f}\")\nplt.axis(\"off\")\nplt.imshow(pil_im)","metadata":{"execution":{"iopub.status.busy":"2022-03-31T19:14:33.575880Z","iopub.execute_input":"2022-03-31T19:14:33.576132Z","iopub.status.idle":"2022-03-31T19:14:33.796501Z","shell.execute_reply.started":"2022-03-31T19:14:33.576103Z","shell.execute_reply":"2022-03-31T19:14:33.795560Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Materials that helped me understand the material on the basics of convolutional neural networks","metadata":{}},{"cell_type":"markdown","source":"eng:\n1. https://www.kaggle.com/code/mustafacicek/dogs-cats-vgg16-implementation-transfer-learning#5)-Pre-Trained-VGG-16-Model-&-Transfer-Learning\n2. https://keras.io/ (really a lot of pages, so summarized to the main page)\n3. https://towardsdatascience.com/illustrated-10-cnn-architectures-95d78ace614d#c5a6\n4. https://www.kaggle.com/code/rajmehra03/a-comprehensive-guide-to-transfer-learning/notebook\n5. https://www.kaggle.com/code/uysimty/keras-cnn-dog-or-cat-classification/notebook\n6. https://www.kaggle.com/code/mustafacicek/mnist-cnn-data-augmentation/notebook\n7. https://scikit-learn.org/stable/modules/cross_validation.html#stratification\n8. https://www.kaggle.com/code/lbronchal/keras-gpu-cpu-reproducibility-test/notebook#Conclusion (seeds)\n9. https://towardsdatascience.com/understanding-8-types-of-cross-validation-80c935a4976d (remembered about cross validation)\n\nrus:\n1. https://www.asozykin.ru/courses/nnpython\n2. https://proproprogs.ru/data\n3. https://ru-keras.com/","metadata":{}}]}