{"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 numpy as np\nimport sys\nimport tensorflow as tf\nimport os\nimport pandas as pd\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n%matplotlib inline\nimport matplotlib.pyplot as plt","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-07-10T02:15:12.832424Z","iopub.execute_input":"2023-07-10T02:15:12.833060Z","iopub.status.idle":"2023-07-10T02:15:29.283115Z","shell.execute_reply.started":"2023-07-10T02:15:12.833028Z","shell.execute_reply":"2023-07-10T02:15:29.281123Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import zipfile\n\nzip_paths = ['/kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip' , '/kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip']  # 압축 파일의 경로와 파일명\nextract_dir = '/kaggle/working/'  # 압축 해제할 폴더의 경로와 이름\n\nfor zip_path in zip_paths:\n  with zipfile.ZipFile(zip_path, 'r') as zip_ref:\n      zip_ref.extractall(extract_dir)","metadata":{"execution":{"iopub.status.busy":"2023-07-10T02:19:07.733942Z","iopub.execute_input":"2023-07-10T02:19:07.735064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train 폴더 확인\ntrain_folder_path = '/kaggle/working/train'\n\ntrain_file_names = os.listdir(train_folder_path)\nprint(\"train file name\" , train_file_names[:5] )\nprint(\"train file numbers\" , len(train_file_names))","metadata":{"execution":{"iopub.status.busy":"2023-07-10T02:25:43.353879Z","iopub.execute_input":"2023-07-10T02:25:43.354267Z","iopub.status.idle":"2023-07-10T02:25:43.377369Z","shell.execute_reply.started":"2023-07-10T02:25:43.354237Z","shell.execute_reply":"2023-07-10T02:25:43.376422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# test 폴더 확인\ntest_folder_path = '/kaggle/working/test'\n\ntest_file_names = os.listdir(test_folder_path)\nprint(\"test file name\" , test_file_names[:5] )\nprint(\"test file numbers\" , len(test_file_names))","metadata":{"execution":{"iopub.status.busy":"2023-07-10T02:27:39.693254Z","iopub.execute_input":"2023-07-10T02:27:39.693642Z","iopub.status.idle":"2023-07-10T02:27:39.708603Z","shell.execute_reply.started":"2023-07-10T02:27:39.693611Z","shell.execute_reply":"2023-07-10T02:27:39.707534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train dataframe\n\ntargets = []\nfull_paths = []\ntrain_cats_dir = []\ntrain_dogs_dir = []\n\n\n# Target setting\nfor file_name in train_file_names:\n    target = file_name.split(\".\")[0] # target name\n    full_path = os.path.join(train_folder_path, file_name)\n\n    if(target == \"dog\"):\n        train_dogs_dir.append(full_path)\n    if(target == \"cat\"):\n        train_cats_dir.append(full_path)\n\n    full_paths.append(full_path)\n    targets.append(target)\n\n\ndf_train = pd.DataFrame()\ndf_train['image_path'] = full_paths\ndf_train['target'] = targets","metadata":{"execution":{"iopub.status.busy":"2023-07-10T02:28:27.092473Z","iopub.execute_input":"2023-07-10T02:28:27.092863Z","iopub.status.idle":"2023-07-10T02:28:27.180326Z","shell.execute_reply.started":"2023-07-10T02:28:27.092831Z","shell.execute_reply":"2023-07-10T02:28:27.179421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Test Data DataFrame\nfull_paths = []\nfile_names = []\n\nfor file_name in test_file_names:\n    full_path = os.path.join(test_folder_path, file_name)\n\n    file_names.append(file_name)\n    full_paths.append(full_path)\n\n\ndf_test = pd.DataFrame()\ndf_test['image_path'] = full_paths\ndf_test['filename'] = file_names","metadata":{"execution":{"iopub.status.busy":"2023-07-10T02:28:38.968760Z","iopub.execute_input":"2023-07-10T02:28:38.969395Z","iopub.status.idle":"2023-07-10T02:28:39.011413Z","shell.execute_reply.started":"2023-07-10T02:28:38.969357Z","shell.execute_reply":"2023-07-10T02:28:39.010481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data , val_data = train_test_split(df_train, test_size=0.2, random_state=123)","metadata":{"execution":{"iopub.status.busy":"2023-07-10T02:28:54.774030Z","iopub.execute_input":"2023-07-10T02:28:54.774380Z","iopub.status.idle":"2023-07-10T02:28:54.797062Z","shell.execute_reply.started":"2023-07-10T02:28:54.774353Z","shell.execute_reply":"2023-07-10T02:28:54.796170Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import seaborn as sns\nprint('학습 데이터 개수 ' , len(train_data))\nprint('검증 데이터 개수 ' , len(val_data))\n\nplt.suptitle('Train Class Count')\nsns.countplot(data = df_train , x='target')","metadata":{"execution":{"iopub.status.busy":"2023-07-10T02:29:13.334372Z","iopub.execute_input":"2023-07-10T02:29:13.334731Z","iopub.status.idle":"2023-07-10T02:29:14.018861Z","shell.execute_reply.started":"2023-07-10T02:29:13.334702Z","shell.execute_reply":"2023-07-10T02:29:14.017714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.suptitle('Sub-Train Class Count')\nsns.countplot(data = train_data , x='target')","metadata":{"execution":{"iopub.status.busy":"2023-07-10T03:34:47.140745Z","iopub.execute_input":"2023-07-10T03:34:47.141477Z","iopub.status.idle":"2023-07-10T03:34:47.390458Z","shell.execute_reply.started":"2023-07-10T03:34:47.141442Z","shell.execute_reply":"2023-07-10T03:34:47.389539Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.suptitle('Sub-Val Class Count')\nsns.countplot(data = val_data , x='target')","metadata":{"execution":{"iopub.status.busy":"2023-07-10T03:34:52.220297Z","iopub.execute_input":"2023-07-10T03:34:52.220673Z","iopub.status.idle":"2023-07-10T03:34:52.458522Z","shell.execute_reply.started":"2023-07-10T03:34:52.220640Z","shell.execute_reply":"2023-07-10T03:34:52.457650Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 테스트 parameter Initialization\nbatch_size = 128\nepochs = 30\nIMG_HEIGHT = 256\nIMG_WIDTH = 256","metadata":{"execution":{"iopub.status.busy":"2023-07-10T02:29:51.752804Z","iopub.execute_input":"2023-07-10T02:29:51.753521Z","iopub.status.idle":"2023-07-10T02:29:51.758439Z","shell.execute_reply.started":"2023-07-10T02:29:51.753485Z","shell.execute_reply":"2023-07-10T02:29:51.757141Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.applications.vgg16 import preprocess_input as vgg16_preprocess_input\n\n# DataGenrator 를 사용해서 Train , Val , Test data 를 생성 하도록 한다.\nimage_gen_train = ImageDataGenerator(rescale=1./255,\n                                     rotation_range=10,\n                                     width_shift_range=0.1,\n                                     height_shift_range=0.1,\n                                     zoom_range=0.1,\n                                     horizontal_flip=True,\n                                     preprocessing_function = vgg16_preprocess_input)\n\ntrain_data_gen = image_gen_train.flow_from_dataframe(batch_size = batch_size,\n                                                     dataframe = train_data,\n                                                     x_col = 'image_path',\n                                                     y_col = 'target',\n                                                     shuffle=True,\n                                                     target_size=(IMG_HEIGHT, IMG_WIDTH),\n                                                     class_mode='binary')\n\nval_datagen = ImageDataGenerator(rescale=1./255)\n\nval_data_gen = val_datagen.flow_from_dataframe(batch_size = batch_size,\n                                                     dataframe = val_data,\n                                                     x_col = 'image_path',\n                                                     y_col = 'target',\n                                                     target_size=(IMG_HEIGHT, IMG_WIDTH),\n                                                     class_mode='binary')","metadata":{"execution":{"iopub.status.busy":"2023-07-10T02:30:32.087748Z","iopub.execute_input":"2023-07-10T02:30:32.088206Z","iopub.status.idle":"2023-07-10T02:30:32.402747Z","shell.execute_reply.started":"2023-07-10T02:30:32.088171Z","shell.execute_reply":"2023-07-10T02:30:32.401673Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# callback 선언.\nfrom keras.callbacks import EarlyStopping , ReduceLROnPlateau\n\nearly_stopping = EarlyStopping(monitor='val_loss', patience=5, verbose=1, mode='min')\nreduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=3, verbose=1, mode='min')\n\ncallbacks = [early_stopping, reduce_lr]","metadata":{"execution":{"iopub.status.busy":"2023-07-10T02:31:31.277088Z","iopub.execute_input":"2023-07-10T02:31:31.278085Z","iopub.status.idle":"2023-07-10T02:31:31.284382Z","shell.execute_reply.started":"2023-07-10T02:31:31.278042Z","shell.execute_reply":"2023-07-10T02:31:31.283164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.applications import VGG16\nfrom keras import models, layers\n\n# VGG16 모델 불러오기\nvgg16 = VGG16(input_shape=(IMG_HEIGHT,IMG_WIDTH,3), include_top=False, weights=\"imagenet\")\n\n# 모든 층을 고정\nfor layer in vgg16.layers:\n    layer.trainable = False\n\n# FC Layer 추가하기\nmodel = models.Sequential()\nmodel.add(vgg16)\nmodel.add(layers.Flatten())\nmodel.add(layers.Dense(256, activation='relu'))\nmodel.add(layers.Dense(1, activation='sigmoid'))\n\n\nmodel.compile(loss = tf.keras.losses.binary_crossentropy,\n              optimizer = tf.keras.optimizers.RMSprop(learning_rate=1e-4), metrics=['accuracy'])\n\nhistory = model.fit(\n  train_data_gen,\n    \n  steps_per_epoch= train_data.shape[0]/batch_size,\n  validation_steps= val_data.shape[0]/batch_size,\n  batch_size = batch_size,\n  epochs=epochs,\n  callbacks = callbacks,\n  validation_data= val_data_gen)","metadata":{"execution":{"iopub.status.busy":"2023-07-10T03:57:00.887597Z","iopub.execute_input":"2023-07-10T03:57:00.887993Z","iopub.status.idle":"2023-07-10T07:07:43.123733Z","shell.execute_reply.started":"2023-07-10T03:57:00.887963Z","shell.execute_reply":"2023-07-10T07:07:43.122717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save('./kaggle/working/vgg16_ver1.h5')","metadata":{"execution":{"iopub.status.busy":"2023-07-10T07:16:03.589221Z","iopub.execute_input":"2023-07-10T07:16:03.589607Z","iopub.status.idle":"2023-07-10T07:16:03.956044Z","shell.execute_reply.started":"2023-07-10T07:16:03.589578Z","shell.execute_reply":"2023-07-10T07:16:03.954767Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_model_history(model_history, acc='accuracy', val_acc='val_accuracy'):\n    fig, axs = plt.subplots(1,2,figsize=(15,5))\n\n    axs[0].plot(range(1,len(model_history.history[acc])+1),model_history.history[acc])\n    axs[0].plot(range(1,len(model_history.history[val_acc])+1),model_history.history[val_acc])\n    axs[0].set_title('Model Accuracy')\n    axs[0].set_ylabel('Accuracy')\n    axs[0].set_xlabel('Epoch')\n\n    axs[0].legend(['train', 'val'], loc='best')\n\n    axs[1].plot(range(1,len(model_history.history['loss'])+1),model_history.history['loss'])\n    axs[1].plot(range(1,len(model_history.history['val_loss'])+1),model_history.history['val_loss'])\n    axs[1].set_title('Model Loss')\n    axs[1].set_ylabel('Loss')\n    axs[1].set_xlabel('Epoch')\n\n    axs[1].legend(['train', 'val'], loc='best')\n    plt.show()\n\nplot_model_history(history)","metadata":{"execution":{"iopub.status.busy":"2023-07-10T07:16:19.950344Z","iopub.execute_input":"2023-07-10T07:16:19.950695Z","iopub.status.idle":"2023-07-10T07:16:20.524285Z","shell.execute_reply.started":"2023-07-10T07:16:19.950666Z","shell.execute_reply":"2023-07-10T07:16:20.523317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_datagen = ImageDataGenerator(rescale=1./255)\n\ntest_data_gen = test_datagen.flow_from_dataframe(batch_size = batch_size,\n                                                     dataframe = df_test,\n                                                     x_col = 'image_path',\n                                                     y_col = 'target',\n                                                     target_size=(IMG_HEIGHT, IMG_WIDTH),\n                                                     class_mode=None)","metadata":{"execution":{"iopub.status.busy":"2023-07-10T07:22:01.080436Z","iopub.execute_input":"2023-07-10T07:22:01.080853Z","iopub.status.idle":"2023-07-10T07:22:01.203412Z","shell.execute_reply.started":"2023-07-10T07:22:01.080819Z","shell.execute_reply":"2023-07-10T07:22:01.202341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 모델 예측하기\npred = model.predict(test_data_gen)\n\n# 임계값 적용하기\npredictions = (pred > 0.5).astype(int)\ndf_test['pred']  = predictions","metadata":{"execution":{"iopub.status.busy":"2023-07-10T07:47:29.291812Z","iopub.execute_input":"2023-07-10T07:47:29.292169Z","iopub.status.idle":"2023-07-10T07:48:44.463024Z","shell.execute_reply.started":"2023-07-10T07:47:29.292140Z","shell.execute_reply":"2023-07-10T07:48:44.461913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submission = df_test.copy()\ndf_submission['id'] = df_submission['filename'].str.split('.').str[0]\ndf_submission['label'] = df_submission['pred']","metadata":{"execution":{"iopub.status.busy":"2023-07-10T07:48:51.316978Z","iopub.execute_input":"2023-07-10T07:48:51.317372Z","iopub.status.idle":"2023-07-10T07:48:51.349167Z","shell.execute_reply.started":"2023-07-10T07:48:51.317340Z","shell.execute_reply":"2023-07-10T07:48:51.348237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submission.head()","metadata":{"execution":{"iopub.status.busy":"2023-07-10T07:48:56.087614Z","iopub.execute_input":"2023-07-10T07:48:56.088558Z","iopub.status.idle":"2023-07-10T07:48:56.102990Z","shell.execute_reply.started":"2023-07-10T07:48:56.088521Z","shell.execute_reply":"2023-07-10T07:48:56.101569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submission.drop(['filename','image_path', 'pred'], axis=1, inplace=True)","metadata":{"execution":{"iopub.status.busy":"2023-07-10T07:49:00.610374Z","iopub.execute_input":"2023-07-10T07:49:00.610766Z","iopub.status.idle":"2023-07-10T07:49:00.618592Z","shell.execute_reply.started":"2023-07-10T07:49:00.610733Z","shell.execute_reply":"2023-07-10T07:49:00.617582Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# df_submission.to_csv('submission.csv')\ndf_submission.to_csv('submission.csv' , index=False)","metadata":{"execution":{"iopub.status.busy":"2023-07-10T08:14:00.458181Z","iopub.execute_input":"2023-07-10T08:14:00.458980Z","iopub.status.idle":"2023-07-10T08:14:00.494254Z","shell.execute_reply.started":"2023-07-10T08:14:00.458943Z","shell.execute_reply":"2023-07-10T08:14:00.493312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submission.head()","metadata":{"execution":{"iopub.status.busy":"2023-07-10T08:14:04.190033Z","iopub.execute_input":"2023-07-10T08:14:04.190395Z","iopub.status.idle":"2023-07-10T08:14:04.200003Z","shell.execute_reply.started":"2023-07-10T08:14:04.190366Z","shell.execute_reply":"2023-07-10T08:14:04.198848Z"},"trusted":true},"execution_count":null,"outputs":[]}]}