{"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\nfor 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 20GB 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 os\nimport time\nimport numpy as np\nfrom PIL import Image\nfrom torch.utils.data.dataset import Dataset\nfrom tqdm import tqdm\nfrom torchvision import transforms\nfrom torchvision import models\nimport torch\nfrom torch.utils.tensorboard import SummaryWriter\nfrom sklearn.metrics import precision_score, recall_score, f1_score\nfrom torch import nn\nfrom torch.utils.data.dataloader import DataLoader\nfrom matplotlib import pyplot as plt\nfrom numpy import printoptions\nimport requests\nimport tarfile\nimport random\nimport json\nfrom shutil import copyfile","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.manual_seed(2020)\ntorch.cuda.manual_seed(2020)\nnp.random.seed(2020)\nrandom.seed(2020)\ntorch.backends.cudnn.deterministic = True","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os, sys, tarfile\nfrom tqdm import tqdm\ndef extract(tar_url, extract_path='.'):\n    print(tar_url)\n    tar = tarfile.open(tar_url, 'r')\n    for item in tqdm(tar):\n        tar.extract(item, extract_path)\n        if item.name.find(\".tgz\") != -1 or item.name.find(\".tar\") != -1:\n            extract(item.name, \"./\" + item.name[:item.name.rfind('/')])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"try:\n    extract('../input/yelp-restaurant-photo-classification/train_photos' + '.tgz')\n    print ('Done.')\nexcept:\n    #name = os.path.basename(sys.argv[0])\n    print('error')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tqdm import tqdm\ntry:\n    extract('../input/yelp-restaurant-photo-classification/test_photos.tgz')\n    print ('Done.')\nexcept:\n    #name = os.path.basename(sys.argv[0])\n    print('error')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tqdm import tqdm\ntry:\n    extract('../input/yelp-restaurant-photo-classification/train.csv.tgz')\n    extract('../input/yelp-restaurant-photo-classification/train_photo_to_biz_ids.csv.tgz')\n    extract('../input/yelp-restaurant-photo-classification/test_photo_to_biz.csv.tgz')\n    extract('../input/yelp-restaurant-photo-classification/sample_submission.csv.tgz')\n    print ('Done.')\nexcept:\n    #name = os.path.basename(sys.argv[0])\n    print('error')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\ntrain_biz=pd.read_csv('./train_photo_to_biz_ids.csv')\ntrain_biz=train_biz.head(10000)\ntest_biz_biz=pd.read_csv('./test_photo_to_biz.csv')\ntest_biz_biz=test_biz_biz.head(10000)\ntrain=pd.read_csv('./train.csv')\ntrain=train.head(10000)\nsub=pd.read_csv('./sample_submission.csv')\ntrain_biz.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data=pd.merge(train_biz,train, on='business_id',how='left')\ndata=data.head(10000)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_test=pd.merge(test_biz_biz,sub, on='business_id',how='left') \ndata_test.head()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data=data.dropna(subset=['labels'])\ndata.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data['labs']=data['labels'].apply(lambda x:str(x).split(' '))\ndata","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labelsint=data.labs.tolist()\nfor i in tqdm(labelsint):\n    for j in range(len(i)):\n        #print(j)\n        #break\n        i[j]=int(i[j])\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data['labsint']=labelsint\ndata","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn import metrics, model_selection, preprocessing\ndf_train, df_valid = model_selection.train_test_split(\n        data, test_size=0.1, random_state=42\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class NusDataset(Dataset):\n    def __init__(self, data_path, data, transforms):\n        self.transforms = transforms\n        data=data\n        samples = data['photo_id'].tolist()\n        labs=data['labsint'].tolist()\n        self.classes = [0,1,2,3,4,5,6,7,8]\n\n        self.imgs = []\n        self.annos = []\n        self.data_path = data_path\n        #print('loading', anno_path)\n        for sample in samples:\n            self.imgs.append(sample)\n        for lab in labs:\n            self.annos.append(lab)\n            \n        for item_id in range(len(self.annos)):\n            item = self.annos[item_id]\n            vector = [cls in item for cls in self.classes]\n            self.annos[item_id] = np.array(vector, dtype=float)\n\n    def __getitem__(self, item):\n        anno = self.annos[item]\n        img_path = os.path.join(self.data_path, str(self.imgs[item])+'.jpg')\n        img = Image.open(img_path)\n        if self.transforms is not None:\n            img = self.transforms(img)\n        return img, anno\n\n        \n\n    def __len__(self):\n        return len(self.imgs)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dataset_val = NusDataset('./train_photos', df_valid, None)\ndataset_train = NusDataset('./train_photos', df_train, None)\n\n\nclass Resnext50(nn.Module):\n    def __init__(self, n_classes):\n        super().__init__()\n        resnet = models.resnext50_32x4d(pretrained=True)\n        resnet.fc = nn.Sequential(\n            nn.Dropout(p=0.2),\n            nn.Linear(in_features=resnet.fc.in_features, out_features=n_classes)\n        )\n        self.base_model = resnet\n        self.sigm = nn.Sigmoid()\n\n    def forward(self, x):\n        return self.sigm(self.base_model(x))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def calculate_metrics(pred, target, threshold=0.5):\n    pred = np.array(pred > threshold, dtype=float)\n    return {'micro/precision': precision_score(y_true=target, y_pred=pred, average='micro'),\n            'micro/recall': recall_score(y_true=target, y_pred=pred, average='micro'),\n            'micro/f1': f1_score(y_true=target, y_pred=pred, average='micro'),\n            'macro/precision': precision_score(y_true=target, y_pred=pred, average='macro'),\n            'macro/recall': recall_score(y_true=target, y_pred=pred, average='macro'),\n            'macro/f1': f1_score(y_true=target, y_pred=pred, average='macro'),\n            'samples/precision': precision_score(y_true=target, y_pred=pred, average='samples'),\n            'samples/recall': recall_score(y_true=target, y_pred=pred, average='samples'),\n            'samples/f1': f1_score(y_true=target, y_pred=pred, average='samples'),\n            }","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n# Initialize the training parameters.\nnum_workers = 8 \nlr = 1e-4 # Learning rate\nbatch_size = 32\nsave_freq = 35 # checkpoint frequency (epochs)\ntest_freq = 200 # Test model frequency (iterations)\nmax_epoch_number = 15 # Number of epochs for training \n\n\nmean = [0.485, 0.456, 0.406]\nstd = [0.229, 0.224, 0.225]\n\ndevice = torch.device('cuda')\n# Save path for checkpoints\nsave_path = 'chekpoints/'\n# Save path for logs\nlogdir = 'logs/'\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def checkpoint_save(model, save_path, epoch):\n    f = os.path.join(save_path, 'checkpoint-{:06d}.pth'.format(epoch))\n    if 'module' in dir(model):\n        torch.save(model.module.state_dict(), f)\n    else:\n        torch.save(model.state_dict(), f)\n    print('saved checkpoint:', f)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"val_transform = transforms.Compose([\n    transforms.Resize((256, 256)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean, std)\n])\nprint(tuple(np.array(np.array(mean)*255).tolist()))\n\n# Train preprocessing\ntrain_transform = transforms.Compose([\n    transforms.Resize((256, 256)),\n    transforms.RandomHorizontalFlip(),\n    transforms.ColorJitter(),\n    transforms.RandomAffine(degrees=20, translate=(0.2, 0.2), scale=(0.5, 1.5),\n                            shear=None, resample=False, \n                            fillcolor=tuple(np.array(np.array(mean)*255).astype(int).tolist())),\n    transforms.ToTensor(),\n    transforms.Normalize(mean, std)\n])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#test_annotations = os.path.join(img_folder, 'small_test.json')\n#train_annotations = os.path.join(img_folder, 'small_train.json')\n\ntest_dataset = NusDataset('./train_photos', df_valid, val_transform)\ntrain_dataset = NusDataset('./train_photos', df_train, train_transform)\n\n\n\ntrain_dataloader = DataLoader(train_dataset, batch_size=batch_size, num_workers=num_workers, shuffle=True,\n                              drop_last=True)\ntest_dataloader = DataLoader(test_dataset, batch_size=batch_size, num_workers=num_workers)\n\nnum_train_batches = int(np.ceil(len(train_dataset) / batch_size))\n\n# Initialize the model\nmodel = Resnext50(len(train_dataset.classes))\n# Switch model to the training mode and move it to GPU.\nmodel.train()\nmodel = model.to(device)\n\noptimizer = torch.optim.Adam(model.parameters(), lr=lr)\n\n\nif torch.cuda.device_count() > 1:\n    model = nn.DataParallel(model)\n\nos.makedirs(save_path, exist_ok=True)\n\n# Loss function\ncriterion = nn.BCELoss()\n# Tensoboard logger\nlogger = SummaryWriter(logdir)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"epoch = 0\niteration = 0\nwhile True:\n    batch_losses = []\n    for imgs, targets in tqdm(train_dataloader):\n        imgs, targets = imgs.to(device), targets.to(device)\n\n        optimizer.zero_grad()\n\n        model_result = model(imgs)\n        loss = criterion(model_result, targets.type(torch.float))\n\n        batch_loss_value = loss.item()\n        loss.backward()\n        optimizer.step()\n\n        logger.add_scalar('train_loss', batch_loss_value, iteration)\n        batch_losses.append(batch_loss_value)\n        with torch.no_grad():\n            result = calculate_metrics(model_result.cpu().numpy(), targets.cpu().numpy())\n            for metric in result:\n                logger.add_scalar('train/' + metric, result[metric], iteration)\n\n        if iteration % test_freq == 0:\n            model.eval()\n            with torch.no_grad():\n                model_result = []\n                targets = []\n                for imgs, batch_targets in tqdm(test_dataloader):\n                    imgs = imgs.to(device)\n                    model_batch_result = model(imgs)\n                    model_result.extend(model_batch_result.cpu().numpy())\n                    targets.extend(batch_targets.cpu().numpy())\n\n            result = calculate_metrics(np.array(model_result), np.array(targets))\n            for metric in result:\n                logger.add_scalar('test/' + metric, result[metric], iteration)\n            print(\"epoch:{:2d} iter:{:3d} test: \"\n                  \"micro f1: {:.3f} \"\n                  \"macro f1: {:.3f} \"\n                  \"samples f1: {:.3f}\".format(epoch, iteration,\n                                              result['micro/f1'],\n                                              result['macro/f1'],\n                                              result['samples/f1']))\n\n            model.train()\n        iteration += 1\n\n    loss_value = np.mean(batch_losses)\n    print(\"epoch:{:2d} iter:{:3d} train: loss:{:.3f}\".format(epoch, iteration, loss_value))\n    if epoch % save_freq == 0:\n        checkpoint_save(model, save_path, epoch)\n    epoch += 1\n    if max_epoch_number < epoch:\n        break","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.eval()\nif torch.cuda.is_available():\n    model.cuda()\nfor sample_id in [1,2,3,4,6]:\n    test_img, test_labels = test_dataset[sample_id]                        # this is what you had\n    test_img = test_img.cuda()\n    test_img_path = os.path.join('./train_photos', str(test_dataset.imgs[sample_id])+'.jpg')\n    with torch.no_grad():\n        raw_pred = model(test_img.unsqueeze(0)).cpu().numpy()[0]\n        raw_pred = np.array(raw_pred > 0.5, dtype=float)\n\n    predicted_labels = np.array(dataset_val.classes)[np.argwhere(raw_pred > 0)[:, 0]]\n    if not len(predicted_labels):\n        predicted_labels = ['no predictions']\n    img_labels = np.array(dataset_val.classes)[np.argwhere(test_labels > 0)[:, 0]]\n    plt.imshow(Image.open(test_img_path))\n    plt.title(\"Predicted labels: {} \\nGT labels: {}\".format(', '.join(str(predicted_labels)), ', '.join(str(img_labels))))\n    plt.axis('off')\n    plt.show()","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}