{"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":"# 1. About CNN","metadata":{}},{"cell_type":"markdown","source":"CNN - Convolutional Neural Networks          \nCNN is a neural network model that is mainly used to process images or image data and includes a preprocessing task called convolution.","metadata":{}},{"cell_type":"markdown","source":"# 2. About cat & dog dataset","metadata":{}},{"cell_type":"markdown","source":"This dataset is very easy to start CNN. So our study group select this to practice CNN modeling.         \n\n* The dataset provide 25000 cats and dogs images to classify.","metadata":{}},{"cell_type":"code","source":"''' importing library''' \n\nimport numpy as np\nimport sys\nimport tensorflow as tf\nimport os\nimport sys\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\nfrom tensorflow.keras.optimizers import RMSprop\n\n%matplotlib inline\nimport matplotlib.image as mpimg\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:26.503707Z","iopub.execute_input":"2022-05-16T07:06:26.504354Z","iopub.status.idle":"2022-05-16T07:06:32.462297Z","shell.execute_reply.started":"2022-05-16T07:06:26.504255Z","shell.execute_reply":"2022-05-16T07:06:32.461461Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''setting seed'''\nseed = 0\nnp.random.seed(seed)\ntf.random.set_seed(3)","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:32.463943Z","iopub.execute_input":"2022-05-16T07:06:32.464175Z","iopub.status.idle":"2022-05-16T07:06:32.471342Z","shell.execute_reply.started":"2022-05-16T07:06:32.464141Z","shell.execute_reply":"2022-05-16T07:06:32.470668Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Data files are zip file. So we have to unzip data files.","metadata":{}},{"cell_type":"code","source":"import zipfile\n\nzip_files = ['test1', 'train']\n\nfor zip_file in zip_files:\n    with zipfile.ZipFile(\"../input/dogs-vs-cats/{}.zip\".format(zip_file),\"r\") as z:\n        z.extractall(\".\")\n        print(\"{} unzipped\".format(zip_file))","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:32.474035Z","iopub.execute_input":"2022-05-16T07:06:32.474564Z","iopub.status.idle":"2022-05-16T07:06:48.069205Z","shell.execute_reply.started":"2022-05-16T07:06:32.474523Z","shell.execute_reply":"2022-05-16T07:06:48.068452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''test1, train Data is in current working folder'''\nprint(os.listdir('../working'))","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:48.072907Z","iopub.execute_input":"2022-05-16T07:06:48.073160Z","iopub.status.idle":"2022-05-16T07:06:48.080402Z","shell.execute_reply.started":"2022-05-16T07:06:48.073128Z","shell.execute_reply":"2022-05-16T07:06:48.079692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMAGE_FOLDER_PATH = \"../working/train\"\nFILE_NAMES = os.listdir(IMAGE_FOLDER_PATH)\nWIDTH = 150\nHEIGHT = 150","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:48.081683Z","iopub.execute_input":"2022-05-16T07:06:48.081923Z","iopub.status.idle":"2022-05-16T07:06:48.635783Z","shell.execute_reply.started":"2022-05-16T07:06:48.081895Z","shell.execute_reply":"2022-05-16T07:06:48.634881Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"FILE_NAMES[0:5]","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:48.637277Z","iopub.execute_input":"2022-05-16T07:06:48.637542Z","iopub.status.idle":"2022-05-16T07:06:48.646517Z","shell.execute_reply.started":"2022-05-16T07:06:48.637507Z","shell.execute_reply":"2022-05-16T07:06:48.645862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Make new dataset for image_path, target data.","metadata":{}},{"cell_type":"code","source":"# empty list\ntargets = list()\nfull_paths = list()\ntrain_cats_dir = list()\ntrain_dogs_dir = list()\n\n# finding each file's target\nfor file_name in FILE_NAMES:\n    target = file_name.split(\".\")[0] # target name\n    full_path = os.path.join(IMAGE_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\ndataset = pd.DataFrame() # make dataframe\ndataset['image_path'] = full_paths # file path\ndataset['target'] = targets # file's target","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:48.648001Z","iopub.execute_input":"2022-05-16T07:06:48.648591Z","iopub.status.idle":"2022-05-16T07:06:48.737649Z","shell.execute_reply.started":"2022-05-16T07:06:48.648554Z","shell.execute_reply":"2022-05-16T07:06:48.736994Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset.head(10)","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:48.738914Z","iopub.execute_input":"2022-05-16T07:06:48.739161Z","iopub.status.idle":"2022-05-16T07:06:48.751286Z","shell.execute_reply.started":"2022-05-16T07:06:48.739129Z","shell.execute_reply":"2022-05-16T07:06:48.750635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"total data counts:\", dataset['target'].count())\ncounts = dataset['target'].value_counts()\nprint(counts)","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:48.752450Z","iopub.execute_input":"2022-05-16T07:06:48.752876Z","iopub.status.idle":"2022-05-16T07:06:48.767152Z","shell.execute_reply.started":"2022-05-16T07:06:48.752835Z","shell.execute_reply":"2022-05-16T07:06:48.766375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## cat data","metadata":{}},{"cell_type":"code","source":"rows = 4\ncols = 4\naxes = []\nfig=plt.figure(figsize=(10,10))\ni = 0\n\nfor a in range(rows*cols):\n    b = mpimg.imread(train_cats_dir[i])\n    sp = fig.add_subplot(rows,cols,a+1);\n    axes.append(sp);\n    sp.axis('off');\n    plt.imshow(b)\n    i+=1\nfig.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:48.769976Z","iopub.execute_input":"2022-05-16T07:06:48.770214Z","iopub.status.idle":"2022-05-16T07:06:50.164908Z","shell.execute_reply.started":"2022-05-16T07:06:48.770181Z","shell.execute_reply":"2022-05-16T07:06:50.164147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## dog data","metadata":{}},{"cell_type":"code","source":"rows = 4\ncols = 4\naxes = []\nfig=plt.figure(figsize=(10,10))\ni = 0\n\nfor a in range(rows*cols):\n    b = mpimg.imread(train_dogs_dir[i])\n    sp = fig.add_subplot(rows,cols,a+1);\n    axes.append(sp);\n    sp.axis('off');\n    plt.imshow(b)\n    i+=1\nfig.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:50.166117Z","iopub.execute_input":"2022-05-16T07:06:50.166354Z","iopub.status.idle":"2022-05-16T07:06:51.264151Z","shell.execute_reply.started":"2022-05-16T07:06:50.166323Z","shell.execute_reply":"2022-05-16T07:06:51.263310Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 3. Data preprocessing","metadata":{}},{"cell_type":"markdown","source":"## Reason for rescaling\n* The brightness of each pixel is between 0 and 255.\n* Keras performs optimally when data's value is between 0 and 1.\n* This process is called data normalization.","metadata":{}},{"cell_type":"markdown","source":"## data split\nTo prevent overfitting, the data should be divided into train data and test data.\n* [about overfitting](https://en.wikipedia.org/wiki/Overfitting)","metadata":{}},{"cell_type":"code","source":"dataset_train, dataset_test = train_test_split(dataset, test_size=0.2, random_state=seed)","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:51.265277Z","iopub.execute_input":"2022-05-16T07:06:51.266018Z","iopub.status.idle":"2022-05-16T07:06:51.277410Z","shell.execute_reply.started":"2022-05-16T07:06:51.265980Z","shell.execute_reply":"2022-05-16T07:06:51.276566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## ImageDataGenerator (모딥 p.307)\nWhen there is little data to train, we have to use **ImageDataGenerator** to increase the number of data.\nIt is recommended to use only scaling for **test data**.\n\n* rescale = 1./255 : change the value between 0 and 1\n* rotation_range = 15 : Random rotation within 15 degrees\n* shear_range = 0.1 : shear range 10%\n* zoom_range = 0.2 : zoom range 20%\n* horizontal_flip = True : Randomly flip horizontally.\n* width_shift_range = 0.1 : Randomly move the original image horizontally within 10% of the width\n* height_shift_range=0.1 : Randomly move the original image vertically within 10% of the width\n\n[about ImageDataGenerator_kor.ver](https://keras.io/ko/preprocessing/image/)\n\n[about ImageDataGenerator_Image change process_kor.ver](https://tykimos.github.io/2017/06/10/CNN_Data_Augmentation/)","metadata":{}},{"cell_type":"markdown","source":"## flow_from_dataframe\nSave the image data data to the pandas data frame and send it to the ImageDataGenerator.\n\n* dataframe: Dataframe must consist of file path and target\n* x_col: column in 'dataframe' that contains the filenames\n* y_col: column in 'dataframe' that has the target data.\n* target_size: image size\n* class_mode: \"binary\" -> binary classification, \"categorical\" -> categorical classification (the data should be one-hot encoded label)\n* batch_size: size of data batch","metadata":{}},{"cell_type":"code","source":"train_datagen=ImageDataGenerator(\nrotation_range=15,\nrescale=1./255,\nshear_range=0.1,\nzoom_range=0.2,\nhorizontal_flip=True,\nwidth_shift_range=0.1,\nheight_shift_range=0.1)\n\ntrain_datagenerator=train_datagen.flow_from_dataframe(dataframe=dataset_train,\n                                                     x_col=\"image_path\",\n                                                     y_col=\"target\",\n                                                     target_size=(WIDTH, HEIGHT),\n                                                     class_mode=\"binary\",\n                                                     batch_size=150)","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:51.278601Z","iopub.execute_input":"2022-05-16T07:06:51.279162Z","iopub.status.idle":"2022-05-16T07:06:51.468763Z","shell.execute_reply.started":"2022-05-16T07:06:51.279127Z","shell.execute_reply":"2022-05-16T07:06:51.468036Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_datagen = ImageDataGenerator(rescale=1./255)\ntest_datagenerator=test_datagen.flow_from_dataframe(dataframe=dataset_test,\n                                                   x_col=\"image_path\",\n                                                   y_col=\"target\",\n                                                   target_size=(WIDTH, HEIGHT),\n                                                   class_mode=\"binary\",\n                                                   batch_size=150)","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:51.470022Z","iopub.execute_input":"2022-05-16T07:06:51.470411Z","iopub.status.idle":"2022-05-16T07:06:51.528465Z","shell.execute_reply.started":"2022-05-16T07:06:51.470374Z","shell.execute_reply":"2022-05-16T07:06:51.527563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 4. CNN model","metadata":{}},{"cell_type":"markdown","source":"## model","metadata":{}},{"cell_type":"code","source":"def create_model():\n\n  model = tf.keras.models.Sequential([ \n    tf.keras.layers.Conv2D(16,(3,3), activation = 'relu', input_shape=(150,150,3)),\n    tf.keras.layers.MaxPooling2D(2,2),\n\n    tf.keras.layers.Conv2D(32,(3,3), activation = 'relu'),\n    tf.keras.layers.MaxPooling2D(2,2),\n\n    tf.keras.layers.Conv2D(64,(3,3), activation = 'relu'),\n    tf.keras.layers.MaxPooling2D(2,2),\n\n    tf.keras.layers.Flatten(),\n    tf.keras.layers.Dense(512, activation = 'relu'),\n    tf.keras.layers.Dense(1, activation='sigmoid')\n  ])\n\n  \n  model.compile(optimizer=RMSprop(lr=0.001),\n                loss='binary_crossentropy',\n                metrics=['accuracy']) \n    \n  return model","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:51.529908Z","iopub.execute_input":"2022-05-16T07:06:51.530152Z","iopub.status.idle":"2022-05-16T07:06:51.538572Z","shell.execute_reply.started":"2022-05-16T07:06:51.530119Z","shell.execute_reply":"2022-05-16T07:06:51.537602Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = create_model()\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:51.539999Z","iopub.execute_input":"2022-05-16T07:06:51.540251Z","iopub.status.idle":"2022-05-16T07:06:54.630392Z","shell.execute_reply.started":"2022-05-16T07:06:51.540216Z","shell.execute_reply":"2022-05-16T07:06:54.629703Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(loss=\"binary_crossentropy\", optimizer='adam', metrics=['accuracy'])\nprint(\"[INFO]: model compiled...\")","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:54.637331Z","iopub.execute_input":"2022-05-16T07:06:54.637858Z","iopub.status.idle":"2022-05-16T07:06:54.688103Z","shell.execute_reply.started":"2022-05-16T07:06:54.637818Z","shell.execute_reply":"2022-05-16T07:06:54.687461Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class mycallback(tf.keras.callbacks.Callback):\n    def on_epoch_end(self,epoch,logs={}):\n        if(logs.get('val_accuracy')>=0.90):\n            self.model.stop_training = True\n            \ncallback = mycallback()","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:54.691417Z","iopub.execute_input":"2022-05-16T07:06:54.692974Z","iopub.status.idle":"2022-05-16T07:06:54.701299Z","shell.execute_reply.started":"2022-05-16T07:06:54.692936Z","shell.execute_reply":"2022-05-16T07:06:54.698760Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Training","metadata":{}},{"cell_type":"code","source":"modelHistory=model.fit(train_datagenerator,\n                       epochs=50,\n                       validation_data=test_datagenerator,\n                       validation_steps=dataset_test.shape[0]/150,\n                       steps_per_epoch=dataset_train.shape[0]/150,\n                       callbacks=[callback])","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:06:54.702381Z","iopub.execute_input":"2022-05-16T07:06:54.703600Z","iopub.status.idle":"2022-05-16T07:09:49.816209Z","shell.execute_reply.started":"2022-05-16T07:06:54.703563Z","shell.execute_reply":"2022-05-16T07:09:49.813318Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Accuracy","metadata":{}},{"cell_type":"code","source":"acc = modelHistory.history['accuracy']\nval_acc = modelHistory.history['val_accuracy']\nloss = modelHistory.history['loss']\nval_loss = modelHistory.history['val_loss']\n\nepochs = range(len(acc))\n\nplt.plot(epochs, acc, 'bo', label='Training accuracy')\nplt.plot(epochs, val_acc, 'b', label='Validation accuracy')\nplt.title('Training and validation accuracy')\nplt.legend()\n\nplt.figure()\n\nplt.plot(epochs, loss, 'go', label='Training Loss')\nplt.plot(epochs, val_loss, 'g', label='Validation Loss')\nplt.title('Training and validation loss')\nplt.legend()\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-16T07:09:49.818559Z","iopub.status.idle":"2022-05-16T07:09:49.819247Z","shell.execute_reply.started":"2022-05-16T07:09:49.819024Z","shell.execute_reply":"2022-05-16T07:09:49.819047Z"},"trusted":true},"execution_count":null,"outputs":[]}]}