{"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":"# 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","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-04-03T04:44:53.573099Z","iopub.execute_input":"2022-04-03T04:44:53.573364Z","iopub.status.idle":"2022-04-03T04:45:39.981864Z","shell.execute_reply.started":"2022-04-03T04:44:53.573335Z","shell.execute_reply":"2022-04-03T04:45:39.980162Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Config","metadata":{}},{"cell_type":"code","source":"class CFG:\n    device = \"cuda\"\n    model_name = \"tf_efficientnet_b0_ns\"\n    image_size = 224 #528でpretrain\"https://github.com/rwightman/pytorch-image-models/blob/master/results/results-imagenet.csv\"\n    batch_size = 30\n    num_workers = 1\n    num_epochs = 10\n    fold = 0\n    seed = 123   ","metadata":{"execution":{"iopub.status.busy":"2022-04-07T13:43:21.887846Z","iopub.execute_input":"2022-04-07T13:43:21.888381Z","iopub.status.idle":"2022-04-07T13:43:21.915625Z","shell.execute_reply.started":"2022-04-07T13:43:21.888296Z","shell.execute_reply":"2022-04-07T13:43:21.915021Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install timm","metadata":{"execution":{"iopub.status.busy":"2022-04-07T13:51:26.560447Z","iopub.execute_input":"2022-04-07T13:51:26.560717Z","iopub.status.idle":"2022-04-07T13:51:36.983971Z","shell.execute_reply.started":"2022-04-07T13:51:26.560687Z","shell.execute_reply":"2022-04-07T13:51:36.983086Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"乱数固定","metadata":{}},{"cell_type":"code","source":"import os\nimport gc\nimport cv2\nimport math\nimport copy\nimport time\nimport random\n\n# For data manipulation\nimport numpy as np\nimport pandas as pd\n\n# Pytorch Imports\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nfrom torch.optim import lr_scheduler\nfrom torch.utils.data import Dataset, DataLoader\nfrom torch.cuda import amp\n\n# Utils\nimport joblib\nfrom tqdm import tqdm\nfrom collections import defaultdict\n\n# Sklearn Imports\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.model_selection import StratifiedKFold\n\n# For Image Models\nimport timm\n\n# Albumentations for augmentations\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\n\n# For colored terminal text\nfrom colorama import Fore, Back, Style\nb_ = Fore.BLUE\nsr_ = Style.RESET_ALL\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\n# For descriptive error messages\nos.environ['CUDA_LAUNCH_BLOCKING'] = \"1\"","metadata":{"execution":{"iopub.status.busy":"2022-04-07T13:51:43.672681Z","iopub.execute_input":"2022-04-07T13:51:43.672961Z","iopub.status.idle":"2022-04-07T13:51:45.674982Z","shell.execute_reply.started":"2022-04-07T13:51:43.672930Z","shell.execute_reply":"2022-04-07T13:51:45.674161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import random\nimport numpy as np\nimport torch\n\ndef torch_fix_seed (seed):\n    #Python random\n    random.seed(seed)\n    #Numpy\n    np.random.seed(seed)\n    #pyTorch\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    \n    #https://qiita.com/north_redwing/items/1e153139125d37829d2d\n    torch.backends.cudnn.benchmark = False \n    torch.backends.cudnn.deterministic = True\n    torch.use_deterministic_algoristhms = True\n    \ntorch_fix_seed (CFG.seed)","metadata":{"execution":{"iopub.status.busy":"2022-04-07T13:44:07.420715Z","iopub.execute_input":"2022-04-07T13:44:07.420972Z","iopub.status.idle":"2022-04-07T13:44:07.429774Z","shell.execute_reply.started":"2022-04-07T13:44:07.420943Z","shell.execute_reply":"2022-04-07T13:44:07.429056Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"データの確認","metadata":{}},{"cell_type":"code","source":"from glob import glob\n\n#指定のコンペから開いたnotebookじゃないと、ダメ\nroot_dir = \"../input/happy-whale-and-dolphin\"\n#globは、指定されたパターンに一致するパスを取得\n#glob中の*はワールドカードを表す\n#print中の*は、リストのアンパックを表す、要素ごとにとりだすが、今回はsepで要素間が改行\nprint(*glob(f\"{root_dir}/*\"), sep=\"\\n\")\nimage_dir = f\"{root_dir}/train_images\"","metadata":{"execution":{"iopub.status.busy":"2022-04-07T13:53:32.811831Z","iopub.execute_input":"2022-04-07T13:53:32.812144Z","iopub.status.idle":"2022-04-07T13:53:32.818655Z","shell.execute_reply.started":"2022-04-07T13:53:32.812110Z","shell.execute_reply":"2022-04-07T13:53:32.817898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\n\ntrain = pd.read_csv(f\"{root_dir}/train.csv\")\n\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2022-04-07T13:53:54.284543Z","iopub.execute_input":"2022-04-07T13:53:54.285156Z","iopub.status.idle":"2022-04-07T13:53:54.383307Z","shell.execute_reply.started":"2022-04-07T13:53:54.285080Z","shell.execute_reply":"2022-04-07T13:53:54.382500Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"画像読み込み","metadata":{}},{"cell_type":"code","source":"import cv2\nimport matplotlib.pyplot as plt\n\n#一番上の画像をパスで取得\nimage = cv2.imread(f\"{image_dir}/{train['image'].values[0]}\")\n#RGBへの変換\nimage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\nplt.title(train[\"species\"].values[0])\nplt.imshow(image)\nplt.show","metadata":{"execution":{"iopub.status.busy":"2022-04-07T13:56:05.461548Z","iopub.execute_input":"2022-04-07T13:56:05.461838Z","iopub.status.idle":"2022-04-07T13:56:06.013274Z","shell.execute_reply.started":"2022-04-07T13:56:05.461808Z","shell.execute_reply":"2022-04-07T13:56:06.012544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"datasetの定義","metadata":{}},{"cell_type":"code","source":"from torch.utils.data import Dataset\n\n#Datasetを継承して、学習用データセットのクラスをつくる\nclass WhaleDataset(Dataset):\n    def __init__(self, pathes, classes, transform = None):\n        self.pathes = pathes\n        self.classes = classes\n        self.transform = transform\n    def __len__(self):\n        return len(self.pathes)\n    #WhaleDataset(dataset)(index)となり、indexに対応した、cv2.imreadで処理されたデータおよび、classが出てくる\n    def __getitem__(self, index):\n        image = cv2.imread(f\"{image_dir}/{self.pathes[index]}\")\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        if self.transform:\n            image = transform(image=image)[\"image\"]\n        return image, torch.tensor(self.classes[index]).long()","metadata":{"execution":{"iopub.status.busy":"2022-04-07T13:57:09.477887Z","iopub.execute_input":"2022-04-07T13:57:09.478464Z","iopub.status.idle":"2022-04-07T13:57:09.484862Z","shell.execute_reply.started":"2022-04-07T13:57:09.478425Z","shell.execute_reply":"2022-04-07T13:57:09.484190Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import LabelEncoder\n\nLE = LabelEncoder()\n#LEのfitとtransformを一度に行う便利な関数。カテゴリ変数を数値化(0~)\ntrain[\"le_individual_id\"] = LE.fit_transform(train[\"individual_id\"])\n\n#LEにはclasses_が定義されている。_は名前の衝突を防ぐために使う\nprint(len(LE.classes_))\nprint(LE.classes_)\nprint(train[\"le_individual_id\"])\ndataset = WhaleDataset(train[\"image\"].values, train[\"le_individual_id\"].values)\n\nimage, label = dataset[0]\nplt.imshow(image)\nplt.title(label)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-07T14:03:06.201586Z","iopub.execute_input":"2022-04-07T14:03:06.201848Z","iopub.status.idle":"2022-04-07T14:03:06.503294Z","shell.execute_reply.started":"2022-04-07T14:03:06.201819Z","shell.execute_reply":"2022-04-07T14:03:06.500337Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"skf = StratifiedKFold(n_splits=5)\n\n#層状K分割だから、全体のデータXが必要？\nfor fold, ( _, val_) in enumerate(skf.split(X=train, y=train.individual_id)):\n    train.loc[val_ , \"kfold\"] = fold\n    print(_)\n    print(val_)\n        ","metadata":{"execution":{"iopub.status.busy":"2022-04-07T14:25:43.941609Z","iopub.execute_input":"2022-04-07T14:25:43.942363Z","iopub.status.idle":"2022-04-07T14:25:44.528379Z","shell.execute_reply.started":"2022-04-07T14:25:43.942314Z","shell.execute_reply":"2022-04-07T14:25:44.527676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train","metadata":{"execution":{"iopub.status.busy":"2022-04-07T14:21:21.072548Z","iopub.execute_input":"2022-04-07T14:21:21.072845Z","iopub.status.idle":"2022-04-07T14:21:21.093618Z","shell.execute_reply.started":"2022-04-07T14:21:21.072800Z","shell.execute_reply":"2022-04-07T14:21:21.092930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train[\"image\"].values","metadata":{"execution":{"iopub.status.busy":"2022-04-03T05:05:02.422829Z","iopub.execute_input":"2022-04-03T05:05:02.423612Z","iopub.status.idle":"2022-04-03T05:05:02.434467Z","shell.execute_reply.started":"2022-04-03T05:05:02.423562Z","shell.execute_reply":"2022-04-03T05:05:02.433779Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset[1]","metadata":{"execution":{"iopub.status.busy":"2022-04-03T05:08:40.515772Z","iopub.execute_input":"2022-04-03T05:08:40.51654Z","iopub.status.idle":"2022-04-03T05:08:40.63633Z","shell.execute_reply.started":"2022-04-03T05:08:40.516493Z","shell.execute_reply":"2022-04-03T05:08:40.635547Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2022-04-03T04:56:28.496121Z","iopub.execute_input":"2022-04-03T04:56:28.496388Z","iopub.status.idle":"2022-04-03T04:56:28.508059Z","shell.execute_reply.started":"2022-04-03T04:56:28.496358Z","shell.execute_reply":"2022-04-03T04:56:28.506778Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"画像前処理の定義\nResizeで画像サイズを処理、Nomalizeで色情報を変換、ToTensorV2でtensorに変換","metadata":{}},{"cell_type":"code","source":"from albumentations import Compose, Resize, Normalize\nfrom albumentations.pytorch import ToTensorV2\n\n#datasetのうち後半はひつようないから_で済ましている\nimage, _ = dataset[0]\n\n#例\ntransform = Resize(100,100)\ntransformed = transform(image=image)[\"image\"]\nplt.imshow(transformed)\nplt.title(\"Resize\")\nplt.show()\n\ntransform = Compose([Resize(100,100), Normalize()])\ntransformed = transform(image=image)[\"image\"]\nplt.imshow(transformed)\nplt.title(\"Resize and Normalize\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-07T14:28:35.909405Z","iopub.execute_input":"2022-04-07T14:28:35.909658Z","iopub.status.idle":"2022-04-07T14:28:36.308185Z","shell.execute_reply.started":"2022-04-07T14:28:35.909630Z","shell.execute_reply":"2022-04-07T14:28:36.307496Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transform = Compose([Resize(CFG.image_size, CFG.image_size),\n                    Normalize(),\n                    ToTensorV2()])\ndataset = WhaleDataset(train[\"image\"].values, train[\"le_individual_id\"].values, transform)\n\nimage, num = dataset[1]\nprint(image)\nprint(num)","metadata":{"execution":{"iopub.status.busy":"2022-04-07T14:29:04.615198Z","iopub.execute_input":"2022-04-07T14:29:04.615472Z","iopub.status.idle":"2022-04-07T14:29:04.822232Z","shell.execute_reply.started":"2022-04-07T14:29:04.615442Z","shell.execute_reply":"2022-04-07T14:29:04.820842Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"DataLoaderに載せる","metadata":{}},{"cell_type":"code","source":"from torch.utils.data import DataLoader\n\ndataloader = DataLoader(dataset, num_workers = CFG.num_workers, batch_size = CFG.batch_size, shuffle = True, drop_last = True, pin_memory = True)","metadata":{"execution":{"iopub.status.busy":"2022-04-07T14:29:30.323950Z","iopub.execute_input":"2022-04-07T14:29:30.324533Z","iopub.status.idle":"2022-04-07T14:29:30.328649Z","shell.execute_reply.started":"2022-04-07T14:29:30.324495Z","shell.execute_reply":"2022-04-07T14:29:30.327973Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"timmを用いてモデルを定義","metadata":{}},{"cell_type":"markdown","source":"学習","metadata":{}},{"cell_type":"code","source":"import timm\n\n#クラス情報はLEに入っている\nmodel = timm.create_model(CFG.model_name, num_classes = len(LE.classes_))\nmodel.to(CFG.device)\nmodel","metadata":{"execution":{"iopub.status.busy":"2022-04-07T14:29:46.647114Z","iopub.execute_input":"2022-04-07T14:29:46.647557Z","iopub.status.idle":"2022-04-07T14:29:50.209260Z","shell.execute_reply.started":"2022-04-07T14:29:46.647522Z","shell.execute_reply":"2022-04-07T14:29:50.208578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.nn as nn\nimport torch.optim as optim\n\n#画像分類ではクロスエントロピーが一般的\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr = 1e-4)","metadata":{"execution":{"iopub.status.busy":"2022-04-07T14:30:03.249468Z","iopub.execute_input":"2022-04-07T14:30:03.249720Z","iopub.status.idle":"2022-04-07T14:30:03.255553Z","shell.execute_reply.started":"2022-04-07T14:30:03.249691Z","shell.execute_reply":"2022-04-07T14:30:03.254837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Cross validation","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import KFold\n\n# とりあえず5-foldで分ける\nkf = KFold(n_splits=5, shuffle=True, random_state=CFG.seed)\nfold = np.zeros(len(train), dtype=np.int32)\n\nfor i, (train_idx, valid_idx) in enumerate(kf.split(train[\"image\"])):\n    fold[valid_idx] = i\n    print(i)\n    print(train_idx)\n    print(valid_idx)\ntrain[\"fold\"] = fold","metadata":{"execution":{"iopub.status.busy":"2022-04-07T14:30:21.063587Z","iopub.execute_input":"2022-04-07T14:30:21.063846Z","iopub.status.idle":"2022-04-07T14:30:21.083741Z","shell.execute_reply.started":"2022-04-07T14:30:21.063816Z","shell.execute_reply":"2022-04-07T14:30:21.083052Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tr = train[train[\"fold\"]!=CFG.fold]\nvl = train[train[\"fold\"]==CFG.fold]\ntrain_dataset = WhaleDataset(tr[\"image\"].values, LE.transform(tr[\"individual_id\"]), transform)\nvalid_dataset = WhaleDataset(vl[\"image\"].values, LE.transform(vl[\"individual_id\"]), transform)\ntrain_dataloader = DataLoader(train_dataset, num_workers=CFG.num_workers, batch_size=CFG.batch_size,\n                              shuffle=True, drop_last=True, pin_memory=True)\n# validation用ではshuffleやdrop_lastをFalseにする\nvalid_dataloader = DataLoader(valid_dataset, num_workers=CFG.num_workers, batch_size=CFG.batch_size,\n                              shuffle=False, drop_last=False, pin_memory=True)","metadata":{"execution":{"iopub.status.busy":"2022-04-07T14:30:47.622105Z","iopub.execute_input":"2022-04-07T14:30:47.622624Z","iopub.status.idle":"2022-04-07T14:30:47.659409Z","shell.execute_reply.started":"2022-04-07T14:30:47.622586Z","shell.execute_reply":"2022-04-07T14:30:47.658720Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from __future__ import print_function\nfrom __future__ import division\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.nn import Parameter\nimport math\n\n\nclass ArcMarginProduct(nn.Module):\n    r\"\"\"Implement of large margin arc distance: :\n        Args:\n            in_features: size of each input sample\n            out_features: size of each output sample\n            s: norm of input feature\n            m: margin\n            cos(theta + m)\n        \"\"\"\n    def __init__(self, in_features, out_features, s=30.0, \n                 m=0.50, easy_margin=False, ls_eps=0.0):\n        super(ArcMarginProduct, self).__init__()\n        self.in_features = in_features\n        self.out_features = out_features\n        self.s = s\n        self.m = m\n        self.ls_eps = ls_eps  # label smoothing\n        self.weight = nn.Parameter(torch.FloatTensor(out_features, in_features))\n        nn.init.xavier_uniform_(self.weight)\n\n        self.easy_margin = easy_margin\n        self.cos_m = math.cos(m)\n        self.sin_m = math.sin(m)\n        self.th = math.cos(math.pi - m)\n        self.mm = math.sin(math.pi - m) * m\n\n    def forward(self, input, label):\n        # --------------------------- cos(theta) & phi(theta) ---------------------\n        cosine = F.linear(F.normalize(input), F.normalize(self.weight))\n        sine = torch.sqrt(1.0 - torch.pow(cosine, 2))\n        phi = cosine * self.cos_m - sine * self.sin_m\n        if self.easy_margin:\n            phi = torch.where(cosine > 0, phi, cosine)\n        else:\n            phi = torch.where(cosine > self.th, phi, cosine - self.mm)\n        # --------------------------- convert label to one-hot ---------------------\n        # one_hot = torch.zeros(cosine.size(), requires_grad=True, device='cuda')\n        one_hot = torch.zeros(cosine.size(), device=CONFIG['device'])\n        one_hot.scatter_(1, label.view(-1, 1).long(), 1)\n        if self.ls_eps > 0:\n            one_hot = (1 - self.ls_eps) * one_hot + self.ls_eps / self.out_features\n        # -------------torch.where(out_i = {x_i if condition_i else y_i) ------------\n        output = (one_hot * phi) + ((1.0 - one_hot) * cosine)\n        output *= self.s\n\n        return output\n","metadata":{"execution":{"iopub.status.busy":"2022-04-07T14:37:07.600551Z","iopub.execute_input":"2022-04-07T14:37:07.600905Z","iopub.status.idle":"2022-04-07T14:37:07.613133Z","shell.execute_reply.started":"2022-04-07T14:37:07.600854Z","shell.execute_reply":"2022-04-07T14:37:07.612466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":" metric = ArcMarginProduct(512, 15587, s=30, m=0.05, easy_margin=True)","metadata":{"execution":{"iopub.status.busy":"2022-04-07T14:37:11.085938Z","iopub.execute_input":"2022-04-07T14:37:11.086479Z","iopub.status.idle":"2022-04-07T14:37:11.161855Z","shell.execute_reply.started":"2022-04-07T14:37:11.086441Z","shell.execute_reply":"2022-04-07T14:37:11.161068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.nn.functional as F\nfrom sklearn.metrics import accuracy_score\nfrom tqdm.auto import tqdm\n\nmodel = timm.create_model(CFG.model_name, num_classes=len(LE.classes_))\nmodel.to(CFG.device)\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=1e-3)\n\ntrain_losses = []\nvalid_losses = []\naccs = []\n\nfor epoch in range(1, CFG.num_epochs+1):\n    print(f\"Epoch : {epoch}\")\n    count = 0\n    loss_sum = 0\n    model.train()\n    for inputs, labels in tqdm(train_dataloader):\n        bs, _, _, _ = inputs.size()\n        optimizer.zero_grad()\n        inputs = inputs.to(CFG.device)\n        labels = labels.to(CFG.device)\n        features = model(inputs)\n        outputs = metrics.forward(features, labels)\n        loss = criterion(outputs, labels)\n        loss_sum += loss.item()*bs\n        count += bs\n        loss.backward()\n        optimizer.step()\n    print(f\"Train Loss {loss_sum/count:.4f}\")\n    train_losses.append(loss_sum/count)\n\n    count = 0\n    loss_sum = 0\n    # validation用ではeval関数によってmodelを推論モードにする必要がある\n    model.eval()\n    gt = []\n    preds = []\n    # validationでは誤差逆伝播を行わないので、勾配情報が不要\n    # このtorch.no_gradを使うと勾配情報を計算しないようになり、計算時間を節約できる\n    with torch.no_grad():\n        for inputs, labels in tqdm(valid_dataloader):\n            bs, _, _, _ = inputs.size()\n            inputs = inputs.to(CFG.device)\n            labels = labels.to(CFG.device)\n            features = model(inputs)\n            outputs = metrics.forward(features, labels)\n            gt.append(labels.to(\"cpu\").numpy())\n            preds.append(F.softmax(outputs, dim=1).to(\"cpu\").numpy())\n            loss = criterion(outputs, labels)\n            loss_sum += loss.item()*bs\n            count += bs\n    gt = np.concatenate(gt)\n    preds = np.concatenate(preds)\n    acc = accuracy_score(gt, np.argmax(preds, axis=1))\n    print(f\"Valid Loss {loss_sum/count:.4f}\")\n    valid_losses.append(loss_sum/count)\n    print(f\"Accuracy {acc:.4f}\")\n    accs.append(acc)","metadata":{"execution":{"iopub.status.busy":"2022-04-03T13:49:06.501924Z","iopub.execute_input":"2022-04-03T13:49:06.50238Z","iopub.status.idle":"2022-04-03T14:00:36.28106Z","shell.execute_reply.started":"2022-04-03T13:49:06.502336Z","shell.execute_reply":"2022-04-03T14:00:36.278009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"models","metadata":{"execution":{"iopub.status.busy":"2022-04-03T12:13:49.134105Z","iopub.execute_input":"2022-04-03T12:13:49.134497Z","iopub.status.idle":"2022-04-03T12:13:49.234042Z","shell.execute_reply.started":"2022-04-03T12:13:49.134412Z","shell.execute_reply":"2022-04-03T12:13:49.232882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(range(1, CFG.num_epochs+1), train_losses, label=\"train\")\nplt.plot(range(1, CFG.num_epochs+1), valid_losses, label=\"valid\")\nplt.legend()\nplt.title(\"Cross Entropy Loss\")\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"CE\")\nplt.show()\n\nplt.plot(range(1, CFG.num_epochs+1), accs)\nplt.title(\"Accuracy\")\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"ACC\")\nplt.ylim(0, 1)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-03T06:43:42.809381Z","iopub.execute_input":"2022-04-03T06:43:42.809684Z","iopub.status.idle":"2022-04-03T06:43:43.167166Z","shell.execute_reply.started":"2022-04-03T06:43:42.809643Z","shell.execute_reply":"2022-04-03T06:43:43.166498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"LE.inverse_transform(np.argmax(preds, axis=1))","metadata":{"execution":{"iopub.status.busy":"2022-04-03T06:48:57.007396Z","iopub.execute_input":"2022-04-03T06:48:57.007652Z","iopub.status.idle":"2022-04-03T06:48:57.015474Z","shell.execute_reply.started":"2022-04-03T06:48:57.007623Z","shell.execute_reply":"2022-04-03T06:48:57.014772Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"LE.inverse_transform(gt)","metadata":{"execution":{"iopub.status.busy":"2022-04-03T06:44:40.435153Z","iopub.execute_input":"2022-04-03T06:44:40.43587Z","iopub.status.idle":"2022-04-03T06:44:40.443214Z","shell.execute_reply.started":"2022-04-03T06:44:40.435819Z","shell.execute_reply":"2022-04-03T06:44:40.442202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# nunpy.nparrayにおける[:, 0]は、0列目の行列を表す。\nvl[\"prediction\"] = LE.inverse_transform(np.argmax(preds, axis=1))\nfor i, c in enumerate(LE.classes_):\n    vl[f\"pred_{c}\"] = preds[:, i]","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i, c in enumerate(LE.classes_):\n    print(i, c)","metadata":{"execution":{"iopub.status.busy":"2022-04-03T06:54:23.151006Z","iopub.execute_input":"2022-04-03T06:54:23.151272Z","iopub.status.idle":"2022-04-03T06:54:23.161683Z","shell.execute_reply.started":"2022-04-03T06:54:23.151242Z","shell.execute_reply":"2022-04-03T06:54:23.160937Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vl","metadata":{"execution":{"iopub.status.busy":"2022-04-03T06:49:28.472936Z","iopub.execute_input":"2022-04-03T06:49:28.473198Z","iopub.status.idle":"2022-04-03T06:49:28.508551Z","shell.execute_reply.started":"2022-04-03T06:49:28.473168Z","shell.execute_reply":"2022-04-03T06:49:28.507755Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"_, top_idx = torch.topk(torch.tensor(preds), k=5)\n#nはつまり、行数\nn = top_idx.size()[0]\n#LE.inverse_transformは、一行のnparrayが入力される。だからreshape(n*5)\ntop_species = LE.inverse_transform(top_idx.numpy().reshape(n*5)).reshape(n, 5)\n\nfor i in range(5):\n    vl[f\"top {i+1}\"] = top_species[:, i]","metadata":{"execution":{"iopub.status.busy":"2022-04-03T06:50:24.117333Z","iopub.execute_input":"2022-04-03T06:50:24.117591Z","iopub.status.idle":"2022-04-03T06:50:24.13313Z","shell.execute_reply.started":"2022-04-03T06:50:24.117561Z","shell.execute_reply":"2022-04-03T06:50:24.132388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vl","metadata":{"execution":{"iopub.status.busy":"2022-04-03T06:50:42.066152Z","iopub.execute_input":"2022-04-03T06:50:42.066424Z","iopub.status.idle":"2022-04-03T06:50:42.101343Z","shell.execute_reply.started":"2022-04-03T06:50:42.066392Z","shell.execute_reply":"2022-04-03T06:50:42.100604Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2022-04-03T07:12:01.790603Z","iopub.execute_input":"2022-04-03T07:12:01.791334Z","iopub.status.idle":"2022-04-03T07:12:01.803801Z","shell.execute_reply.started":"2022-04-03T07:12:01.791299Z","shell.execute_reply":"2022-04-03T07:12:01.802989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = timm.create_model(CFG.model_name, num_classes=len(LE.classes_))\nprint(model)","metadata":{"execution":{"iopub.status.busy":"2022-04-03T10:00:03.996693Z","iopub.execute_input":"2022-04-03T10:00:03.997036Z","iopub.status.idle":"2022-04-03T10:00:04.160344Z","shell.execute_reply.started":"2022-04-03T10:00:03.996997Z","shell.execute_reply":"2022-04-03T10:00:04.159686Z"},"trusted":true},"execution_count":null,"outputs":[]}]}