{"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# 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":"# импорт библиотек\nfrom __future__ import print_function, division\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.optim import lr_scheduler\nfrom torch.autograd import Variable\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms, utils, models\nimport torchvision\nfrom PIL import Image\nfrom tqdm import tqdm_notebook as tqdm\nimport matplotlib.pyplot as plt\nimport time","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# определяем пути \nTRAIN_IMG_PATH = \"../input/dog-breed-identification/train\"\nTEST_IMG_PATH = \"../input/dog-breed-identification/test\"\nLABELS_CSV_PATH = \"../input/dog-breed-identification/labels.csv\"\nSAMPLE_SUB_PATH = \"../input/dog-breed-identification/sample_submission.csv\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class DogsDataset(Dataset):\n    def __init__(self, img_dir, dataframe, transform=None):\n        self.labels_frame = dataframe\n        self.img_dir = img_dir\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.labels_frame)\n\n    def __getitem__(self, idx):\n        img_name = os.path.join(self.img_dir, self.labels_frame.id[idx]) + \".jpg\"\n        image = Image.open(img_name)\n        label = self.labels_frame.target[idx]\n\n        if self.transform:\n            image = self.transform(image)\n\n        return [image, label] ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dframe = pd.read_csv(LABELS_CSV_PATH)\nlabelnames = pd.read_csv(SAMPLE_SUB_PATH).keys()[1:]\ncodes = range(len(labelnames))\nbreed_to_code = dict(zip(labelnames, codes))\ncode_to_breed = dict(zip(codes, labelnames))\ndframe['target'] =  [breed_to_code[x] for x in dframe.breed]\n\ncut = int(len(dframe)*0.8)\ntrain, test = np.split(dframe, [cut], axis=0)\ntest = test.reset_index(drop=True)\n\ntrain_ds = DogsDataset(TRAIN_IMG_PATH, train)\ntest_ds = DogsDataset(TRAIN_IMG_PATH, test)\nidx = 29\nplt.imshow(train_ds[idx][0])\nprint(code_to_breed[train_ds[idx][1]])\nprint(\"Shape of the image is: \", train_ds[idx][0].size)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_transform = transforms.Compose([\n        transforms.RandomSizedCrop(224),\n        transforms.RandomHorizontalFlip(),\n        transforms.ToTensor(),\n        transforms.Normalize(mean=[0.485, 0.456, 0.406],\n                             std=[0.229, 0.224, 0.225])\n    ])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_ds = DogsDataset(TRAIN_IMG_PATH, train, data_transform)\ntest_ds = DogsDataset(TRAIN_IMG_PATH, test, data_transform)\ndatasets = {\"train\": train_ds, \"val\": test_ds}\n\nidx = 29\nprint(code_to_breed[train_ds[idx][1]])\nprint(\"Shape of the image is: \", train_ds[idx][0].shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"trainloader = DataLoader(train_ds, batch_size=14,\n                        shuffle=True, num_workers=4)\n\ntestloader = DataLoader(test_ds, batch_size=14,\n                        shuffle=True, num_workers=4)\n\ndataloaders = {\"train\": trainloader, \"val\": testloader}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# определяем device\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\ndevice","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = torchvision.models.resnet18(pretrained=True, progress=True)\n\n# настраиваем модель под свою задачу\nin_features = model.fc.in_features\nmodel.avgpool = nn.AdaptiveAvgPool2d(output_size=1)\nmodel.fc = nn.Linear(in_features, 120)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# функция тренировки\ndef train_model(model_conv, train_loader, valid_loader, criterion, optimizer, sheduler, n_epochs):\n    # переносим на GPU\n    model_conv.to(device)\n    \n    valid_loss_min = np.Inf\n\n    # количество эпох\n    for epoch in range(n_epochs):\n        train_loss = []\n        for batch_i, (data, target) in tqdm(enumerate(train_loader)):\n            data, target = data.to(device), target.to(device)\n            optimizer.zero_grad()\n            output = model_conv(data)\n            loss = criterion(output, target)\n            train_loss.append(loss.item())\n            loss.backward()\n            optimizer.step()\n        \n        # запускаем валидацию\n        model_conv.eval()\n        val_loss = []\n        for batch_i, (data, target) in enumerate(valid_loader):\n            data, target = data.to(device), target.to(device)\n            output = model_conv(data)\n            loss = criterion(output, target)\n            val_loss.append(loss.item())\n        \n        print(f'Epoch {epoch}, train loss: {np.mean(train_loss):.4f}, valid loss: {np.mean(val_loss):.4f}.')\n        valid_loss = np.mean(val_loss)\n        scheduler.step(valid_loss)\n        \n      \n        if valid_loss <= valid_loss_min:\n            print('Validation loss decreased ({:.6f} --> {:.6f}).  Saving model ...'.format(valid_loss_min, valid_loss))\n            torch.save(model_conv.state_dict(), 'model.pt')\n            valid_loss_min = valid_loss\n            \n\n    return model_conv, train_loss, val_loss","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# определяем лосс, оптимайзер, шедуллер\ncriterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)\nscheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, factor=0.8, patience=3,)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# запускаем обучение\nmodel_resnet, train_loss, val_loss = train_model(model, trainloader, testloader, criterion, optimizer, scheduler, n_epochs=25,)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.load_state_dict(torch.load(\"model.pt\"))\nmodel.to(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch.nn.functional as F\n# тестируем модель\nmodel.to(device)\nmodel.eval()\npred_list = []\nlabels_list = []\nfor images,labels in testloader:\n    images = images.to(device)\n    with torch.no_grad():\n        output = model(images)\n    pred = F.softmax(output)\n    pred = torch.argmax(pred, dim=1).cpu().numpy()\n    pred_list += [p.item() for p in pred]\n    labels_list += [name for name in labels]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df = pd.read_csv(SAMPLE_SUB_PATH)\noutput_df = pd.DataFrame(index=submission_df.index, columns=submission_df.keys() )\noutput_df['id'] = submission_df['id']\nsubmission_df['target'] =  [0] * len(submission_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tdata_transform = transforms.Compose([\n        transforms.Scale(256),\n        transforms.CenterCrop(224),\n        transforms.ToTensor(),\n        transforms.Normalize(mean=[0.485, 0.456, 0.406],\n                             std=[0.229, 0.224, 0.225])\n])\n\ntest_ds = DogsDataset(TEST_IMG_PATH, submission_df,tdata_transform)\ntestloader = DataLoader(test_ds, batch_size=14,\n                        shuffle=True, num_workers=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def test_sumission(model):\n    since = time.time()\n    sub_outputs = []\n    model.train(False)  # Set model to evaluate mode\n    # Iterate over data.\n    for data in testloader:\n        # get the inputs\n        inputs, labels = data\n\n        inputs = Variable(inputs.type(torch.cuda.FloatTensor))\n        labels = Variable(labels.type(torch.cuda.LongTensor))\n\n        # forward\n        outputs = model(inputs)\n        _, preds = torch.max(outputs.data, 1)\n        sub_outputs.append(outputs.data.cpu().numpy())\n\n    sub_outputs = np.concatenate(sub_outputs)\n    for idx,row in enumerate(sub_outputs.astype(float)):\n        sub_outputs[idx] = np.exp(row)/np.sum(np.exp(row))\n\n    output_df.loc[:,1:] = sub_outputs\n        \n    print()\n    time_elapsed = time.time() - since\n    print('Run complete in {:.0f}m {:.0f}s'.format(\n        time_elapsed // 60, time_elapsed % 60))\n\n    return output_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"odf = test_sumission(model)\nodf.to_csv(\"dogs_id.csv\", index=False)","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}