{"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":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nimport PIL\n\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator","metadata":{"execution":{"iopub.status.busy":"2021-12-18T16:36:19.365152Z","iopub.execute_input":"2021-12-18T16:36:19.365405Z","iopub.status.idle":"2021-12-18T16:36:19.371197Z","shell.execute_reply.started":"2021-12-18T16:36:19.36538Z","shell.execute_reply":"2021-12-18T16:36:19.370486Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ndata_set = \"dogs-vs-cats\"\n\nimport zipfile \nwith zipfile.ZipFile(\"/kaggle/input/\"+ data_set +\"/train.zip\",\"r\") as z:\n    z.extractall(\".\")\n    # save all files to kaggle/files/images\n    destination = '/kaggle/files/images/train'\n    z.extractall(destination)\n    \nwith zipfile.ZipFile(\"/kaggle/input/\"+ data_set +\"/test1.zip\",\"r\") as z:\n    z.extractall(\".\")\n    # save all files to kaggle/files/images\n    destination = '/kaggle/files/images/test'\n    z.extractall(destination)","metadata":{"execution":{"iopub.status.busy":"2021-12-18T16:36:19.372784Z","iopub.execute_input":"2021-12-18T16:36:19.373332Z","iopub.status.idle":"2021-12-18T16:36:45.935718Z","shell.execute_reply.started":"2021-12-18T16:36:19.373298Z","shell.execute_reply":"2021-12-18T16:36:45.934973Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#print(os.listdir('/kaggle/files/images/test/test1'))\n#print(os.listdir('/kaggle/files/images/train/train'))","metadata":{"execution":{"iopub.status.busy":"2021-12-18T16:36:45.937188Z","iopub.execute_input":"2021-12-18T16:36:45.937439Z","iopub.status.idle":"2021-12-18T16:36:45.945441Z","shell.execute_reply.started":"2021-12-18T16:36:45.937404Z","shell.execute_reply":"2021-12-18T16:36:45.944919Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# create a train/test df, containing the image filepaths and training label\nimport os\n \ndef list_full_paths(directory):\n    return [os.path.join(directory, file) for file in os.listdir(directory)]\n\ntrain = pd.DataFrame({'filepath': list_full_paths('/kaggle/files/images/train/train')})\ntrain['truth_label'] = np.where(train['filepath'].str.contains('dog'), 'dog', 'cat')\n\ntest = pd.DataFrame({'filepath': list_full_paths('/kaggle/files/images/test/test1')})","metadata":{"execution":{"iopub.status.busy":"2021-12-18T16:36:45.94624Z","iopub.execute_input":"2021-12-18T16:36:45.946592Z","iopub.status.idle":"2021-12-18T16:36:47.237934Z","shell.execute_reply.started":"2021-12-18T16:36:45.946561Z","shell.execute_reply":"2021-12-18T16:36:47.237223Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head(20)","metadata":{"execution":{"iopub.status.busy":"2021-12-18T16:36:47.240322Z","iopub.execute_input":"2021-12-18T16:36:47.240615Z","iopub.status.idle":"2021-12-18T16:36:47.250478Z","shell.execute_reply.started":"2021-12-18T16:36:47.240575Z","shell.execute_reply":"2021-12-18T16:36:47.249527Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.head()","metadata":{"execution":{"iopub.status.busy":"2021-12-18T16:36:47.251763Z","iopub.execute_input":"2021-12-18T16:36:47.252015Z","iopub.status.idle":"2021-12-18T16:36:47.263489Z","shell.execute_reply.started":"2021-12-18T16:36:47.251982Z","shell.execute_reply":"2021-12-18T16:36:47.262784Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# examples of image visualisation\nbasepath = '/kaggle/files/images/train/train/'\nfig, axs = plt.subplots(2, 2, figsize=(10, 10))\n_ = axs[0, 0].imshow(PIL.Image.open(basepath + 'dog.1.jpg'))\n_ = axs[0, 0].axis('off')\n\n_ = axs[0, 1].imshow(PIL.Image.open(basepath + 'dog.2.jpg'))\n_ = axs[0, 1].axis('off')\n\n_ = axs[1, 0].imshow(PIL.Image.open(basepath + 'cat.1.jpg'))\n_ = axs[1, 0].axis('off')\n\n_ = axs[1, 1].imshow(PIL.Image.open(basepath + 'cat.2.jpg'))\n_ = axs[1, 1].axis('off')","metadata":{"execution":{"iopub.status.busy":"2021-12-18T16:36:47.265668Z","iopub.execute_input":"2021-12-18T16:36:47.266301Z","iopub.status.idle":"2021-12-18T16:36:47.695137Z","shell.execute_reply.started":"2021-12-18T16:36:47.266249Z","shell.execute_reply":"2021-12-18T16:36:47.694504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# split train into train and validation, ensuring reproducability\nfrom sklearn.model_selection import train_test_split\ntrain, validation = train_test_split(train, test_size=0.2, random_state=1, shuffle=True)","metadata":{"execution":{"iopub.status.busy":"2021-12-18T16:36:47.696269Z","iopub.execute_input":"2021-12-18T16:36:47.696638Z","iopub.status.idle":"2021-12-18T16:36:47.707615Z","shell.execute_reply.started":"2021-12-18T16:36:47.696609Z","shell.execute_reply":"2021-12-18T16:36:47.70637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#train.head(10)\n#validation.head(10)\nprint(np.sum(train['truth_label'] == 'cat') / len(train))\nprint(np.sum(train['truth_label'] == 'dog') / len(train))\n\nprint(np.sum(validation['truth_label'] == 'cat') / len(validation))\nprint(np.sum(validation['truth_label'] == 'dog') / len(validation))\n\n# roughly even splitting, no need for reweighting/resampling","metadata":{"execution":{"iopub.status.busy":"2021-12-18T16:36:47.708822Z","iopub.execute_input":"2021-12-18T16:36:47.709191Z","iopub.status.idle":"2021-12-18T16:36:47.730281Z","shell.execute_reply.started":"2021-12-18T16:36:47.709159Z","shell.execute_reply":"2021-12-18T16:36:47.729543Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# data pre-processing\ntrain_gen = ImageDataGenerator(rescale=1. / 255)\nval_gen = ImageDataGenerator(rescale=1. / 255)\n\ntrain_generator      = train_gen.flow_from_dataframe(dataframe=train, x_col='filepath', y_col='truth_label', class_mode='categorical')\nvalidation_generator = val_gen.flow_from_dataframe(dataframe=validation, x_col='filepath', y_col='truth_label', class_mode='categorical')","metadata":{"execution":{"iopub.status.busy":"2021-12-18T16:36:47.731496Z","iopub.execute_input":"2021-12-18T16:36:47.732172Z","iopub.status.idle":"2021-12-18T16:36:47.989496Z","shell.execute_reply.started":"2021-12-18T16:36:47.732136Z","shell.execute_reply":"2021-12-18T16:36:47.988799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# TODO data augmentation\n* Random flips/rotatations\n* Random zooms\n* Colour scaling/reversing?","metadata":{}},{"cell_type":"code","source":"# data augmentation\nfrom tensorflow.keras.layers import RandomFlip, RandomRotation, RandomZoom\n\ninput_shape = (255, 255, 3)\n\ndata_augmentation = keras.Sequential()\ndata_augmentation.add(RandomFlip('horizontal', input_shape=input_shape))\ndata_augmentation.add(RandomRotation(0.1))\ndata_augmentation.add(RandomZoom(0.1))\n\n# model definition\nmodel = Sequential()\n\nmodel.add(data_augmentation)\n\nmodel.add(Conv2D(input_shape=input_shape, filters=32, kernel_size=(3, 3), activation='relu'))\nmodel.add(MaxPooling2D(2, 2))\n\nmodel.add(Conv2D(input_shape=input_shape, filters=64, kernel_size=(3, 3), activation='relu'))\nmodel.add(MaxPooling2D(2, 2))\n\nmodel.add(Conv2D(input_shape=input_shape, filters=128, kernel_size=(3, 3), activation='relu'))\nmodel.add(MaxPooling2D(2, 2))\n\n\nmodel.add(Flatten())\n\nmodel.add(Dense(10, activation='relu'))\nmodel.add(Dense(2, activation='softmax'))\n\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-12-18T16:36:47.990984Z","iopub.execute_input":"2021-12-18T16:36:47.99123Z","iopub.status.idle":"2021-12-18T16:36:48.286926Z","shell.execute_reply.started":"2021-12-18T16:36:47.991197Z","shell.execute_reply":"2021-12-18T16:36:48.286141Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# fit data\nmodel.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n\n# callbacks\nes = EarlyStopping(monitor='val_loss', patience=15, verbose=1, mode='min', restore_best_weights=True)\nlr = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=10, verbose=1, mode='min', min_lr=0.00000001)\n\nepochs = 100\nwith tf.device('/device:GPU:0'):\n    history = model.fit(train_generator, validation_data=validation_generator, epochs=epochs, callbacks=[es, lr])","metadata":{"execution":{"iopub.status.busy":"2021-12-18T16:36:48.288421Z","iopub.execute_input":"2021-12-18T16:36:48.28865Z","iopub.status.idle":"2021-12-18T18:33:09.466078Z","shell.execute_reply.started":"2021-12-18T16:36:48.288619Z","shell.execute_reply":"2021-12-18T18:33:09.465031Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axs = plt.subplots(1, 2, figsize = (10, 5))\n_ = axs[0].plot(history.history['loss'], label='Test')\n_ = axs[0].plot(history.history['val_loss'], label='Validation')\naxs[0].set_xlabel('epochs')\naxs[0].set_ylabel('loss')\n_ = axs[0].legend()\n\n_ = axs[1].plot(history.history['accuracy'], label='Test')\n_ = axs[1].plot(history.history['val_accuracy'], label='Validation')\naxs[1].set_xlabel('epochs')\naxs[1].set_ylabel('accuracy')\n_ = axs[1].legend()","metadata":{"execution":{"iopub.status.busy":"2021-12-18T18:33:09.468598Z","iopub.execute_input":"2021-12-18T18:33:09.468925Z","iopub.status.idle":"2021-12-18T18:33:09.999815Z","shell.execute_reply.started":"2021-12-18T18:33:09.468882Z","shell.execute_reply":"2021-12-18T18:33:09.999144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# pred on validation, submit predictions to kaggle\n#y_pred = np.argmax(model.predict(X_test), axis=1)\n#from sklearn.metrics import ConfusionMatrixDisplay\n#_ = ConfusionMatrixDisplay.from_predictions(test.class_protein_localization.values, y_pred, normalize='true')","metadata":{"execution":{"iopub.status.busy":"2021-12-18T18:33:10.001205Z","iopub.execute_input":"2021-12-18T18:33:10.001671Z","iopub.status.idle":"2021-12-18T18:33:10.007499Z","shell.execute_reply.started":"2021-12-18T18:33:10.001633Z","shell.execute_reply":"2021-12-18T18:33:10.006256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}