{"metadata":{"colab":{"provenance":[],"gpuType":"T4"},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"},"accelerator":"GPU"},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"\n# ✨ Summary ✨\n1. 👬 Team: ML (Mesh La3eb)\n2. 🤔 Approach:\n    - 📩 Download Dataset\n    - 🏗️ Feature Extraction with Resnet\n    - 🧠 Train SVM Classifier\n\n# 📥 Download Dataset\nThe dataset is zipped and stored on Google.\n\n# 📦 Extract Dataset\nExtract the downloaded dataset.\n\n# 📕 Read Dataset\nRead the dataset, identify the classes and append them along with their corresponding file paths into a DataFrame.\n\n# ✂️ Split Dataset\n- Define Image transforms.\n- Read the Dataset into a DataFrame `df`.\n- Apply transformations and split the images into different classes, store this as a dataset.\n- Split this dataset into training and test datasets.\n\n# 🖼️  Image Feature Extraction\n- Load pretrained Resnet model and utilize it as feature extractor.\n- Prepare tensors for the feature extraction.\n- Pass these through the Resnet model to extract features.\n\n# 🎯 Hyper Parameter Tuning\n- Use a RandomForestRegressor with GridSearchCV to conduct hyper-parameter tuning.\n\n# 🧪 Define the Classifier\n- Use a Support Vector Machine (SVM) with a polynomial kernel to fit our training data and predict the test data.\n- Print the accuracy, f1 score of the model.\n\n# 🚀 Get Prediction\n- Obtain the model's predictions on the test dataset.\n\n# 🎁 Format and Save Submission\n- Format the submission according to requirements and save it as 'submission1.csv'.\n\n","metadata":{"id":"9g4ME14Wj5Rx"}},{"cell_type":"markdown","source":"# 📩 Download Dataset","metadata":{"id":"8t9L2FWakYlk"}},{"cell_type":"code","source":"# Download Dataset\n!wget 'https://storage.googleapis.com/kaggle-competitions-data/kaggle-v2/59947/6471643/bundle/archive.zip?GoogleAccessId=web-data@kaggle-161607.iam.gserviceaccount.com&Expires=1693731716&Signature=ufbqBH3OA8lA3ZlV18koKyu9iTkF%2Fo8zQlP0UkvYSAUFHdXvpHbCjYioaBTbfyM2nZzTYyIpQmlqnRfJR9QOqfU9V6dKPZFryFVxRjyIBjfurq2TEb9WMJUYbP4XeQo9nJ%2BPY4HegXDV7uyDJlWbmsiKf5OxxrjvRb8ydDmWb70HHDFBx6jfubYd%2BoP15NXyrsY7%2BV63NI6y43blyzoxPxTKWoMOazUxuziPLqgnJSIxUAJZ6TRXPzRMZYYUhLsjBLr8yd6%2FaKUZCjJ5UmYTDrRuxvTxPCsT%2BRBwLMrPtFcAZTJ6n3Oa441lWmPjr5JJXr5D8b7q005vcauhmRL4rA%3D%3D&response-content-disposition=attachment%3B+filename%3Dbioverse-hackathon.zip'","metadata":{"id":"qj9Wl9gn1Ptx","outputId":"af23a529-a812-4633-9191-6f4b9be6c499"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 🛒 Extract Dataset","metadata":{"id":"UjlHdIDWlGpa"}},{"cell_type":"code","source":"# Extract Dataset\n!unzip 'archive.zip?GoogleAccessId=web-data@kaggle-161607.iam.gserviceaccount.com&Expires=1693731716&Signature=ufbqBH3OA8lA3ZlV18koKyu9iTkF%2Fo8zQlP0UkvYSAUFHdXvpHbCjYioaBTbfyM2nZzTYyIpQmlqnRfJR9QOqfU9V6dKPZFryFVxRjyIBjfurq2TEb9WMJUYbP4XeQo9nJ+'\n","metadata":{"id":"FuLq28Ft1RjP","outputId":"dbe3e8e2-e3a4-4205-b8b5-cb6e60cfaeb4"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 📖 Read Dataset","metadata":{"id":"nM3t85KTl7Il"}},{"cell_type":"code","source":"import os\nimport pandas as pd\n\ndef read_dataset(dataset_path):\n    data = []\n    for class_label in os.listdir(dataset_path):\n        class_dir = os.path.join(dataset_path, class_label)\n        if os.path.isdir(class_dir):\n            for sample_file in os.listdir(class_dir):\n                sample_path = os.path.join(class_dir, sample_file)\n                for sample_img in os.listdir(sample_path):\n                  if sample_img.endswith(\".png\"):\n                      img_path = os.path.join(sample_path, sample_img)\n                      data.append({\"path\": img_path, \"class\": class_label})\n    return pd.DataFrame(data)\n\n# Usage example\ndataset_path = \"train\"\ndf = read_dataset(dataset_path)\ndf.head()","metadata":{"id":"uyYM9OMu3jGR","outputId":"eb50b1e2-5430-4d97-c801-b0b0a09a293d"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 🔪 Split Dataset","metadata":{"id":"nExNg9wJmB_y"}},{"cell_type":"code","source":"import torchvision.transforms as transforms\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader\nfrom torchvision.datasets import ImageFolder\nfrom torchvision.transforms import ToTensor, Resize, Normalize\nfrom torchvision.models import resnet18, resnet50\nimport torchvision.transforms as transforms\nfrom PIL import Image\nfrom sklearn.model_selection import train_test_split\n\ndef process_img(img_path: str, transform):\n  image = Image.open(img_path)\n  image = transform(image)\n  return image\n\ndef split_dataset(df, classes):\n  df = df.groupby('class')\n  return [df.get_group(c)['path'] for c in classes]\n\ndef get_train_data(df, classes, transform):\n  dataset = []\n\n  for class_index, c in enumerate(split_dataset(df, classes)):\n    dataset.extend([(process_img(image, transform), class_index, image) for i, image in enumerate(c)])\n\n  return dataset\n\ndef get_test_data(dataset_path, transform):\n    data = []\n    for sample_img in os.listdir(dataset_path):\n          if sample_img.endswith(\".png\"):\n                  img_path = os.path.join(dataset_path, sample_img)\n                  data.append({\"path\": img_path})\n    data = pd.DataFrame(data)\n    test_data = []\n    test_data.extend([(process_img(image, transform), image) for image in data['path']])\n    return test_data\n\n\n\nnum_classes = 3\n\n# Define data transforms\ntrain_transforms = transforms.Compose([\n                                       transforms.Resize(255),\n                                       transforms.CenterCrop(224),\n                                       transforms.RandomHorizontalFlip(),\n                                       transforms.ToTensor(),\n                                       transforms.Lambda(lambda x: x.repeat(3, 1, 1) if x.shape[0] != 3 else x),\n                                       transforms.Normalize((0.5), (0.5))])\n\ntest_transforms = transforms.Compose([\n                                       transforms.Resize(255),\n                                       transforms.CenterCrop(224),\n                                       transforms.ToTensor(),\n                                       transforms.Lambda(lambda x: x.repeat(3, 1, 1)),\n                                       transforms.Normalize((0.5), (0.5))])\n","metadata":{"id":"_4G_JYAlQNjS"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 🖼️  Image Feature Extraction","metadata":{"id":"WKkd0m1wql77"}},{"cell_type":"code","source":"classes = ['beneign', 'normal', 'malignant']\n\n# Read Dataset\ndf = read_dataset('train')\ndataset = get_train_data(df, classes, train_transforms)\n\n# Train Val Split\ntrain, test = train_test_split(dataset, train_size=0.9)\n\n# Image Feature Extraction\n## Load pretrained resnet\nfeature_extractor = resnet50(pretrained=True).cuda()\nfeature_extractor.fc = nn.Identity()\n\n## Convert and prepare for extracting\nX_train = torch.tensor(train[0][0].unsqueeze(0))\nX_test = torch.tensor(test[0][0].unsqueeze(0))\n\nfor x in train[1:]:\n  X_train = torch.cat([X_train, x[0].unsqueeze(0)], dim=0)\n\nfor x in test[1:]:\n  X_test = torch.cat([X_test, x[0].unsqueeze(0)], dim=0)\n\ny_train = [x[1] for x in train]\ny_test = [x[1] for x in test]","metadata":{"id":"TySOXnSXEZ5t","outputId":"a69ca9af-3b77-4704-bb8c-bcfe8805425e"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Pass tensors to resnet\nX_train = X_train.cuda()\nX_test = X_test.cuda()\nwith torch.no_grad():\n  X_train = feature_extractor(X_train)\n  X_test = feature_extractor(X_test)\n  print(X_train.shape, X_test.shape)","metadata":{"id":"13vhqbW1GMxT","outputId":"167bbadb-176b-4461-e7e4-3216b6903282"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 🎯 Hyper Parameter Tuning","metadata":{"id":"WyRp-0ciqvaO"}},{"cell_type":"code","source":"# Hyper Parameter Tuning\nfrom sklearn.model_selection import GridSearchCV\nfrom sklearn.svm import SVC\n# Prepare data for classifier\nX_train = X_train.detach().cpu().numpy()\nX_test = X_test.detach().cpu().numpy()\n\nparam_grid = {'C': [0.1, 10, 100, 1000],\n              'gamma': [1, 0.001, 0.1, 0.01, 0.0001],\n              'kernel': ['rbf', 'poly'],\n              'degree' : [3, 4, 5, 6]}\n\ngrid = GridSearchCV(SVC(), param_grid, refit = True, verbose = 3)\n\n# fitting the model for grid search\ngrid.fit(X_train, y_train)","metadata":{"id":"hpr_bdx1Ziox","outputId":"6ccf0586-d79d-4dcd-9440-a19ac8101be5"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# print hyper-parameter tuning result\nprint(grid.best_estimator_)\nprint(\"\\n The best parameters across ALL searched params:\\n\",grid.best_params_)\n","metadata":{"id":"UfYfht8KfmON","outputId":"2a3376c8-8b7b-4503-dab3-a3dbf9c090ec"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 🧪 Define the Classifier\n","metadata":{"id":"CKjNByqsq0-Q"}},{"cell_type":"code","source":"from sklearn import svm, datasets\nimport sklearn.model_selection as model_selection\nfrom sklearn.metrics import accuracy_score\nfrom sklearn.metrics import f1_score\nimport xgboost as xgb\nfrom sklearn.model_selection import cross_val_score, GridSearchCV, KFold, RandomizedSearchCV, train_test_split\n\n\n# Define the Classifier\npoly = SVC(kernel='poly', C=10,degree=3, gamma=0.001).fit(X_train, y_train)\n\npoly_pred = poly.predict(X_test)\n\n# Print accuracy and f1 score\npoly_accuracy = accuracy_score(y_test, poly_pred)\npoly_f1 = f1_score(y_test, poly_pred, average='weighted')\nprint('Accuracy (Polynomial Kernel): ', \"%.2f\" % (poly_accuracy*100))\nprint('F1 (Polynomial Kernel): ', \"%.2f\" % (poly_f1*100))","metadata":{"id":"9c-enr0tE7JO","outputId":"98230e15-02d1-486c-c705-7d737df3e75c"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Accuracy (Polynomial Kernel):**  81.58 🎉\n## **F1 (Polynomial Kernel):**  81.58 🎊","metadata":{"id":"ozbQFygGrEQy"}},{"cell_type":"markdown","source":"# 🚀 Get Prediction\n","metadata":{"id":"72knfs4oq59u"}},{"cell_type":"code","source":"# Get Prediction\nimport time\n\ntest_dataset = get_test_data('test', train_transforms)\n\nX_test = torch.tensor(test_dataset[0][0].unsqueeze(0))\nfor x in test_dataset[1:]:\n  X_test = torch.cat([X_test, x[0].unsqueeze(0)], dim=0)\n\nimg_path = [x[1] for x in test_dataset]\n\nX_test = X_test.cuda()\nwith torch.no_grad():\n  X_test = feature_extractor(X_test)\n\nX_test = X_test.detach().cpu().numpy()\n\nt = time.time()\npoly_pred = poly.predict(X_test)\nprint(\"Inference Time: \", time.time()-t)","metadata":{"id":"gVRdEBEdN32z","outputId":"45c8ce2d-06b1-4dc5-f738-a297e3476b50"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Inference Time:**  0.036 🤘","metadata":{"id":"5UcQZSfjmRa3"}},{"cell_type":"markdown","source":"# 🚀 Format and Save Submission","metadata":{"id":"Yuzr-O5QkME7"}},{"cell_type":"code","source":"# Format and Save Submission\nimg_path = [os.path.basename(file_path) for file_path in img_path ]\noutput = [classes[p] for p in poly_pred]\n\ndata = {'filename': img_path, 'class': output}\ndff = pd.DataFrame(data)\n\n# Write to file\ndff.to_csv('final.csv', index=False)","metadata":{"id":"35aR3CqpOm1h"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"id":"nrL5KIbGsCEu"},"execution_count":null,"outputs":[]}],"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"}}