{"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":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport torch\nimport torchvision as tv\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optims\nimport torchvision.transforms as transforms\nfrom PIL import Image\nimport os\nfrom transformers import AutoImageProcessor, ResNetForImageClassification\nimport torchvision.transforms as T\nfrom PIL import Image\nimport matplotlib.pyplot as plt","metadata":{"_uuid":"3d4c015f-53b8-4057-9cf4-20316977c544","_cell_guid":"8172d2de-fe68-45b0-a8f4-916f967c2092","scrolled":true,"execution":{"iopub.status.busy":"2023-06-03T12:19:11.572161Z","iopub.execute_input":"2023-06-03T12:19:11.572899Z","iopub.status.idle":"2023-06-03T12:19:26.65429Z","shell.execute_reply.started":"2023-06-03T12:19:11.572857Z","shell.execute_reply":"2023-06-03T12:19:26.65257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Домашняя работа\nФедотов Максим, 23 по списку, БИВ202","metadata":{}},{"cell_type":"markdown","source":"# Задание 1. Подготовка датасета","metadata":{}},{"cell_type":"markdown","source":"Разработать программу, принимающую на вход изображение из категории Imagenet своего варианта и выдающее название категории изображенного объекта и вероятность соответствия его этой категории. ","metadata":{}},{"cell_type":"markdown","source":"вариант = 20 * 2 + 10 * 23 = 230 + 40 = 270","metadata":{}},{"cell_type":"markdown","source":"Сначала напишу функцию для правильного резайса изображения.","metadata":{}},{"cell_type":"code","source":"def resize_image(src, size=(128, 128), bgc=\"white\"):\n    src.thumbnail(size, Image.ANTIALIAS)\n    \n    new_image = Image.new(\"RGB\", size, bgc)\n    \n    new_image.paste(src, (int((size[0]-src.size[0]) / 2)), int((size[1] - src.size[1]) / 2))\n    \n    return new_image","metadata":{"execution":{"iopub.status.busy":"2023-06-03T12:19:26.657119Z","iopub.execute_input":"2023-06-03T12:19:26.657476Z","iopub.status.idle":"2023-06-03T12:19:26.667936Z","shell.execute_reply.started":"2023-06-03T12:19:26.657439Z","shell.execute_reply":"2023-06-03T12:19:26.666404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Для дообучения будут неоходимые различные трансформации над изображением для лучшего обучения. Это работает как регуляризация, чтобы модель могла лучше видеть в темноте или перевернутое изображение.\nДля первого задания пока закомментирую некоторые трансформации, чтобы было удобнее смотреть.","metadata":{}},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.Resize([256, 256]),\n#     transforms.RandomHorizontalFlip(),\n#     transforms.RandomVerticalFlip(),\n#     transforms.ColorJitter(brightness=0.5, contrast=0),\n    transforms.ToTensor(),\n#     transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])\n])","metadata":{"execution":{"iopub.status.busy":"2023-06-03T12:19:26.670377Z","iopub.execute_input":"2023-06-03T12:19:26.670956Z","iopub.status.idle":"2023-06-03T12:19:26.683525Z","shell.execute_reply.started":"2023-06-03T12:19:26.670897Z","shell.execute_reply":"2023-06-03T12:19:26.682075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Для дообучения понадобится даталодер. Разделю его на тренеровочную и тестовую, чтобы на одной обучать, а на другой тестировать. Дополнительно перемешаю их","metadata":{}},{"cell_type":"code","source":"def load(path, transform=None):\n    dataset = tv.datasets.ImageFolder(root=path,transform = transform)\n    \n    train_size = int(0.7 * len(dataset))\n    test_size = len(dataset) - train_size\n    \n    train_set, test_set = torch.utils.data.random_split(dataset, [train_size, test_size])\n    \n    train_loader = torch.utils.data.DataLoader(\n        train_set,\n        batch_size=50,\n        num_workers=0,\n        shuffle=False\n    )\n    \n    test_loader = torch.utils.data.DataLoader(\n        test_set,\n        batch_size=50,\n        num_workers=0,\n        shuffle=False\n    )\n\n    return train_loader, test_loader\n\ntrain_loader, test_loader = load('/kaggle/input/imagenetmini-1000/imagenet-mini/train', transform)\nprint(f\"train loaders: {train_loader}\")","metadata":{"execution":{"iopub.status.busy":"2023-06-03T12:19:26.687334Z","iopub.execute_input":"2023-06-03T12:19:26.687837Z","iopub.status.idle":"2023-06-03T12:19:44.273392Z","shell.execute_reply.started":"2023-06-03T12:19:26.687787Z","shell.execute_reply":"2023-06-03T12:19:44.272114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Функция для возвращения изображения определенного класса","metadata":{}},{"cell_type":"code","source":"def get_example_class(cl: int):\n    for test_images, test_labels in test_loader:\n        for image, label in zip(test_images, test_labels):\n            if label == cl:\n                return image","metadata":{"execution":{"iopub.status.busy":"2023-06-03T12:19:44.27465Z","iopub.execute_input":"2023-06-03T12:19:44.275403Z","iopub.status.idle":"2023-06-03T12:19:44.281987Z","shell.execute_reply.started":"2023-06-03T12:19:44.275358Z","shell.execute_reply":"2023-06-03T12:19:44.280443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Изображение моего класса","metadata":{}},{"cell_type":"code","source":"my_class = get_example_class(270)\nplt.imshow(np.dstack(my_class))\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-03T12:19:44.283393Z","iopub.execute_input":"2023-06-03T12:19:44.285361Z","iopub.status.idle":"2023-06-03T12:19:53.313752Z","shell.execute_reply.started":"2023-06-03T12:19:44.285308Z","shell.execute_reply":"2023-06-03T12:19:53.312643Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"И не моего класса","metadata":{}},{"cell_type":"code","source":"not_my_class = get_example_class(271)\nplt.imshow(np.dstack(not_my_class))\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-03T12:19:53.315346Z","iopub.execute_input":"2023-06-03T12:19:53.315727Z","iopub.status.idle":"2023-06-03T12:19:55.637904Z","shell.execute_reply.started":"2023-06-03T12:19:53.315689Z","shell.execute_reply":"2023-06-03T12:19:55.636456Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Импортирую предобученную модель https://huggingface.co/microsoft/resnet-50.","metadata":{}},{"cell_type":"code","source":"# скачиваю модель и процессор\nprocessor = AutoImageProcessor.from_pretrained(\"microsoft/resnet-50\")\nmodel = ResNetForImageClassification.from_pretrained(\"microsoft/resnet-50\")\n\n# получаю преобразованные изображения\ninputs_my = processor(my_class, return_tensors=\"pt\")\ninputs_not_my = processor(not_my_class, return_tensors=\"pt\")\n\n# отправляю изображение в модель, вычисляю вероятности с помощью функции softmax\nwith torch.no_grad():\n    probs_my = F.softmax(model(**inputs_my).logits)\n    probs_not_my = F.softmax(model(**inputs_not_my).logits)\n\n# далее выбираю argmax с наивысшей вероятностью и определяю класс\npredicted_label_my = probs_my.argmax(-1).item()\npredicted_label_not_my = probs_not_my.argmax(-1).item()","metadata":{"execution":{"iopub.status.busy":"2023-06-03T12:19:55.639478Z","iopub.execute_input":"2023-06-03T12:19:55.639855Z","iopub.status.idle":"2023-06-03T12:20:12.298219Z","shell.execute_reply.started":"2023-06-03T12:19:55.639818Z","shell.execute_reply":"2023-06-03T12:20:12.296875Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Класс и вероятность моего класса изображения","metadata":{}},{"cell_type":"code","source":"predicted_label_my, probs_my.max(-1).values.item()","metadata":{"execution":{"iopub.status.busy":"2023-06-03T12:20:12.30003Z","iopub.execute_input":"2023-06-03T12:20:12.30118Z","iopub.status.idle":"2023-06-03T12:20:12.311225Z","shell.execute_reply.started":"2023-06-03T12:20:12.301124Z","shell.execute_reply":"2023-06-03T12:20:12.310093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"probs_my[0][271]","metadata":{"execution":{"iopub.status.busy":"2023-06-03T12:24:01.126353Z","iopub.execute_input":"2023-06-03T12:24:01.12678Z","iopub.status.idle":"2023-06-03T12:24:01.136687Z","shell.execute_reply.started":"2023-06-03T12:24:01.126745Z","shell.execute_reply":"2023-06-03T12:24:01.135294Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"И не моего","metadata":{}},{"cell_type":"code","source":"predicted_label_not_my, probs_not_my.max(-1).values.item()","metadata":{"execution":{"iopub.status.busy":"2023-06-02T10:21:07.039584Z","iopub.execute_input":"2023-06-02T10:21:07.040564Z","iopub.status.idle":"2023-06-02T10:21:07.050399Z","shell.execute_reply.started":"2023-06-02T10:21:07.040504Z","shell.execute_reply":"2023-06-02T10:21:07.049215Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"probs_not_my[0][270]","metadata":{"execution":{"iopub.status.busy":"2023-06-03T12:23:44.804841Z","iopub.execute_input":"2023-06-03T12:23:44.805723Z","iopub.status.idle":"2023-06-03T12:23:44.814945Z","shell.execute_reply.started":"2023-06-03T12:23:44.805678Z","shell.execute_reply":"2023-06-03T12:23:44.813505Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Модель успешно решила задание!","metadata":{}}]}