{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\n\n#for dirname, _, filenames in os.walk('/kaggle/input'):\n    #for filename in filenames:\n        #print(os.path.join(dirname, filename))\n\n# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import json\n\nwith open(\"../input/til2020/train.json\",'r') as file:\n    train_data = json.load(file)\n    \nwith open(\"../input/til2020/val.json\",'r') as file:\n    test_data = json.load(file)\n    \nprint(\"%.1000s\" % train_data)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_annotations = train_data['annotations']\ntrain_images = train_data['images']\ncategories = train_data['categories']\n\nprint(train_annotations[0])\nprint(train_images[0])\nprint(categories)\n\nprint(len(train_annotations))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_annotations = test_data['annotations']\ntest_images = test_data['images']\n\nprint(test_annotations[0])\nprint(test_images[0])\n\nprint(len(test_annotations))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Build a dictionary for categories"},{"metadata":{"trusted":true},"cell_type":"code","source":"category_mapping = {}\n\nfor category_item in categories:\n    category_mapping[category_item['id']] = category_item['name']\n\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Let's add image path in annotations"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_id_to_path_mapping = {}\n\nfor image_item in train_images:\n    train_id_to_path_mapping[image_item['id']] = image_item['file_name']\n    \ntest_id_to_path_mapping = {}\n\nfor image_item in test_images:\n    test_id_to_path_mapping[image_item['id']] = image_item['file_name']\n    \nfor annotation in train_annotations:\n    annotation['image_path'] = train_id_to_path_mapping[annotation['image_id']]\n    annotation['cat'] = category_mapping[annotation['category_id']]\n    annotation['bbox'] = list(map(int,annotation['bbox']))\n    \nfor annotation in test_annotations:\n    annotation['image_path'] = test_id_to_path_mapping[annotation['image_id']]\n    annotation['cat'] = category_mapping[annotation['category_id']]\n    annotation['bbox'] = list(map(int,annotation['bbox']))\n    \nprint(\"%.1000s\" % train_annotations)\nprint(\"%.1000s\" % test_annotations)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Crop Image"},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"from matplotlib import pyplot as plt\nimport cv2\n\nbase_path = r'../input/til2020/train/train/'\n\nannotation = train_annotations[0]\ncoordinates = annotation['bbox']\n\nim = cv2.imread(base_path+annotation['image_path'])\n#Show the image with matplotlib\nprint(im.shape)\nplt.imshow(im)\nplt.show()\n\nfrom PIL import Image, ImageFont, ImageDraw\n\nimg = Image.open(base_path+annotation['image_path'])\n# create rectangle image\nimg1 = ImageDraw.Draw(img)\nimg1.rectangle(((coordinates[0], coordinates[1]),(coordinates[0]+coordinates[2], coordinates[1]+coordinates[3])),  outline =\"red\",width=10)\nimg1.text((523,25), \"dresses\", fill=(255,255,255,128))\ndisplay(img)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"image = im[coordinates[1]:coordinates[1]+coordinates[3],coordinates[0]:coordinates[0]+coordinates[2]]\n\nplt.imshow(image)\nplt.show()\nprint(image.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"resized_image = cv2.resize(image, (128, 128),  \n               interpolation = cv2.INTER_NEAREST) \n\nplt.imshow(resized_image)\nplt.show()\nprint(resized_image.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Visualising 10 Images\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"max_images = 10\n\nfor annotation in train_annotations[:max_images]:\n    coordinates = annotation['bbox']\n    \n    x = coordinates[0]\n    y = coordinates[1]\n    width = coordinates[2]\n    height = coordinates[3]\n\n    im = cv2.imread(base_path+annotation['image_path'])\n    image = im[y:y+height,x:x+width]\n\n    resized_image = cv2.resize(image, (128, 128), interpolation = cv2.INTER_NEAREST) \n    #resized_image = cv2.resize(image, (224, 224), interpolation = cv2.INTER_NEAREST) \n    #resized_image = cv2.resize(image, (64, 64), interpolation = cv2.INTER_NEAREST) \n    plt.imshow(resized_image)\n    plt.title(annotation['cat'])\n    plt.show()\n    #print(annotation['cat'])\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Training a Simple CNN"},{"metadata":{"trusted":true},"cell_type":"code","source":"from matplotlib import pyplot as plt\nfrom PIL import Image, ImageFont, ImageDraw\n    \nimport numpy as np\nimport cv2\nimport keras\n\n#, original_shape, new_shape=(224,224)\n\ndef get_cropped_image(img, bbox):\n    start_x, start_y, width, height = bbox\n    cropped_img = img[start_y:start_y+height, start_x:start_x+width]\n    return cropped_img\n      \ndef get_reshaped_image(img, new_shape=(224,224)):\n    resized_image = cv2.resize(img, new_shape, interpolation = cv2.INTER_NEAREST) \n    return resized_image\n\ndef rescale_bbox(bbox, current_img_shape, new_img_shape=(224,224)):\n    x_ratio = new_img_shape[0] / current_img_shape[0]\n    y_ratio = new_img_shape[1] / current_img_shape[1]\n    \n    new_x = bbox[0] * x_ratio\n    new_y = bbox[1] * y_ratio\n    new_width = bbox[2] * x_ratio\n    new_height = bbox[3] * y_ratio\n    \n    return new_x, new_y, new_width, new_height\n   ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Temporary Test"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Temporary Test\nmax_images = 1\ntitle_distance = 10\n\nfor annotation in train_annotations[:max_images]:\n    bbox = annotation['bbox']\n\n    img = Image.open(base_path+annotation['image_path'])\n    img2 = np.asarray(image)\n    \n    x,y,w,h = rescale_bbox(bbox, (img2.shape[0],img2.shape[1]))\n    cropped_image = get_cropped_image(img2, bbox)\n    reshaped_image = get_reshaped_image(cropped_image)\n\n    img = Image.fromarray(reshaped_image)\n    img3 = ImageDraw.Draw(img)\n    img3.rectangle(((x, y),(x+w, y+h)),  outline =\"green\",width=1)\n    #img3.text((x-title_distance,y-title_distance), \"dresses\", fill=(255,255,255,128))\n    display(img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n%matplotlib inline\nsns.set_style()\n\n# to divide our data into train and validation set\nfrom sklearn.model_selection import train_test_split\n#to encode our labels\nfrom tensorflow.keras.utils import to_categorical\n#to build our model \nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense,Conv2D,MaxPool2D,Flatten,Dropout\n# Our optimizer options\nfrom keras.optimizers import RMSprop\nfrom keras.optimizers import Adam\n#Callback options\nfrom tensorflow.keras.callbacks import EarlyStopping\nfrom keras.callbacks import ReduceLROnPlateau\n#importing image data generator for data augmentation\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n#for the final prediction report\nfrom sklearn.metrics import classification_report ,confusion_matrix","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Prepare Training Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"new_categories = [x['name'] for x in categories]\nprint(new_categories)\nencoded_categories = to_categorical(list(range(len(new_categories))), num_classes=len(new_categories))\nprint(encoded_categories)\n\ncategory_mapping = {x:encoded_categories[i] for i,x in enumerate(new_categories)}\nprint(category_mapping)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2\nimport traceback\nimport sys\n\n# dresses_count = 0\n# trousers_count = 0\n\ndef transform_data(annotations, base_dir, samples_per_cat=None, cats=None):\n    features = []\n    labels = []\n    max_check = False\n    cat_count = {}\n    \n    if samples_per_cat is not None:\n        max_check = True\n        cat_count = {x:0 for x in cats}\n    else:\n        samples_per_cat = sys.maxsize\n        \n    \n    for i, annotation in enumerate(annotations):\n        img_path = annotation['image_path']\n        cat = annotation['cat']\n        bbox = annotation['bbox']\n\n        try:\n            if max_check:\n                if cat in cats:\n                    if cat_count[cat] >= samples_per_cat:\n                        continue\n                else:\n                    continue\n\n        #     if cat == 'trousers':\n        #         trousers_count +=1\n\n        #         if trousers_count > max_img:\n        #             continue\n        #     elif cat == 'dresses':\n        #         dresses_count +=1\n\n        #         if dresses_count > max_img:\n        #             continue\n        #     else:\n        #         continue\n\n            img = cv2.imread(base_dir+img_path)\n\n            if img is None:\n                continue\n            \n            #x,y,w,h = rescale_bbox(bbox, (img.shape[0],img.shape[1]))\n            cropped_image = get_cropped_image(img, bbox)\n            resized_image = get_reshaped_image(cropped_image, new_shape=(128,128))\n\n            features.append(resized_image)\n            labels.append(category_mapping[cat])\n\n            cat_count[cat] += 1\n            \n            if i != 0 and i % 1000 == 0:\n                print(\"Processed Images: \",i)\n\n            #print(resized_image.shape)\n\n            #plt.imshow(resized_image)\n            #plt.title(cat)\n            #plt.show()\n        except:\n            print(f\"Error in image: bbox={bbox}, img_path={img_path}, cat={cat}\")\n            traceback.print_exc()\n        \n    return features, labels\n    \n    \nmax_samples = 10000\n# cats = {'tops','trousers'}\ncats = set(new_categories)\n    \ntrain_features, train_labels = transform_data(train_annotations, r'../input/til2020/train/train/',samples_per_cat=max_samples, cats=cats)\n    \nprint(len(train_features))\nprint(len(train_labels))\n\n#print(train_data[0])\n#print(labels[0])\n\ntest_features, test_labels = transform_data(test_annotations, r'../input/til2020/val/val/',samples_per_cat=max_samples, cats=cats)\n    \nprint(len(test_features))\nprint(len(test_labels))\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(len(train_features))\nprint(len(train_labels))\n\ntrain_features_2 = np.asarray(train_features)\nprint(train_features_2.shape)\ntrain_labels_2 = np.asarray(train_labels)\nprint(train_labels_2.shape)\n\nprint(len(test_features))\nprint(len(test_labels))\n\ntest_features_2 = np.asarray(test_features)\nprint(test_features_2.shape)\ntest_labels_2 = np.asarray(test_labels)\nprint(test_labels_2.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\ninput_shape = (128, 128, 3)\nepoch = 100\n\nmodel = Sequential()\n\nmodel.add(Conv2D(64, kernel_size=(5,5), input_shape=input_shape, activation='relu'))\nmodel.add(MaxPool2D(pool_size=(2,2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(64, kernel_size=(3,3), input_shape=input_shape, activation='relu'))\nmodel.add(MaxPool2D(pool_size=(2,2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(32, kernel_size=(3,3), input_shape=input_shape, activation='relu'))\nmodel.add(MaxPool2D(pool_size=(2,2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(32, kernel_size=(3,3), input_shape=input_shape, activation='relu'))\nmodel.add(MaxPool2D(pool_size=(2,2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Flatten())\nmodel.add(Dense(1024, activation='relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(len(category_mapping), activation='softmax'))\n\nmodel.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])\n\n# x_train, x_test, y_train, y_test = train_test_split(train_data2, labels2, test_size=0.2, random_state=1)\n\nearly_stop= EarlyStopping(monitor='val_loss',patience=10)\n\nmodel.fit(train_features_2, train_labels_2,\n          epochs=epoch,\n          validation_data=(test_features_2,test_labels_2), \n          callbacks=[early_stop])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Let's Train VGG16 "},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"# example of loading the vgg16 model\nfrom keras.applications.vgg16 import VGG16\n\nvgg16 = VGG16(weights=None, input_shape=input_shape, classes=len(categories))\n\n# summarize the model\nvgg16.summary()\n\nvgg16.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])\n\nearly_stop= EarlyStopping(monitor='val_loss',patience=10)\n\nlearning_rate_reduction = ReduceLROnPlateau(monitor='val_accuracy', \n                                            patience=10, \n                                            verbose=1, \n                                            factor=0.5, \n                                            min_lr=0.00001)\n\nvgg16.fit(train_features_2, train_labels_2,\n          epochs=epoch,\n          validation_data=(test_features_2,test_labels_2), \n          callbacks=[early_stop, learning_rate_reduction])\n\nmetrics=pd.DataFrame(vgg16.history.history)\nmetrics","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Let's Train ResNet50"},{"metadata":{"trusted":true},"cell_type":"code","source":"# example of loading the vgg16 model\nfrom keras.applications.resnet50 import ResNet50\n\nresnet_50 = ResNet50(weights=None, input_shape=input_shape, classes=len(categories))\n\n# summarize the model\nresnet_50.summary()\n\nresnet_50.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])\n\nearly_stop= EarlyStopping(monitor='val_loss',patience=10)\n\nlearning_rate_reduction = ReduceLROnPlateau(monitor='val_accuracy', \n                                            patience=10, \n                                            verbose=1, \n                                            factor=0.5, \n                                            min_lr=0.00001)\n\nresnet_50.fit(train_features_2, train_labels_2,\n          epochs=epoch,\n          validation_data=(test_features_2,test_labels_2), \n          callbacks=[early_stop, learning_rate_reduction])\n\nmetrics=pd.DataFrame(resnet_50.history.history)\nmetrics","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Let's Train InceptionV3"},{"metadata":{"trusted":true},"cell_type":"code","source":"# example of loading the vgg16 model\nfrom keras.applications.inception_v3 import InceptionV3\n\ninception_v3 = InceptionV3(weights=None, input_shape=input_shape, classes=len(categories))\n\n# summarize the model\ninception_v3.summary()\n\ninception_v3.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])\n\nearly_stop= EarlyStopping(monitor='val_loss',patience=10)\n\nlearning_rate_reduction = ReduceLROnPlateau(monitor='val_accuracy', \n                                            patience=10, \n                                            verbose=1, \n                                            factor=0.5, \n                                            min_lr=0.00001)\n\ninception_v3.fit(train_features_2, train_labels_2,\n          epochs=epoch,\n          validation_data=(test_features_2,test_labels_2), \n          callbacks=[early_stop, learning_rate_reduction])\n\nmetrics=pd.DataFrame(inception_v3.history.history)\nmetrics","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":4}