{"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":"!ls /kaggle/input/dogs-vs-cats","metadata":{"execution":{"iopub.status.busy":"2021-09-14T08:49:50.513925Z","iopub.execute_input":"2021-09-14T08:49:50.514362Z","iopub.status.idle":"2021-09-14T08:49:51.168872Z","shell.execute_reply.started":"2021-09-14T08:49:50.514264Z","shell.execute_reply":"2021-09-14T08:49:51.167918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# CREATE FOLDER FOR LOAD DATA","metadata":{}},{"cell_type":"markdown","source":"### Uncompressing data","metadata":{}},{"cell_type":"code","source":"from zipfile import ZipFile as zf\ntrain_zip = zf('/kaggle/input/dogs-vs-cats/train.zip', 'r')\ntrain_zip.extractall()\ntrain_zip.close()\ntest_zip = zf('/kaggle/input/dogs-vs-cats/test1.zip', 'r')\ntest_zip.extractall()\ntest_zip.close()","metadata":{"execution":{"iopub.status.busy":"2021-09-14T08:49:53.082403Z","iopub.execute_input":"2021-09-14T08:49:53.082777Z","iopub.status.idle":"2021-09-14T08:50:12.740172Z","shell.execute_reply.started":"2021-09-14T08:49:53.082745Z","shell.execute_reply":"2021-09-14T08:50:12.739300Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Path to the directory where the original dataset was uncompressed","metadata":{}},{"cell_type":"code","source":"import os, shutil\nimport random\n\n# PATH_DATA = '/kaggle/input/dogs-vs-cats/'\nBASE_DIR = './my_arange_data/'\nos.makedirs(BASE_DIR, exist_ok=True)\n\n# Make directories of train, validation, test\ntrain_dir = os.path.join(BASE_DIR, 'train')\nos.makedirs(train_dir, exist_ok=True)\nvalidation_dir = os.path.join(BASE_DIR, 'validation')\nos.makedirs(validation_dir, exist_ok=True)\n\n# With cats pictures\ntrain_cats_dir = os.path.join(train_dir, 'cats')\nos.makedirs(train_cats_dir, exist_ok=True)\nvalid_cats_dir = os.path.join(validation_dir, 'cats')\nos.makedirs(valid_cats_dir, exist_ok=True)\n\n\n# With dogs pictures\ntrain_dogs_dir = os.path.join(train_dir, 'dogs')\nos.makedirs(train_dogs_dir, exist_ok=True)\nvalid_dogs_dir = os.path.join(validation_dir, 'dogs')\nos.makedirs(valid_dogs_dir, exist_ok=True)\n\n# copy train to base_dir train\nfor filename in os.listdir('./train'):\n    if filename.split('.')[0] == 'dog':\n        shutil.copy(os.path.join('./train/',filename), os.path.join(train_dogs_dir, filename))\n    else:\n        shutil.copy(os.path.join('./train/',filename), os.path.join(train_cats_dir, filename))\n\n        # move some of train to validation\ntrain_dogs = os.listdir(train_dogs_dir)\ntrain_cats = os.listdir(train_cats_dir)\n\nrandom.shuffle(train_dogs)\nrandom.shuffle(train_cats)\n\n## train: 10000 image, valid: 2500 for each class\nfor i in range(2500):\n    shutil.move(os.path.join(train_dogs_dir, train_dogs[i]), os.path.join(valid_dogs_dir, train_dogs[i]))\n    shutil.move(os.path.join(train_cats_dir, train_cats[i]), os.path.join(valid_cats_dir, train_cats[i]))        ","metadata":{"execution":{"iopub.status.busy":"2021-09-14T06:58:17.148468Z","iopub.execute_input":"2021-09-14T06:58:17.148811Z","iopub.status.idle":"2021-09-14T06:58:20.196094Z","shell.execute_reply.started":"2021-09-14T06:58:17.148775Z","shell.execute_reply":"2021-09-14T06:58:20.191192Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(len(os.listdir(train_dogs_dir)), len(os.listdir(valid_dogs_dir)))","metadata":{"execution":{"iopub.status.busy":"2021-09-14T04:13:48.565998Z","iopub.execute_input":"2021-09-14T04:13:48.566342Z","iopub.status.idle":"2021-09-14T04:13:48.579442Z","shell.execute_reply.started":"2021-09-14T04:13:48.566307Z","shell.execute_reply":"2021-09-14T04:13:48.578649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Preprocessing","metadata":{}},{"cell_type":"markdown","source":"### Display some pictures","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\n\nfnames = [os.path.join('./train/', fname) for fname in os.listdir('./train')]\nfor i, fname in enumerate(fnames):\n    if i <= 4:\n        plt.figure(i)\n        plt.imshow(mpimg.imread(fname))","metadata":{"execution":{"iopub.status.busy":"2021-09-14T04:13:53.801037Z","iopub.execute_input":"2021-09-14T04:13:53.801387Z","iopub.status.idle":"2021-09-14T04:13:54.737667Z","shell.execute_reply.started":"2021-09-14T04:13:53.801357Z","shell.execute_reply":"2021-09-14T04:13:54.736692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Load data\n\nUsing class ImageDataGenerator to load images","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nload_datagen = ImageDataGenerator(rescale=1./255)\n\ntrain_generator = load_datagen.flow_from_directory(\\\n                                                   train_dir,\n                                                   target_size=(150, 150),\n                                                   batch_size=32,\n                                                   class_mode='binary')\nvalid_generator = load_datagen.flow_from_directory(\\\n                                                   validation_dir,\n                                                   target_size=(150, 150),\n                                                   batch_size=32,\n                                                   class_mode='binary')","metadata":{"execution":{"iopub.status.busy":"2021-09-14T04:13:59.893664Z","iopub.execute_input":"2021-09-14T04:13:59.893995Z","iopub.status.idle":"2021-09-14T04:14:05.528628Z","shell.execute_reply.started":"2021-09-14T04:13:59.893964Z","shell.execute_reply":"2021-09-14T04:14:05.527611Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Try with simple model","metadata":{}},{"cell_type":"markdown","source":"Check gpu device","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\ndevice_name = tf.test.gpu_device_name()\nif \"GPU\" not in device_name:\n    print(\"GPU device not found\")\nprint('Found GPU at: {}'.format(device_name))","metadata":{"execution":{"iopub.status.busy":"2021-09-14T04:14:07.589391Z","iopub.execute_input":"2021-09-14T04:14:07.589726Z","iopub.status.idle":"2021-09-14T04:14:09.558015Z","shell.execute_reply.started":"2021-09-14T04:14:07.589696Z","shell.execute_reply":"2021-09-14T04:14:09.55701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras import layers\nfrom tensorflow.keras import models\nfrom tensorflow.keras import optimizers\n\nmodel = models.Sequential()\nmodel.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3)))\nmodel.add(layers.MaxPooling2D(2, 2))\nmodel.add(layers.Conv2D(64, (3, 3), activation='relu'))\nmodel.add(layers.Conv2D(128, (3, 3), activation='relu'))\nmodel.add(layers.MaxPooling2D(2, 2))\nmodel.add(layers.Conv2D(64, (3, 3), activation='relu'))\nmodel.add(layers.Flatten())\nmodel.add(layers.Dense(512, activation='relu'))\nmodel.add(layers.Dense(1, activation='sigmoid'))\n\nmodel.compile(\n    loss='binary_crossentropy',\n    optimizer=optimizers.RMSprop(lr=1e-4),\n    metrics=['acc'])","metadata":{"execution":{"iopub.status.busy":"2021-09-14T04:14:09.560019Z","iopub.execute_input":"2021-09-14T04:14:09.560399Z","iopub.status.idle":"2021-09-14T04:14:09.960535Z","shell.execute_reply.started":"2021-09-14T04:14:09.560367Z","shell.execute_reply":"2021-09-14T04:14:09.95964Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2021-09-14T04:14:10.940713Z","iopub.execute_input":"2021-09-14T04:14:10.94104Z","iopub.status.idle":"2021-09-14T04:14:10.951222Z","shell.execute_reply.started":"2021-09-14T04:14:10.941008Z","shell.execute_reply":"2021-09-14T04:14:10.950257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nhistory = model.fit_generator(\n    train_generator,\n    steps_per_epoch=100,\n    epochs=50, \n    validation_data=valid_generator, \n    validation_steps=50)","metadata":{"execution":{"iopub.status.busy":"2021-09-13T09:55:44.76097Z","iopub.execute_input":"2021-09-13T09:55:44.7613Z","iopub.status.idle":"2021-09-13T10:07:34.438281Z","shell.execute_reply.started":"2021-09-13T09:55:44.761271Z","shell.execute_reply":"2021-09-13T10:07:34.437464Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\ndef visualize_result(history):\n    fig, axes = plt.subplots(2, 1, figsize=(15, 12))\n    epochs = np.arange(1, len(history.history['acc']) + 1, 1)\n    # accuracy\n    axes[0].plot(epochs, history.history['acc'], '-o', color='b', label='train_accuracy')\n    axes[0].plot(epochs, history.history['val_acc'], '-o', color='r', label='val_accuracy')\n    axes[0].legend()\n    #loss\n    axes[1].plot(epochs, history.history['loss'], '-o', color='b', label='train_loss')\n    axes[1].plot(epochs, history.history['val_loss'], '-o', color='r', label='val_loss')\n    axes[1].legend()\n\n    axes[0].set_xticks(epochs)\n    axes[1].set_xticks(epochs)\nvisualize_result(history)","metadata":{"execution":{"iopub.status.busy":"2021-09-14T04:14:22.060073Z","iopub.execute_input":"2021-09-14T04:14:22.060436Z","iopub.status.idle":"2021-09-14T04:14:22.342981Z","shell.execute_reply.started":"2021-09-14T04:14:22.060394Z","shell.execute_reply":"2021-09-14T04:14:22.341476Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Augmentation data","metadata":{}},{"cell_type":"markdown","source":"You can using augmentation method to make more data from original data.","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\ntrain_datagen = ImageDataGenerator(\n    rescale=1./255,\n    horizontal_flip=True,\n    rotation_range=30,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.2,\n    zoom_range=0.2,\n    fill_mode='nearest')\n\ntest_datagen = ImageDataGenerator(\n    rescale=1./255)\n\ntrain_generator = train_datagen.flow_from_directory(\n    train_dir,\n    batch_size=128,\n    target_size=(150, 150),\n    class_mode='binary')\nvalid_generator = test_datagen.flow_from_directory(\n    validation_dir,\n    target_size=(150, 150),\n    batch_size=128,\n    class_mode='binary')","metadata":{"execution":{"iopub.status.busy":"2021-09-14T04:14:31.955587Z","iopub.execute_input":"2021-09-14T04:14:31.955898Z","iopub.status.idle":"2021-09-14T04:14:31.963518Z","shell.execute_reply.started":"2021-09-14T04:14:31.95587Z","shell.execute_reply":"2021-09-14T04:14:31.962627Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- Let see images generator after using augmentation for a picture","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing import image\nimg = image.load_img(fnames[1], target_size=(150, 150))\nplt.imshow(img)","metadata":{"execution":{"iopub.status.busy":"2021-09-14T04:14:36.030848Z","iopub.execute_input":"2021-09-14T04:14:36.031175Z","iopub.status.idle":"2021-09-14T04:14:36.198912Z","shell.execute_reply.started":"2021-09-14T04:14:36.031144Z","shell.execute_reply":"2021-09-14T04:14:36.19797Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = image.img_to_array(img)\nx = x.reshape((1,x.shape[0], x.shape[1], x.shape[2]))\ngenerator_img = train_datagen.flow(x, batch_size=1)\n\nfor i, batch in enumerate(generator_img):\n    plt.figure(i)\n    plt.imshow(image.array_to_img(batch[0]))\n    if i == 10:\n        break\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-09-14T04:14:39.013813Z","iopub.execute_input":"2021-09-14T04:14:39.014133Z","iopub.status.idle":"2021-09-14T04:14:40.561389Z","shell.execute_reply.started":"2021-09-14T04:14:39.014102Z","shell.execute_reply":"2021-09-14T04:14:40.560456Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# USING PRETRAINED CONVNET","metadata":{}},{"cell_type":"markdown","source":"Using Xception model from keras api, you can read more in this: https://keras.io/api/applications/xception/","metadata":{}},{"cell_type":"code","source":"from keras.applications import Xception\n\npretrained_model = Xception(\n    weights='imagenet', \n    include_top=False, \n    input_shape=(150, 150, 3))\n\npretrained_model.summary()","metadata":{"execution":{"iopub.status.busy":"2021-09-14T06:57:30.002895Z","iopub.execute_input":"2021-09-14T06:57:30.003223Z","iopub.status.idle":"2021-09-14T06:57:38.275406Z","shell.execute_reply.started":"2021-09-14T06:57:30.003192Z","shell.execute_reply":"2021-09-14T06:57:38.274333Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"notice the final feature map has shape (None, 5, 5, 2048)","metadata":{}},{"cell_type":"markdown","source":"## 1. Feature extraction before training","metadata":{}},{"cell_type":"markdown","source":"Using pretrained model to extract the features of data, then using these to predict.","metadata":{}},{"cell_type":"code","source":"def extract_features(dir):\n    n_samples = len(os.listdir(dir))\n    features = np.zeros(shape=(n_samples, 5, 5, 2048))\n    labels = np.zeros(shape=(n_samples))\n    datagen = ImageDataGenerator(rescale=1./255)\n    \n    batch_size = 1\n    # using ImageDataGenerator format\n    gen_data = datagen.flow_from_directory(\n        dir, \n        target_size=(150, 150), \n        batch_size=batch_size, \n        class_mode='binary')\n    i = 0\n    for inputs_batch, labels_batch in gen_data:\n        features_batch = pretrained_model.predict(inputs_batch)\n        features[i*batch_size: (i+1)*batch_size] = features_batch\n        labels[i*batch_size: (i+1)*batch_size] = labels_batch\n        if i*batch_size > n_samples:\n            break\n        i += 1\n    return features, labels\n\ntrain_features, train_labels = extract_features(train_dir)\nvalid_features, valid_labels = extract_features(validation_dir)","metadata":{"execution":{"iopub.status.busy":"2021-09-14T04:36:41.569969Z","iopub.execute_input":"2021-09-14T04:36:41.57033Z","iopub.status.idle":"2021-09-14T04:36:43.130631Z","shell.execute_reply.started":"2021-09-14T04:36:41.570297Z","shell.execute_reply":"2021-09-14T04:36:43.129735Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_features = train_features.reshape(train_features.shape[0], 5*5*2048)\nvalid_features = valid_features.reshape(valid_features.shape[0], 5*5*2048)","metadata":{"execution":{"iopub.status.busy":"2021-09-14T04:37:53.659594Z","iopub.execute_input":"2021-09-14T04:37:53.659922Z","iopub.status.idle":"2021-09-14T04:37:53.665049Z","shell.execute_reply.started":"2021-09-14T04:37:53.659892Z","shell.execute_reply":"2021-09-14T04:37:53.664161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras import layers\nfrom tensorflow.keras import models\nfrom tensorflow.keras import optimizers\n\nmodel = models.Sequential()\nmodel.add(layers.Dense(256, activation='relu', input_dim=(5*5*2048)))\nmodel.add(layers.Dense(1, activation='sigmoid'))\n\nmodel.compile(\n    optimizer=optimizers.RMSprop(lr=2e-5), \n    loss='binary_crossentropy', \n    metrics=['acc'])","metadata":{"execution":{"iopub.status.busy":"2021-09-14T04:42:34.752595Z","iopub.execute_input":"2021-09-14T04:42:34.75292Z","iopub.status.idle":"2021-09-14T04:42:34.787135Z","shell.execute_reply.started":"2021-09-14T04:42:34.75289Z","shell.execute_reply":"2021-09-14T04:42:34.786344Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.fit(\n    train_features, \n    train_labels, \n    epochs=30, \n    batch_size=20, \n    validation_data=(valid_features, valid_labels))","metadata":{"execution":{"iopub.status.busy":"2021-09-14T04:43:49.866426Z","iopub.execute_input":"2021-09-14T04:43:49.866762Z","iopub.status.idle":"2021-09-14T04:43:52.171431Z","shell.execute_reply.started":"2021-09-14T04:43:49.866731Z","shell.execute_reply":"2021-09-14T04:43:52.170654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 1. training with pretrained model","metadata":{}},{"cell_type":"markdown","source":"Add some layers to pretrained model","metadata":{}},{"cell_type":"code","source":"model = models.Sequential()\nmodel.add(pretrained_model)\nmodel.add(layers.Flatten())\nmodel.add(layers.Dense(256, activation='relu'))\nmodel.add(layers.Dense(1, activation='sigmoid'))\n\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-09-14T04:54:24.848377Z","iopub.execute_input":"2021-09-14T04:54:24.848695Z","iopub.status.idle":"2021-09-14T04:54:25.179654Z","shell.execute_reply.started":"2021-09-14T04:54:24.848666Z","shell.execute_reply":"2021-09-14T04:54:25.178632Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(\n    optimizer=optimizers.RMSprop(lr=2e-5), \n    loss='binary_crossentropy', \n    metrics=['acc'])\n\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nload_datagen = ImageDataGenerator(rescale=1./255)\n\ntrain_generator = load_datagen.flow_from_directory(\\\n                                                   train_dir,\n                                                   target_size=(150, 150),\n                                                   batch_size=32,\n                                                   class_mode='binary')\nvalid_generator = load_datagen.flow_from_directory(\\\n                                                   validation_dir,\n                                                   target_size=(150, 150),\n                                                   batch_size=32,\n                                                   class_mode='binary')\nmodel.fit(\n    train_generator, \n    epochs=50, \n    steps_per_epoch=100, \n    validation_data=valid_generator, \n    validation_steps=50)","metadata":{"execution":{"iopub.status.busy":"2021-09-14T04:58:20.714306Z","iopub.execute_input":"2021-09-14T04:58:20.714634Z","iopub.status.idle":"2021-09-14T05:19:00.721678Z","shell.execute_reply.started":"2021-09-14T04:58:20.714606Z","shell.execute_reply":"2021-09-14T05:19:00.720887Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 2. Fine-tuning","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import Xception\nfrom tensorflow.keras import layers\nfrom tensorflow.keras import models\nfrom tensorflow.keras import optimizers","metadata":{"execution":{"iopub.status.busy":"2021-09-14T06:59:26.958308Z","iopub.execute_input":"2021-09-14T06:59:26.958656Z","iopub.status.idle":"2021-09-14T06:59:26.963373Z","shell.execute_reply.started":"2021-09-14T06:59:26.958625Z","shell.execute_reply":"2021-09-14T06:59:26.962153Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pretrained_model = Xception(\n    weights='imagenet', \n    include_top=False, input_shape=(150, 150, 3))\npretrained_model.summary()","metadata":{"execution":{"iopub.status.busy":"2021-09-14T07:00:48.799446Z","iopub.execute_input":"2021-09-14T07:00:48.799788Z","iopub.status.idle":"2021-09-14T07:00:49.901851Z","shell.execute_reply.started":"2021-09-14T07:00:48.799758Z","shell.execute_reply":"2021-09-14T07:00:49.899046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Using layers in block14 ","metadata":{}},{"cell_type":"code","source":"pretrained_model.trainable = True\nset_trainable = False\n\nfor layer in pretrained_model.layers:\n    if layer == 'block14_sepconv1':\n        set_trainable = True\n        \n    if set_trainable:\n        layer.trainable = True\n    else:\n        layer.trainable = False","metadata":{"execution":{"iopub.status.busy":"2021-09-14T07:03:44.520784Z","iopub.execute_input":"2021-09-14T07:03:44.521126Z","iopub.status.idle":"2021-09-14T07:03:44.533141Z","shell.execute_reply.started":"2021-09-14T07:03:44.521097Z","shell.execute_reply":"2021-09-14T07:03:44.532326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = models.Sequential()\nmodel.add(pretrained_model)\nmodel.add(layers.Flatten())\nmodel.add(layers.Dense(256, activation='relu'))\nmodel.add(layers.Dense(1, activation='sigmoid'))\nmodel.compile(\n    optimizer=optimizers.RMSprop(lr=2e-5), \n    loss='binary_crossentropy', \n    metrics=['acc'])","metadata":{"execution":{"iopub.status.busy":"2021-09-14T07:04:55.016682Z","iopub.execute_input":"2021-09-14T07:04:55.017016Z","iopub.status.idle":"2021-09-14T07:04:55.342482Z","shell.execute_reply.started":"2021-09-14T07:04:55.016988Z","shell.execute_reply":"2021-09-14T07:04:55.341647Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2021-09-14T07:17:27.111169Z","iopub.execute_input":"2021-09-14T07:17:27.111565Z","iopub.status.idle":"2021-09-14T07:17:27.132712Z","shell.execute_reply.started":"2021-09-14T07:17:27.111513Z","shell.execute_reply":"2021-09-14T07:17:27.131869Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nload_datagen = ImageDataGenerator(rescale=1./255)\n\ntrain_generator = load_datagen.flow_from_directory(\\\n                                                   train_dir,\n                                                   target_size=(150, 150),\n                                                   batch_size=32,\n                                                   class_mode='binary')\nvalid_generator = load_datagen.flow_from_directory(\\\n                                                   validation_dir,\n                                                   target_size=(150, 150),\n                                                   batch_size=32,\n                                                   class_mode='binary')\nmodel.fit(\n    train_generator, \n    epochs=50, \n    steps_per_epoch=100, \n    validation_data=valid_generator, \n    validation_steps=50)","metadata":{"execution":{"iopub.status.busy":"2021-09-14T07:05:00.950974Z","iopub.execute_input":"2021-09-14T07:05:00.951293Z","iopub.status.idle":"2021-09-14T07:17:27.109605Z","shell.execute_reply.started":"2021-09-14T07:05:00.951263Z","shell.execute_reply":"2021-09-14T07:17:27.10871Z"},"trusted":true},"execution_count":null,"outputs":[]}]}