{"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":"# Setup Code","metadata":{}},{"cell_type":"code","source":"import cv2\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torchvision.transforms as transforms \nimport torchvision\nfrom torchvision import models\nimport os\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nfrom torch.utils.data import (\n    Dataset,\n    DataLoader)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-03-01T19:41:48.639682Z","iopub.execute_input":"2023-03-01T19:41:48.640115Z","iopub.status.idle":"2023-03-01T19:41:49.546416Z","shell.execute_reply.started":"2023-03-01T19:41:48.640032Z","shell.execute_reply":"2023-03-01T19:41:49.545413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"בדיקה האם באמת אנחנו משתמשים בכרטיס המסך והוא פעיל ולא במעבד","metadata":{}},{"cell_type":"code","source":"device = torch.device(\"cuda\")\n\nif torch.cuda.is_available:\n  print('Good to go!')\nelse:\n  print('Please set GPU via Edit -> Notebook Settings.')","metadata":{"execution":{"iopub.status.busy":"2023-03-01T19:41:50.264112Z","iopub.execute_input":"2023-03-01T19:41:50.265175Z","iopub.status.idle":"2023-03-01T19:41:50.271343Z","shell.execute_reply.started":"2023-03-01T19:41:50.265136Z","shell.execute_reply":"2023-03-01T19:41:50.270248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"הגדרה של הקלאס, של כל הנתונים (התמונות) שאנחנו מקבלים\nקריאה של קובץ הCSV\nהקובץ בעצם מגדיר איזה תמונות שייכות לאיזה קטוגרייה","metadata":{}},{"cell_type":"code","source":"class HDorNot(Dataset):\n    def __init__(self, csv_file, root_dir, transform=None):\n        self.annotations = pd.read_csv('/kaggle/input/aesthetic-visual-analysis/train.csv', index_col=0)\n        self.root_dir = root_dir\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.annotations)\n\n    def __getitem__(self, index):\n        img_path = '/kaggle/input/aesthetic-visual-analysis/dataset/dataset/'+ str(self.annotations.iloc[index, 0]) +'.jpg'\n        image = cv2.imread(img_path)\n        image = cv2.resize(image, (480, 480), interpolation = cv2.INTER_AREA)\n        y_label = torch.tensor(int(self.annotations.iloc[index, 1]))\n\n        if self.transform:\n            image = self.transform(image)\n        return (image, y_label)","metadata":{"execution":{"iopub.status.busy":"2023-03-01T19:41:51.808022Z","iopub.execute_input":"2023-03-01T19:41:51.808395Z","iopub.status.idle":"2023-03-01T19:41:51.818891Z","shell.execute_reply.started":"2023-03-01T19:41:51.808364Z","shell.execute_reply":"2023-03-01T19:41:51.817816Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"הגדרת פרמטרים בסיסיים, מספר הקלאסים שהוא 2 כי זה רק אם התמונה באיכות גבוהה או לא\nומספר הצבעים של התמונה שהוא 3 כי התמונות צבעוניות","metadata":{}},{"cell_type":"code","source":"# Hyperparameters\nin_channel = 3\nnum_classes = 2","metadata":{"execution":{"iopub.status.busy":"2023-03-01T19:41:53.579640Z","iopub.execute_input":"2023-03-01T19:41:53.579996Z","iopub.status.idle":"2023-03-01T19:41:53.585018Z","shell.execute_reply.started":"2023-03-01T19:41:53.579965Z","shell.execute_reply":"2023-03-01T19:41:53.583804Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"יצירת הקלאס","metadata":{}},{"cell_type":"code","source":"dataset = HDorNot(\n    csv_file=\"train.csv\",\n    root_dir=\"/kaggle/input/aesthetic-visual-analysis\",\n    transform=transforms.ToTensor(),\n)","metadata":{"execution":{"iopub.status.busy":"2023-03-01T19:41:54.987701Z","iopub.execute_input":"2023-03-01T19:41:54.988138Z","iopub.status.idle":"2023-03-01T19:41:55.017129Z","shell.execute_reply.started":"2023-03-01T19:41:54.988100Z","shell.execute_reply":"2023-03-01T19:41:55.016247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"בגלל שכל התמונות שאנחנו מקבלים בסט לא באותו הגדול אז יש צורך לשנות את הגודל של כל התמונות שיהיה זהה,\nבתא הבא יש דוגמה של תהליך שינוי הגודל והדפסה של מספר תמונות דוגמא אל מול התמונות המקוריות.\nשינוי הגודל של כל הסט מתבצע כבר בשלב הקליטה והפונקציה הבאה היא לצורך הדגמה בלבד","metadata":{}},{"cell_type":"code","source":"csv = pd.read_csv('/kaggle/input/aesthetic-visual-analysis/train.csv', index_col=0)\nfig, axs = plt.subplots(2, 5, figsize=(15, 10))\nsamples = 5\nimage_og = []\nimage_resized = []\nfor i in range(samples):\n    img_path = '/kaggle/input/aesthetic-visual-analysis/dataset/dataset/'+ str(csv.iloc[i, 0]) +'.jpg'\n    image = cv2.imread(img_path)\n    image_og.append(image)\n    image = cv2.resize(image, (480, 480), interpolation = cv2.INTER_AREA)\n    image_resized.append(image)\n\n\nfor i in range(len(image_og)):\n    axs[0, i].set_title(\"Original\")\n    axs[0, i].imshow(image_og[i])\n    axs[1, i].set_title(\"Resized\")\n    axs[1, i].imshow(image_resized[i])\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-03-01T08:25:48.806630Z","iopub.execute_input":"2023-03-01T08:25:48.807224Z","iopub.status.idle":"2023-03-01T08:25:50.148698Z","shell.execute_reply.started":"2023-03-01T08:25:48.807199Z","shell.execute_reply":"2023-03-01T08:25:50.147758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"הגדרת סט האימון וסט הבדיקה והגודל של כל סט ביחס למספר התמונות הכולל, החלטתי שסט הבדיקה יהיה 20 אחוז מסך כל התמונות בגלל שזה המספר שלוקחים בדרך כלל","metadata":{}},{"cell_type":"code","source":"train_size = int(0.8 * len(dataset))\ntest_size = len(dataset) - train_size\ntrain_set, test_set = torch.utils.data.random_split(dataset, [train_size, test_size])","metadata":{"execution":{"iopub.status.busy":"2023-03-01T19:41:59.252805Z","iopub.execute_input":"2023-03-01T19:41:59.254019Z","iopub.status.idle":"2023-03-01T19:41:59.264670Z","shell.execute_reply.started":"2023-03-01T19:41:59.253968Z","shell.execute_reply":"2023-03-01T19:41:59.262863Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"פונקציית האימון עצמה, מקבל את מספר האיפוקים שאנחנו רוצים לעשות ומאמנת את הרשת","metadata":{}},{"cell_type":"code","source":"def Train(epochs):\n    for epoch in range(epochs):\n        losses = []\n\n        for batch_idx, (data, targets) in enumerate(train_loader):\n            # Get data to cuda if possible\n            data = data.to(device=device)\n            targets = targets.to(device=device)\n\n            # forward\n            scores= model(data)\n            loss = criterion(scores, targets)\n            \n            losses.append(loss.item())\n\n            # backward\n            optimizer.zero_grad()\n            loss.backward()\n\n            # gradient descent or adam step\n            optimizer.step()","metadata":{"execution":{"iopub.status.busy":"2023-03-01T19:42:00.555393Z","iopub.execute_input":"2023-03-01T19:42:00.556074Z","iopub.status.idle":"2023-03-01T19:42:00.562835Z","shell.execute_reply.started":"2023-03-01T19:42:00.556039Z","shell.execute_reply":"2023-03-01T19:42:00.561893Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"פונקצייה לבדיקת הדיוק של המודל, מקבל את המודל עצמו ואת סט האימון או הבדיקה ומחזירה את הדיוק","metadata":{}},{"cell_type":"code","source":"def check_accuracy(loader, model, mode=1):\n    class_names = [\"Low resolution\", \"High resolution\"]\n    num_correct = 0\n    num_samples = 0\n    model.eval()\n\n    with torch.no_grad():\n        for x, y in loader:\n            x = x.to(device=device)\n            y = y.to(device=device)\n\n            scores = model(x)\n            _, predictions = scores.max(1)\n            num_correct += (predictions == y).sum()\n            num_samples += predictions.size(0)\n            \n        if mode == 2:\n            # Loop through each prediction\n            for i in range(10):\n                # Print the sample image and the true label\n                print(f\"Sample {i+1}:\")\n                plt.imshow(x[i].cpu().permute(1, 2, 0))\n                plt.show()\n                true_label_name = class_names[y[i].item()]\n                print(f\"True label: {true_label_name}\")\n\n                # Determine if the prediction was correct and print the result\n                pred_label_name = class_names[predictions[i].item()]\n                if predictions[i] == y[i]:\n                    print(f\"Prediction: Correct ({pred_label_name})\")\n                else:\n                    print(f\"Prediction: Incorrect (predicted: {pred_label_name})\")\n                print()\n                    \n        elif mode == 1:\n            acc = float(num_correct)/float(num_samples)*100\n            acc = round(acc, 2)\n            return acc\n        elif mode == 0:\n            return (\n                f\"Got {num_correct} / {num_samples} with accuracy {float(num_correct)/float(num_samples)*100:.2f}\"\n            )\n\n    model.train()","metadata":{"execution":{"iopub.status.busy":"2023-03-01T19:42:03.145947Z","iopub.execute_input":"2023-03-01T19:42:03.146313Z","iopub.status.idle":"2023-03-01T19:42:03.157882Z","shell.execute_reply.started":"2023-03-01T19:42:03.146273Z","shell.execute_reply":"2023-03-01T19:42:03.156748Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"הורדה של מודל הרסנט 152 והתאמתו לסט הנוכחי","metadata":{}},{"cell_type":"code","source":"model = torchvision.models.resnet152(pretrained=True)\n\nfor param in model.parameters():\n    param.requires_grad = False\n\nmodel.fc = nn.Linear(2048, out_features=num_classes)\nmodel.to(device)\n\ncriterion = nn.CrossEntropyLoss()","metadata":{"execution":{"iopub.status.busy":"2023-03-01T19:42:06.821791Z","iopub.execute_input":"2023-03-01T19:42:06.822156Z","iopub.status.idle":"2023-03-01T19:42:22.117762Z","shell.execute_reply.started":"2023-03-01T19:42:06.822124Z","shell.execute_reply":"2023-03-01T19:42:22.116781Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"התא הבא מאמן את הרשת ומדפיס מה הדיוק בכל איפוק וככה אפשר לבחור את פרמטר האיפוקים שאיתו נשתמש בתאים הבאים","metadata":{}},{"cell_type":"code","source":"batch_size = 64\nepochs = 7\nweight_decay=1e-5\nlearning_rates = 0.01\nstat_dict = {}\ntrain_loader = DataLoader(dataset=train_set, batch_size=batch_size, shuffle=True)\ntest_loader = DataLoader(dataset=test_set, batch_size=batch_size, shuffle=True)\noptimizer = optim.Adam(model.parameters(), learning_rates, weight_decay=1e-5)\nfor epoch in range(epochs):\n    print(f\"Epoch: {epoch+1}\")\n    losses = []\n\n    for batch_idx, (data, targets) in enumerate(train_loader):\n        data = data.to(device=device)\n        targets = targets.to(device=device)\n\n        scores= model(data)\n        loss = criterion(scores, targets)\n\n        losses.append(loss.item())\n\n        optimizer.zero_grad()\n        loss.backward()\n\n        optimizer.step()\n    acc = check_accuracy(test_loader, model)\n    print(f\"train acc: {check_accuracy(train_loader, model,0)}\")\n    print(f\"test acc: {check_accuracy(test_loader, model,0)}\")\n    stat_dict[epoch+1] = acc","metadata":{"execution":{"iopub.status.busy":"2023-03-01T08:25:51.687216Z","iopub.execute_input":"2023-03-01T08:25:51.687695Z","iopub.status.idle":"2023-03-01T08:54:24.681347Z","shell.execute_reply.started":"2023-03-01T08:25:51.687658Z","shell.execute_reply":"2023-03-01T08:54:24.680248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"יצירת גרף מקלות המציג את הדיוק ואת מספר האיפוק","metadata":{}},{"cell_type":"code","source":"names = list(stat_dict.keys())\nvalues = list(stat_dict.values())\nplt.figure(figsize=(25, 5))\nplt.bar(range(len(stat_dict)), values, tick_label=names)\nfor i, v in enumerate(values):\n    plt.text(i, v, str(v), ha='center')\n\nplt.title(\"Epochs stats\")\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"accuracy %\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-03-01T08:54:24.682871Z","iopub.execute_input":"2023-03-01T08:54:24.683200Z","iopub.status.idle":"2023-03-01T08:54:24.925696Z","shell.execute_reply.started":"2023-03-01T08:54:24.683165Z","shell.execute_reply":"2023-03-01T08:54:24.924516Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"התא הבא משנה את הlr\nבכל סיבוב וככה אפשר לבדוק מה הפרמטר הכי טוב ואיתו אפשר להמשיך הלאה בתוכנית","metadata":{}},{"cell_type":"code","source":"batch_size = 32\nnum_epochs = 6\nweight_decay=1e-5\nlearning_rates = [1e-4, 1e-2, 0.1, 1e0, 1e2]\nstat_dict = {}\n\nfor lr in learning_rates:\n    optimizer = optim.Adam(model.parameters(), lr, weight_decay=1e-5)\n    print(f\"Learning rate: {lr}\")\n    Train(num_epochs)\n    acc = check_accuracy(test_loader, model)\n    print(f\"train acc: {check_accuracy(train_loader, model,0)}\")\n    print(f\"test acc: {check_accuracy(test_loader, model,0)}\")\n    stat_dict[lr] = acc","metadata":{"execution":{"iopub.status.busy":"2023-03-01T08:54:24.927436Z","iopub.execute_input":"2023-03-01T08:54:24.927850Z","iopub.status.idle":"2023-03-01T10:20:15.735256Z","shell.execute_reply.started":"2023-03-01T08:54:24.927812Z","shell.execute_reply":"2023-03-01T10:20:15.734086Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"יצירת גרף מקלות המציג את הדיוק ואת ה-LR","metadata":{}},{"cell_type":"code","source":"names = list(stat_dict.keys())\nvalues = list(stat_dict.values())\nplt.bar(range(len(stat_dict)), values, tick_label=names)\nfor i, v in enumerate(values):\n    plt.text(i, v, str(v), ha='center')\nplt.title(\"Accuracy stats\")\nplt.xlabel(\"learning rates\")\nplt.ylabel(\"accuracy %\")\nplt.figure(figsize=(15, 5))\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-03-01T10:20:15.736741Z","iopub.execute_input":"2023-03-01T10:20:15.737190Z","iopub.status.idle":"2023-03-01T10:20:15.934742Z","shell.execute_reply.started":"2023-03-01T10:20:15.737152Z","shell.execute_reply":"2023-03-01T10:20:15.933791Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"בדיקה מה הגודל של באצים שנותן לנו את הדיוק הגבוה ביותר, מעל 128 מגיעים למגבלת זיכרון ","metadata":{}},{"cell_type":"code","source":"batch_sizes = [8,16,32,64,128]\nnum_epochs = 6\nweight_decay=1e-5\nlearning_rates = 0.1\nstat_dict = {}\n\nfor batch_size in batch_sizes:\n    train_loader = DataLoader(dataset=train_set, batch_size=batch_size, shuffle=True)\n    test_loader = DataLoader(dataset=test_set, batch_size=batch_size, shuffle=True)\n    print(f\"Batch size: {batch_size}\")\n    Train(num_epochs)\n    acc = check_accuracy(test_loader, model)\n    print(f\"train acc: {check_accuracy(train_loader, model,0)}\")\n    print(f\"test acc: {check_accuracy(test_loader, model,0)}\")\n    stat_dict[batch_size] = acc","metadata":{"execution":{"iopub.status.busy":"2023-03-01T10:20:15.936393Z","iopub.execute_input":"2023-03-01T10:20:15.936809Z","iopub.status.idle":"2023-03-01T11:46:11.616397Z","shell.execute_reply.started":"2023-03-01T10:20:15.936770Z","shell.execute_reply":"2023-03-01T11:46:11.615347Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"יצירת גרף מקלות המציג את הדיוק ואת גודל הבאצ","metadata":{}},{"cell_type":"code","source":"names = list(stat_dict.keys())\nvalues = list(stat_dict.values())\nplt.bar(range(len(stat_dict)), values, tick_label=names)\nfor i, v in enumerate(values):\n    plt.text(i, v, str(v), ha='center')\n    \nplt.title(\"Batch sizes stats\")\nplt.xlabel(\"Batch sizes\")\nplt.ylabel(\"accuracy %\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-03-01T11:46:11.617931Z","iopub.execute_input":"2023-03-01T11:46:11.618560Z","iopub.status.idle":"2023-03-01T11:46:11.808743Z","shell.execute_reply.started":"2023-03-01T11:46:11.618520Z","shell.execute_reply":"2023-03-01T11:46:11.807855Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"הדפסה של תמונות דוגמה כולל החיזוי שלהן","metadata":{}},{"cell_type":"code","source":"batch_size = 64\nnum_epochs = 6\nweight_decay=1e-5\nlearning_rates = 0.1\ntrain_loader = DataLoader(dataset=train_set, batch_size=batch_size, shuffle=True)\ntest_loader = DataLoader(dataset=test_set, batch_size=batch_size, shuffle=True)\noptimizer = optim.Adam(model.parameters(), learning_rates, weight_decay=1e-5)\nTrain(num_epochs)\nacc = check_accuracy(test_loader, model)\nprint(f\"train acc: {check_accuracy(train_loader, model,0)}\")\nprint(f\"test acc: {check_accuracy(test_loader, model,0)}\")","metadata":{"execution":{"iopub.status.busy":"2023-03-01T19:42:46.789261Z","iopub.execute_input":"2023-03-01T19:42:46.789643Z","iopub.status.idle":"2023-03-01T19:57:58.804375Z","shell.execute_reply.started":"2023-03-01T19:42:46.789610Z","shell.execute_reply":"2023-03-01T19:57:58.803301Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"check_accuracy(test_loader, model, 2)","metadata":{"execution":{"iopub.status.busy":"2023-03-01T19:57:58.806683Z","iopub.execute_input":"2023-03-01T19:57:58.807354Z","iopub.status.idle":"2023-03-01T19:58:19.913312Z","shell.execute_reply.started":"2023-03-01T19:57:58.807315Z","shell.execute_reply":"2023-03-01T19:58:19.912550Z"},"trusted":true},"execution_count":null,"outputs":[]}]}