{"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom collections import OrderedDict\nimport cv2\nfrom PIL import Image\nimport keras\n# For one-hot-encoding\nfrom keras.utils import np_utils\n# For creating sequenttial model\nfrom keras.models import Sequential\nfrom keras.layers import Conv2D,MaxPooling2D,Dense,Flatten,Dropout\n# For saving and loading models\nfrom keras.models import load_model\n\n\nimport random","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Simple EDA","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"classes = os.listdir('/kaggle/input/vehicle/train/train')\nBASE = '/kaggle/input/vehicle/train/train/'\n\n# create dict of list of images per class\ndataset = {}\nfor vehicle in classes:\n    dataset[vehicle] = [i for i in os.listdir(BASE + vehicle)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# verify\nprint(dataset.keys())\nprint(len(dataset.keys()))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"- There are total 17 classes of vehicles"},{"metadata":{"trusted":true},"cell_type":"code","source":"# convert dict to pandas df\ndf = pd.DataFrame.from_dict(dataset, orient='index')\ndf = df.transpose()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# train set\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df.info()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"- Dataset is imbalanced, let's visualize"},{"metadata":{"trusted":true},"cell_type":"code","source":"cols = []\ncol_imgs = []\nfor col in df.columns:\n    cols.append(col)\n    col_imgs.append(df[col].count())\n\nplt.figure(figsize=(10,6))\nplt.barh(cols, col_imgs)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"- Maybe we will have to augment data"},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"=\"*70)\nprint(\"Displaying 4 ranndom image per vehicle class\")\nprint(\"=\"*70)\n\n# for every class in `cols`\nfor j in range(17):\n    plt.figure(j)\n    plt.figure(figsize=(20,20))\n    \n    # 4 images per every class\n    for i in range(4):\n        id = \"14{}\".format(i+1)\n        plt.subplot(int(id))\n        random_file = random.choice(os.listdir(BASE + cols[j] + \"/\"))\n        img = cv2.imread(BASE + cols[j] + \"/\" + random_file)\n        plt.title(cols[j])\n        plt.imshow(img)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"- It is kind of funny that `Caterpillar` class has real caterpillars instead of *Caterpillar* vehicles "},{"metadata":{},"cell_type":"markdown","source":"## Prepare Data For Training"},{"metadata":{"trusted":true},"cell_type":"code","source":"data = []\nlabels = []","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\ncols = sorted(cols)\n\n# Creating trainable 224x224 images\n#                    -------\nfor vehicle_class in cols:\n    print(vehicle_class + \" started .....\")\n    for filename in df[vehicle_class]:\n        try:\n            # for empty cols\n            if filename == None:\n                pass\n            else:\n                image = cv2.imread(\"/kaggle/input/vehicle/train/train/{}/\".format(vehicle_class) + filename)\n                image_from_numpy_array = Image.fromarray(image, \"RGB\")\n                resized_image = image_from_numpy_array.resize((224, 224))\n                data.append(np.array(resized_image))\n\n                if vehicle_class == 'Ambulance':\n                    labels.append(0)\n                elif vehicle_class == 'Barge':\n                    labels.append(1)\n                elif vehicle_class == 'Bicycle':\n                    labels.append(2)\n                elif vehicle_class == 'Boat':\n                    labels.append(3)\n                elif vehicle_class == 'Bus':\n                    labels.append(4)\n                elif vehicle_class == 'Car':\n                    labels.append(5)\n                elif vehicle_class == 'Cart':\n                    labels.append(6)\n                elif vehicle_class == 'Caterpillar':\n                    labels.append(7)\n                elif vehicle_class == 'Helicopter':\n                    labels.append(8)\n                elif vehicle_class == 'Limousine':\n                    labels.append(9)\n                elif vehicle_class == 'Motorcycle':\n                    labels.append(10)\n                elif vehicle_class == 'Segway':\n                    labels.append(11)\n                elif vehicle_class == 'Snowmobile':\n                    labels.append(12)\n                elif vehicle_class == 'Tank':\n                    labels.append(13)\n                elif vehicle_class == 'Taxi':\n                    labels.append(14)\n                elif vehicle_class == 'Truck':\n                    labels.append(15)\n                elif vehicle_class == 'Van':\n                    labels.append(16)\n                else:\n                    print(\"Something is wrong.\")\n                \n        except AttributeError:\n            print(\"Attribute error occured for \"+filename)\n'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\nvehicle_images_224x224 = np.array(data)\nlabels_224x224 = np.array(labels)\n\n# save\nnp.save(\"all-vehicle-224x224-images-as-arrays\", vehicle_images_224x224)\nnp.save(\"corresponding-labels-for-all-224x224-images\", labels_224x224)\n'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#data = np.load(\"all-vehicle-224x224-images-as-arrays.npy\")\n#labels = np.load(\"corresponding-labels-for-all-224x224-images.npy\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\nprint(vehicle_images_224x224.shape)\nprint(labels_224x224.shape)\nprint(np.unique(labels_224x224))\n'''","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"------"},{"metadata":{"trusted":true},"cell_type":"code","source":"!rm -r /kaggle/working/data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Move images to `test` and `train` dir\nimport shutil\nimport os\n\nos.mkdir(\"/kaggle/working/data\")\nos.mkdir(\"/kaggle/working/data/test\")\nos.mkdir(\"/kaggle/working/data/train\")\n\nclasses = ['Bicycle', 'Boat', 'Bus', 'Car', 'Motorcycle', 'Truck', 'Van']\n\nfor dir in [\"test\", \"train\"]:\n    for _class in classes:\n        os.mkdir(\"/kaggle/working/data/{}/{}\".format(dir, _class))\n\nfor _class in classes:\n    images = os.listdir(\"/kaggle/input/vehicle/train/train/{}\".format(_class))\n\n    test = images[:300]\n    \n    # downsample to 1.5k images\n    if len(images) < 1500:\n      train = images[300:]\n    else:\n      train = images[300:1500]\n\n    # move images to test-set folder\n    for image in test:\n        shutil.copy(\"/kaggle/input/vehicle/train/train/{}/{}\".format(_class, image), \"/kaggle/working/data/test/{}/{}\".format(_class, image))\n\n    # move images to train-set folder\n    for image in train:\n        shutil.copy(\"/kaggle/input/vehicle/train/train/{}/{}\".format(_class, image), \"/kaggle/working/data/train/{}/{}\".format(_class, image))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\n%matplotlib inline\nimport matplotlib.pyplot as plt\nfrom PIL import Image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import keras\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.applications import ResNet50\nfrom keras.applications.resnet50 import preprocess_input\nfrom keras import Model, layers\nfrom keras.models import load_model, model_from_json","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"input_path = \"/kaggle/working/data/\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_datagen = ImageDataGenerator(\n    shear_range=10,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    preprocessing_function=preprocess_input)\n\ntrain_generator = train_datagen.flow_from_directory(\n    input_path + 'train',\n    batch_size=32,\n    #class_mode='binary',\n    target_size=(224,224))\n\nvalidation_datagen = ImageDataGenerator(\n    preprocessing_function=preprocess_input)\n\nvalidation_generator = validation_datagen.flow_from_directory(\n    input_path + 'test',\n    shuffle=False,\n    #class_mode='binary',\n    target_size=(224,224))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"conv_base = ResNet50(\n    include_top=False,\n    weights='imagenet')\n\nfor layer in conv_base.layers:\n    layer.trainable = False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = conv_base.output\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.Dense(1024, activation='relu')(x)\nx = layers.Dense(512, activation='relu')(x)\npredictions = layers.Dense(7, activation='softmax')(x)\nmodel = Model(conv_base.input, predictions)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"optimizer = keras.optimizers.Adam()\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=optimizer,\n              metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit_generator(generator=train_generator,\n                              steps_per_epoch=347 // 32,  # added in Kaggle\n                              epochs=30,\n                              validation_data=validation_generator,\n                              validation_steps=10  # added in Kaggle\n                             )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plot loss chart\nimport matplotlib.pyplot as plt\n\nhistory_dict = history.history\n\nloss_values = history_dict['loss']\nval_loss_values = history_dict['val_loss']\nepochs = range(1, len(loss_values) + 1)\n\nline1 = plt.plot(epochs, val_loss_values, label='Validation/Test Loss')\nline2 = plt.plot(epochs, loss_values, label='Training Loss')\nplt.setp(line1, linewidth=2.0, marker = '+', markersize=10.0)\nplt.setp(line2, linewidth=2.0, marker = '4', markersize=10.0)\nplt.xlabel('Epochs') \nplt.ylabel('Loss')\nplt.grid(True)\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del model\ndel history","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = conv_base.output\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.Dense(128, activation='relu')(x) \npredictions = layers.Dense(7, activation='softmax')(x)\nmodel = Model(conv_base.input, predictions)\n\noptimizer = keras.optimizers.Adam()\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=optimizer,\n              metrics=['accuracy'])\n\nhistory = model.fit_generator(generator=train_generator,\n                              steps_per_epoch=347 // 32,  # added in Kaggle\n                              epochs=30,\n                              validation_data=validation_generator,\n                              validation_steps=10  # added in Kaggle\n                             )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plot loss chart\nimport matplotlib.pyplot as plt\n\nhistory_dict = history.history\n\nloss_values = history_dict['loss']\nval_loss_values = history_dict['val_loss']\nepochs = range(1, len(loss_values) + 1)\n\nline1 = plt.plot(epochs, val_loss_values, label='Validation/Test Loss')\nline2 = plt.plot(epochs, loss_values, label='Training Loss')\nplt.setp(line1, linewidth=2.0, marker = '+', markersize=10.0)\nplt.setp(line2, linewidth=2.0, marker = '4', markersize=10.0)\nplt.xlabel('Epochs') \nplt.ylabel('Loss')\nplt.grid(True)\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del model\ndel history","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"conv_base = ResNet50(\n    include_top=False,\n    weights='imagenet')\n\nfor layer in conv_base.layers:\n    layer.trainable = False\n\nx = conv_base.output\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.Dense(128, activation='relu')(x) \npredictions = layers.Dense(7, activation='softmax')(x)\nmodel = Model(conv_base.input, predictions)\n\noptimizer = keras.optimizers.Adam(learning_rate=0.000001)\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=optimizer,\n              metrics=['accuracy'])\n\nhistory = model.fit_generator(generator=train_generator,\n                              steps_per_epoch=347 // 32,  # added in Kaggle\n                              epochs=30,\n                              validation_data=validation_generator,\n                              validation_steps=10  # added in Kaggle\n                             )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plot loss chart\nimport matplotlib.pyplot as plt\n\nhistory_dict = history.history\n\nloss_values = history_dict['loss']\nval_loss_values = history_dict['val_loss']\nepochs = range(1, len(loss_values) + 1)\n\nline1 = plt.plot(epochs, val_loss_values, label='Validation/Test Loss')\nline2 = plt.plot(epochs, loss_values, label='Training Loss')\nplt.setp(line1, linewidth=2.0, marker = '+', markersize=10.0)\nplt.setp(line2, linewidth=2.0, marker = '4', markersize=10.0)\nplt.xlabel('Epochs') \nplt.ylabel('Loss')\nplt.grid(True)\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del model\ndel history","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"conv_base = ResNet50(\n    include_top=False,\n    weights='imagenet')\n\nfor layer in conv_base.layers:\n    layer.trainable = False\n\nx = conv_base.output\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.Dense(128, activation='relu')(x) \npredictions = layers.Dense(7, activation='softmax')(x)\nmodel = Model(conv_base.input, predictions)\n\noptimizer = keras.optimizers.Adam(lr=1e-2, beta_1=1e-2/60)\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=optimizer,\n              metrics=['accuracy'])\n\nhistory = model.fit_generator(generator=train_generator,\n                              steps_per_epoch=347 // 32,  # added in Kaggle\n                              epochs=60,\n                              validation_data=validation_generator,\n                              validation_steps=10  # added in Kaggle\n                             )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plot loss chart\nimport matplotlib.pyplot as plt\n\nhistory_dict = history.history\n\nloss_values = history_dict['loss']\nval_loss_values = history_dict['val_loss']\nepochs = range(1, len(loss_values) + 1)\n\nline1 = plt.plot(epochs, val_loss_values, label='Validation/Test Loss')\nline2 = plt.plot(epochs, loss_values, label='Training Loss')\nplt.setp(line1, linewidth=2.0, marker = '+', markersize=10.0)\nplt.setp(line2, linewidth=2.0, marker = '4', markersize=10.0)\nplt.xlabel('Epochs') \nplt.ylabel('Loss')\nplt.grid(True)\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del model\ndel history","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"conv_base = ResNet50(\n    include_top=False,\n    weights='imagenet')\n\nfor layer in conv_base.layers:\n    layer.trainable = False\n\nx = conv_base.output\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.Dense(128, activation='relu')(x) \npredictions = layers.Dense(7, activation='softmax')(x)\nmodel = Model(conv_base.input, predictions)\n\noptimizer = keras.optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, amsgrad=False)\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=optimizer,\n              metrics=['accuracy'])\n\nhistory = model.fit_generator(generator=train_generator,\n                              steps_per_epoch=347 // 32,  # added in Kaggle\n                              epochs=60,\n                              validation_data=validation_generator,\n                              validation_steps=10  # added in Kaggle\n                             )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plot loss chart\nimport matplotlib.pyplot as plt\n\nhistory_dict = history.history\n\nloss_values = history_dict['loss']\nval_loss_values = history_dict['val_loss']\nepochs = range(1, len(loss_values) + 1)\n\nline1 = plt.plot(epochs, val_loss_values, label='Validation/Test Loss')\nline2 = plt.plot(epochs, loss_values, label='Training Loss')\nplt.setp(line1, linewidth=2.0, marker = '+', markersize=10.0)\nplt.setp(line2, linewidth=2.0, marker = '4', markersize=10.0)\nplt.xlabel('Epochs') \nplt.ylabel('Loss')\nplt.grid(True)\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del model\ndel history","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"conv_base = ResNet50(\n    include_top=False,\n    weights='imagenet')\n\nfor layer in conv_base.layers:\n    layer.trainable = False\n\nx = conv_base.output\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.Dense(128, activation='relu')(x) \npredictions = layers.Dense(7, activation='softmax')(x)\nmodel = Model(conv_base.input, predictions)\n\n# Note sgd \noptimizer = keras.optimizers.SGD(lr=1e-2, momentum=0.9, decay=1e-2/60)\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=optimizer,\n              metrics=['accuracy'])\n\nhistory = model.fit_generator(generator=train_generator,\n                              steps_per_epoch=347 // 32,  # added in Kaggle\n                              epochs=60,\n                              validation_data=validation_generator,\n                              validation_steps=10  # added in Kaggle\n                             )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plot loss chart\nimport matplotlib.pyplot as plt\n\nhistory_dict = history.history\n\nloss_values = history_dict['loss']\nval_loss_values = history_dict['val_loss']\nepochs = range(1, len(loss_values) + 1)\n\nline1 = plt.plot(epochs, val_loss_values, label='Validation/Test Loss')\nline2 = plt.plot(epochs, loss_values, label='Training Loss')\nplt.setp(line1, linewidth=2.0, marker = '+', markersize=10.0)\nplt.setp(line2, linewidth=2.0, marker = '4', markersize=10.0)\nplt.xlabel('Epochs') \nplt.ylabel('Loss')\nplt.grid(True)\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del model\ndel history          ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"conv_base = ResNet50(\n    include_top=False,\n    weights='imagenet')\n\nfor layer in conv_base.layers:\n    layer.trainable = False\n\nx = conv_base.output\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.Dense(1024, activation='relu')(x)\nx = layers.Dropout(0.5)(x)\nx = layers.Dense(256, activation='relu')(x)\nx = layers.Dropout(0.5)(x)\npredictions = layers.Dense(7, activation='softmax')(x)\nmodel = Model(conv_base.input, predictions)\n\noptimizer = keras.optimizers.Adam()\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=optimizer,\n              metrics=['accuracy'])\n\nhistory = model.fit_generator(generator=train_generator,\n                              steps_per_epoch=347 // 32,  # added in Kaggle\n                              epochs=60,\n                              validation_data=validation_generator,\n                              validation_steps=10  # added in Kaggle\n                             )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plot loss chart\nimport matplotlib.pyplot as plt\n\nhistory_dict = history.history\n\nloss_values = history_dict['loss']\nval_loss_values = history_dict['val_loss']\nepochs = range(1, len(loss_values) + 1)\n\nline1 = plt.plot(epochs, val_loss_values, label='Validation/Test Loss')\nline2 = plt.plot(epochs, loss_values, label='Training Loss')\nplt.setp(line1, linewidth=2.0, marker = '+', markersize=10.0)\nplt.setp(line2, linewidth=2.0, marker = '4', markersize=10.0)\nplt.xlabel('Epochs') \nplt.ylabel('Loss')\nplt.grid(True)\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"- use dropout\n- [x] try sgd - pyimg\n- try vgg, googlenet, efficient net"},{"metadata":{"trusted":true},"cell_type":"code","source":"del model\ndel history          ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"conv_base = ResNet50(\n    include_top=False,\n    weights='imagenet')\n\nfor layer in conv_base.layers:\n    layer.trainable = False\n\nx = conv_base.output\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.Dense(1024, activation='relu')(x)\nx = layers.Dropout(0.5)(x)\nx = layers.Dense(256, activation='relu')(x)\nx = layers.Dropout(0.5)(x)\npredictions = layers.Dense(7, activation='softmax')(x)\nmodel = Model(conv_base.input, predictions)\n\nfrom keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau\n\nearlystop = EarlyStopping(monitor = 'val_loss', \n                          min_delta = 0, \n                          patience = 5,\n                          verbose = 1,\n                          restore_best_weights = True)\n\nreduce_lr = ReduceLROnPlateau(monitor = 'val_loss',\n                              factor = 0.2,\n                              patience = 3,\n                              verbose = 1,\n                              min_delta = 0.00001)\n\ncheckpoint = ModelCheckpoint(\"/kaggle/working/ckp/resnet.h5\",\n                             monitor=\"val_loss\",\n                             mode=\"min\",\n                             save_best_only = True,\n                             verbose=1)\n\n\ncallbacks = [earlystop, checkpoint, reduce_lr]\n\noptimizer = keras.optimizers.Adam(lr = 0.0001)\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=optimizer,\n              metrics=['accuracy'])\n\nnb_train_samples = 8011\nnb_validation_samples = 2100\nepochs = 60\nbatch_size = 7\n\nhistory = model.fit_generator(generator=train_generator,\n                              steps_per_epoch=nb_train_samples // batch_size,  # added in Kaggle\n                              epochs=epochs,\n                              callbacks = callbacks,\n                              validation_data=validation_generator,\n                              validation_steps=10  # added in Kaggle\n                             )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plot loss chart\nimport matplotlib.pyplot as plt\n\nhistory_dict = history.history\n\nloss_values = history_dict['loss']\nval_loss_values = history_dict['val_loss']\nepochs = range(1, len(loss_values) + 1)\n\nline1 = plt.plot(epochs, val_loss_values, label='Validation/Test Loss')\nline2 = plt.plot(epochs, loss_values, label='Training Loss')\nplt.setp(line1, linewidth=2.0, marker = '+', markersize=10.0)\nplt.setp(line2, linewidth=2.0, marker = '4', markersize=10.0)\nplt.xlabel('Epochs') \nplt.ylabel('Loss')\nplt.grid(True)\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":1}